fix(resolve): stop an Object.prototype name resolving as an engine or tool#48
Merged
ralyodio merged 1 commit intoJul 26, 2026
Conversation
… tool ENGINES, ALIASES, TOOLS and AI_EXEC are plain object literals looked up with OBJ[key], so a target named after an Object.prototype member resolved truthy and was handed downstream as a real entry with no bin or install spec. $ moshcode install constructor TypeError: Cannot read properties of undefined (reading 'cmd') Same crash from `moshcode upgrade constructor`, `moshcode constructor` (passthrough), and `/install constructor` in the TUI, where it takes the whole session down instead of printing the unknown-target line. Resolve own properties only, so these names fall through to the existing usage/unknown-target paths.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
ENGINES,ALIASES,TOOLSandAI_EXECare plain object literals looked up withOBJ[key]. A target name that happens to be anObject.prototypemember therefore resolves truthy and is passed on as a real entry — one with nobinand noinstallspec.Reproduced on
main(05cfd7f), every entrypoint:In the TUI this is the worst case: the crash takes the whole pit down, so the session, its history and its cwd go with it, where the code clearly meant to print
unknown engine or tool "constructor"and carry on.__proto__behaves the same way (names are lowercased first, soconstructorand__proto__are the ones that reach these lookups).It is not only a typo path:
moshscriptscripts callinstall(name)/upgrade(name)/ai(p, {engine})with strings the script computed, so an unvalidated value lands here as a stack trace rather than the tool's own error message.Fix
Resolve own properties only, so these names fall through to the existing usage / unknown-target branches that were already written for them:
src/engines.mjs—resolveEngine,aiExecArgs,pickAiEnginesrc/tools.mjs—resolveToolsrc/tui.mjs—installTargetbin/moshcode.mjs— theinstalltarget lookupmoshcode upgradeneeded no change of its own: it goes throughresolveEngine/resolveTool. No behaviour change for any real engine, alias or tool name.Tests
4 added, each stash-verified against unpatched
src/+bin/(all 4 fail there, all 4 pass with the fix):test/engines.test.mjs—resolveEngine/pickAiEngine/aiExecArgsreject the prototype namestest/tools.test.mjs—resolveToolrejects them, plus an end-to-endmoshcode install constructorthat must exit 1 with usage and noTypeErrortest/tui.test.mjs—/install constructorprints the unknown-target line and the pit survives to/quitFull suite:
node --test→ 159 pass / 0 fail (main: 155).