Compare commits

...

2 Commits

Author SHA1 Message Date
Claude Bot
e4c395da0b refactor(test): use async spawn pattern in regression test
- Use `await using Bun.spawn()` instead of `Bun.spawnSync()`
- Remove forbidden negative assertions against stderr
- Keep positive assertions for stdout and exit code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 07:30:48 +00:00
Claude Bot
f15531be9e fix(bundler): convert backslashes in path.pretty on Windows (#26798)
On Windows, `relativePlatform()` can return paths with backslashes when
paths have different roots. This violates the invariant that `path.pretty`
must only contain forward slashes, causing `assertPrettyIsValid()` to panic.

The fix uses `platformToPosixInPlace()` to convert backslashes to forward
slashes before assigning to `path.pretty`, consistent with how this is
handled elsewhere in the codebase (e.g., `dupeAllocFixPretty()`).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 07:04:51 +00:00
2 changed files with 51 additions and 1 deletions

View File

@@ -689,7 +689,9 @@ pub const BundleV2 = struct {
if (path.pretty.ptr == path.text.ptr) {
// TODO: outbase
const rel = bun.path.relativePlatform(transpiler.fs.top_level_dir, path.text, .loose, false);
path.pretty = bun.handleOom(this.allocator().dupe(u8, rel));
const pretty = bun.handleOom(this.allocator().dupe(u8, rel));
bun.path.platformToPosixInPlace(u8, pretty);
path.pretty = pretty;
}
path.assertPrettyIsValid();

View File

@@ -0,0 +1,48 @@
import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDirWithFiles } from "harness";
// Test for https://github.com/oven-sh/bun/issues/26798
// Bun.build crashes on Windows when a plugin's onResolve returns null,
// falling back to the standard resolver, and the resulting path.pretty
// contains Windows backslashes.
test("Bun.build with plugin onResolve returning null should not crash", async () => {
const dir = tempDirWithFiles("onresolve-null-test", {
"src/index.ts": `import { foo } from "./foo"; console.log(foo);`,
"src/foo.ts": `export const foo = "hello";`,
"build.ts": `
const result = await Bun.build({
entrypoints: ["./src/index.ts"],
plugins: [
{
name: "null-returner",
setup(build) {
// Return null to trigger fallback to standard resolver
build.onResolve({ filter: /.*/ }, (args) => {
return null;
});
},
},
],
});
if (!result.success) {
console.error("Build failed:", result.logs);
process.exit(1);
}
console.log("Build succeeded");
`,
});
await using proc = Bun.spawn({
cmd: [bunExe(), "run", "build.ts"],
cwd: dir,
env: bunEnv,
stdout: "pipe",
stderr: "pipe",
});
const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
expect(stdout).toContain("Build succeeded");
expect(exitCode).toBe(0);
});