mirror of
https://github.com/oven-sh/bun
synced 2026-02-14 12:51:54 +00:00
Fix: convert relative paths to absolute in require.resolve paths option
When using `require.resolve()` with relative paths in the `paths` option, Bun was passing them directly to the resolver without converting them to absolute paths. This caused a panic on Windows with the error: "cannot resolve DirInfo for non-absolute path: libs\barcode-svg" The fix converts relative paths to absolute paths (relative to CWD) before passing them to `checkPackagePath`, matching Node.js behavior where the `paths` option accepts both absolute and relative paths. Fixes #14911 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1298,7 +1298,18 @@ pub const Resolver = struct {
|
||||
for (custom_paths) |custom_path| {
|
||||
const custom_utf8 = custom_path.toUTF8WithoutRef(bun.default_allocator);
|
||||
defer custom_utf8.deinit();
|
||||
switch (r.checkPackagePath(custom_utf8.slice(), import_path, kind, global_cache)) {
|
||||
|
||||
// Resolve relative paths to absolute paths relative to CWD, matching Node.js behavior
|
||||
const custom_dir = if (!std.fs.path.isAbsolute(custom_utf8.slice()))
|
||||
ResolvePath.joinAbsString(
|
||||
r.fs.top_level_dir,
|
||||
&.{custom_utf8.slice()},
|
||||
.auto,
|
||||
)
|
||||
else
|
||||
custom_utf8.slice();
|
||||
|
||||
switch (r.checkPackagePath(custom_dir, import_path, kind, global_cache)) {
|
||||
.success => |res| return .{ .success = res },
|
||||
.pending => |p| return .{ .pending = p },
|
||||
.failure => |p| return .{ .failure = p },
|
||||
|
||||
99
test/regression/issue/14911.test.ts
Normal file
99
test/regression/issue/14911.test.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
// Test for https://github.com/oven-sh/bun/issues/14911
|
||||
// require.resolve with relative paths in the `paths` option should not panic
|
||||
import { expect, test } from "bun:test";
|
||||
import { bunEnv, bunExe, tempDir } from "harness";
|
||||
|
||||
test("require.resolve with relative path in paths option should not panic", async () => {
|
||||
using dir = tempDir("issue-14911", {
|
||||
"libs/node_modules/barcode-svg/package.json": JSON.stringify({
|
||||
name: "barcode-svg",
|
||||
main: "index.js",
|
||||
}),
|
||||
"libs/node_modules/barcode-svg/index.js": "module.exports = { test: true };",
|
||||
"test.js": `
|
||||
try {
|
||||
// When using relative paths in the 'paths' option, Node.js treats them
|
||||
// as starting directories and searches for node_modules from there.
|
||||
// This was causing a panic on Windows: "cannot resolve DirInfo for non-absolute path"
|
||||
const resolved = require.resolve('barcode-svg', { paths: ['libs'] });
|
||||
console.log('RESOLVED:', resolved);
|
||||
|
||||
// Verify it resolved successfully
|
||||
if (!resolved.includes('barcode-svg')) {
|
||||
console.log('ERROR: Did not resolve barcode-svg');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('SUCCESS');
|
||||
} catch (err) {
|
||||
console.log('ERROR:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "test.js"],
|
||||
cwd: String(dir),
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
||||
|
||||
// Should not panic with "cannot resolve DirInfo for non-absolute path"
|
||||
expect(stderr).not.toContain("panic");
|
||||
expect(stderr).not.toContain("cannot resolve DirInfo for non-absolute path");
|
||||
expect(stdout).toContain("SUCCESS");
|
||||
expect(exitCode).toBe(0);
|
||||
});
|
||||
|
||||
test("require.resolve with multiple relative paths in paths option", async () => {
|
||||
using dir = tempDir("issue-14911-multiple", {
|
||||
"dir1/node_modules/pkg1/package.json": JSON.stringify({
|
||||
name: "pkg1",
|
||||
main: "index.js",
|
||||
}),
|
||||
"dir1/node_modules/pkg1/index.js": "module.exports = { pkg1: true };",
|
||||
"dir2/node_modules/pkg2/package.json": JSON.stringify({
|
||||
name: "pkg2",
|
||||
main: "index.js",
|
||||
}),
|
||||
"dir2/node_modules/pkg2/index.js": "module.exports = { pkg2: true };",
|
||||
"test.js": `
|
||||
try {
|
||||
// Test with multiple relative paths - they should all be converted to absolute
|
||||
const resolved1 = require.resolve('pkg1', { paths: ['dir1', 'dir2'] });
|
||||
console.log('RESOLVED1:', resolved1);
|
||||
|
||||
const resolved2 = require.resolve('pkg2', { paths: ['dir1', 'dir2'] });
|
||||
console.log('RESOLVED2:', resolved2);
|
||||
|
||||
if (!resolved1.includes('pkg1') || !resolved2.includes('pkg2')) {
|
||||
console.log('ERROR: Paths did not resolve correctly');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('SUCCESS');
|
||||
} catch (err) {
|
||||
console.log('ERROR:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "test.js"],
|
||||
cwd: String(dir),
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(stderr).not.toContain("panic");
|
||||
expect(stdout).toContain("SUCCESS");
|
||||
expect(exitCode).toBe(0);
|
||||
});
|
||||
Reference in New Issue
Block a user