* fix: reject path-traversal segments in dependency aliases
A transitive registry package can use a dependency-alias key like
`@x/../../../../../.git/hooks` to make `pnpm install` create a symlink
outside the intended `node_modules` directory, since pnpm passes the
alias straight into `path.join(modulesDir, alias)` without checking
that the joined path stays inside `modulesDir`.
Reject aliases that aren't a single `name` or `@scope/name` shape at
manifest-read time (both the importer's manifest and every transitive
package manifest) and re-check at the symlink layer as defense in
depth. Mirror the fix in pacquet's deps-resolver.
---
Written by an agent (Claude Code, claude-opus-4-7).
* fix(pacquet): use raw strings in alias validator tests for dylint
Perfectionist's `prefer-raw-string` lint rejects the two
backslash-escaped test inputs.
---
Written by an agent (Claude Code, claude-opus-4-7).
* refactor: tighten dependency-alias validator to validate-npm-package-name
An alias is the directory name pnpm creates inside `node_modules`, so
the only valid shapes are a single `name` or `@scope/name` consisting
of URL-friendly characters with no leading `.` / `_`, and not equal to
reserved names such as `node_modules`. That's the same
`validForOldPackages` rule `parseWantedDependency` already applies to
CLI-given names — the manifest-read path should match. Route both
stacks through it so `.bin`, `.pnpm`, `node_modules`, `favicon.ico`,
whitespace, and non-URL-friendly characters are all rejected alongside
the path-traversal shapes the narrow validator caught.
---
Written by an agent (Claude Code, claude-opus-4-7).
* refactor: collapse symlink-layer assertion + path.join into safeJoinModulesDir
The two-step pattern of "assert the alias stays in the dir" then "join
the dir and the alias" left it possible for a caller to use the join
without the assertion. Fold them into a single `safeJoinModulesDir`
that returns the joined path and throws on escape, so the check is
unmissable.
---
Written by an agent (Claude Code, claude-opus-4-7).
* test(symlink-dependency): cover the path-equals-dir guard branch
The earlier tests only exercised the `!startsWith` branch with
`'../sibling'` and `'@x/../../../etc'`. Add `''` and `'.'` as alias
cases — both resolve to the modules dir itself and hit the
`resolvedLink === resolvedDir` branch of `safeJoinModulesDir`.
---
Written by an agent (Claude Code, claude-opus-4-7).