-
Notifications
You must be signed in to change notification settings - Fork 3k
fix: validate resolved npm path ends with .js before returning #7591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,20 +41,28 @@ export function getNpmCliPath( | |
| // instead of throwing synchronously — getNpmCliPath is called from a | ||
| // non-async site (handleAutoUpdate), and a returned best-effort path lets the | ||
| // downstream spawn surface any failure through its 'error' handler. | ||
| // | ||
| // Some Node version managers (mise, asdf, proto) replace bin/npm with a | ||
| // non-JS wrapper script (e.g. a bash shim). fs.realpathSync succeeds on | ||
| // these (the file exists), but spawning `node /path/to/bash-wrapper` fails | ||
| // with a SyntaxError. Validate the resolved path ends with ".js" before | ||
| // returning it; otherwise fall back to the conventional path. | ||
| const adjacentNpm = path.join(path.dirname(nodePath), 'npm'); | ||
| try { | ||
| return fs.realpathSync(adjacentNpm); | ||
| const resolved = fs.realpathSync(adjacentNpm); | ||
| if (resolved.endsWith('.js')) return resolved; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] When the The module already has a if (resolved.endsWith('.js')) return resolved;
debugLogger(`Resolved npm path does not end with .js, falling back: ${resolved}`);— qwen3.7-max via Qwen Code /review |
||
| } catch { | ||
| return path.join( | ||
| path.dirname(nodePath), | ||
| '..', | ||
| 'lib', | ||
| 'node_modules', | ||
| 'npm', | ||
| 'bin', | ||
| 'npm-cli.js', | ||
| ); | ||
| // Fall through to the conventional path below. | ||
| } | ||
| return path.join( | ||
| path.dirname(nodePath), | ||
| '..', | ||
| 'lib', | ||
| 'node_modules', | ||
| 'npm', | ||
| 'bin', | ||
| 'npm-cli.js', | ||
| ); | ||
| } | ||
|
|
||
| const debugLogger = createDebugLogger('INSTALLATION_INFO'); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Suggestion]
getNpmCliPathhas zero direct unit tests — the.endsWith('.js')guard (the core fix) is untested for both its success and rejection branches. The linked issue #7543's triage explicitly requested a test for this case.Failure scenario: A future refactor simplifies the function back to
return fs.realpathSync(adjacentNpm)(the pre-PR one-liner), or tightens the extension check. With no test asserting the non-.jsfallback, the mise/asdf/proto SyntaxError regresses silently.— qwen3.7-max via Qwen Code /review