Repository navigation
Conversation
require.resolve(id, { paths }) and Module._resolveFilename forward the
paths entries to the resolver, which handed them directly to
check_package_path. That function requires an absolute directory, so any
non-absolute entry tripped the "cannot resolve DirInfo for non-absolute
path" assertion and aborted the process.
Resolve each custom path against the top-level directory before the
node_modules walk, matching Node's Module._nodeModulePaths, which calls
path.resolve(from) on every entry. Absolute entries are unchanged.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe resolver's per-thread scratch buffers gained a ChangesCustom Path Resolution Fix
Related PRs: None identified. Suggested labels: bug, resolver, needs-tests Suggested reviewers: None identified. 🐰 A path once relative, now stands up straight, 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
There was a problem hiding this comment.
LGTM — targeted crash fix on a cold resolver path, uses the existing abs_buf_checked helper with a dedicated buffer, and the test follows harness conventions.
Extended reasoning...
Overview
This PR fixes a panic in require.resolve(id, { paths }) when a paths entry is non-absolute. Two files are touched: src/resolver/resolver.rs (adds a new custom_dir_path_abs scratch buffer to Bufs and resolves each user-provided custom path against top_level_dir via abs_buf_checked before handing it to check_package_path) and test/js/node/module/node-module-module.test.js (adds a subprocess test that resolves a package via a relative paths entry).
Security risks
None. The change only normalizes a user-provided directory string to an absolute path before a directory lookup — the same operation the sibling check_relative_path branch already performs internally. No new I/O surface, no auth/crypto/permissions code touched. The _checked variant returns None on buffer overflow, which the loop handles by continueing rather than panicking.
Level of scrutiny
The resolver is core, but this change is confined to the custom_dir_paths.is_some() branch, which is only set for the duration of a require.resolve/_resolveFilename call with an explicit paths option (see BunObject.rs:1434) and is annotated bun_core::hint::cold(). The fix reuses the established fs_ref().abs_buf_checked helper (which joins against top_level_dir, kept in sync with cwd via process.chdir), and join_abs_string_buf preserves absolute inputs by keeping the last absolute component, so existing absolute-path callers are unaffected. The new custom_dir_path_abs buffer is dedicated to this one call site, so there's no aliasing with buffers used inside check_package_path.
Other factors
The bug-hunting system found nothing. The test uses tempDir, bunExe/bunEnv, drains stdout/stderr/exited concurrently, and asserts stdout before exit code per repo conventions. The PR description confirms it fails under USE_SYSTEM_BUN=1 and that the existing absolute-path options.paths tests still pass. No CODEOWNERS entry covers the resolver, and there are no outstanding reviewer comments.
|
Closing as a duplicate of #31566, which is the older and more complete fix for this panic. After the duplicate flag I re-tested this branch and it still panics on an entry that require.resolve("x", { paths: ["C:/foo"] });
// panic: cannot resolve DirInfo for non-absolute path: C:/fooThe relative-specifier loop is reachable the same way, and this PR does not touch it at all: require.resolve("./x", { paths: ["C:/foo"] });
// panic: cannot resolve DirInfo for non-absolute path: C:/foo/x#31566 adds a host-native join ( |
What does this PR do?
Any non-absolute entry in
require.resolve(id, { paths })(orModule._resolveFilename(..., { paths })) aborted the process:In Node this is valid:
Module._nodeModulePathsrunspath.resolve(from)on every entry, so relative paths are resolved against the working directory before thenode_moduleswalk. Bun's resolver handed the raw user string tocheck_package_path, whosedir_info_cachedasserts the directory is absolute.This was found by fuzzing (the fuzzer passed a function, which
toWTFStringturns into its source text, another non-absolute string), but plain relative strings hit the same assertion.The fix resolves each custom path against
top_level_dirwithabs_buf_checkedbefore the lookup, in the one place that feeds user input intocheck_package_path. Absolute entries behave as before (join_abs_string_bufkeeps the last absolute component). The relative-import branch of the same loop was already safe becausecheck_relative_pathdoes this join internally.How did you verify your code works?
bun bd test test/js/node/module/node-module-module.test.jspasses. The new test spawns a fixture whose cwd is a temp dir containingsub/node_modules/paths-rel-pkg, resolves the package throughpaths: ["sub"], and requires it. Before the fix the subprocess aborts with the panic above; withUSE_SYSTEM_BUN=1the test fails. The existingoptions.pathstests inmodule-resolve-filename-paths.test.js(all absolute entries) still pass.