Compare commits

...

1 Commits

Author SHA1 Message Date
Claude Bot
60dbd2616b fix(windows): remove incorrect @alignCast in standalone sourcemap deserialization (#27276)
The `LazySourceMap` union contains both a `serialized: SerializedSourceMap`
variant (with `bytes: []const u8`) and a `parsed: *SourceMap.ParsedSourceMap`
variant (pointer, alignment 8). Because the union's payload is aligned to the
maximum variant alignment, the `@alignCast` on the sourcemap slice was
promoting its pointer alignment to 8. However, the serialized sourcemap data
in the standalone binary can be at any offset, not necessarily 8-byte aligned.

On Windows (built with ReleaseSafe), this causes a panic:
  "panic(thread 11392): incorrect alignment"

On Linux/macOS (built with ReleaseFast), this is silent undefined behavior.

The fix removes the unnecessary `@alignCast` calls. The `bytes` field is
`[]const u8` with natural alignment 1, so no alignment promotion is needed.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-20 10:31:33 +00:00
2 changed files with 54 additions and 2 deletions

View File

@@ -336,7 +336,7 @@ pub const StandaloneModuleGraph = struct {
.contents = sliceToZ(raw_bytes, module.contents),
.sourcemap = if (module.sourcemap.length > 0)
.{ .serialized = .{
.bytes = @alignCast(sliceTo(raw_bytes, module.sourcemap)),
.bytes = sliceTo(raw_bytes, module.sourcemap),
} }
else
.none,
@@ -588,7 +588,7 @@ pub const StandaloneModuleGraph = struct {
if (comptime Environment.isDebug) {
// An expensive sanity check:
var graph = try fromBytes(allocator, @alignCast(output_bytes), offsets);
var graph = try fromBytes(allocator, output_bytes, offsets);
defer {
graph.files.unlockPointers();
graph.files.deinit();

View File

@@ -0,0 +1,52 @@
import { expect, test } from "bun:test";
import { bunEnv, tempDir } from "harness";
import { join } from "path";
// Regression test for https://github.com/oven-sh/bun/issues/27276
// Standalone compile with sourcemaps panicked on Windows due to an
// incorrect @alignCast when deserializing the embedded module graph.
// The sourcemap slice could be at a non-8-byte-aligned offset, but
// the LazySourceMap union inflated the required alignment to 8 because
// it also holds a pointer variant.
test("standalone compile with sourcemap does not panic on misaligned sourcemap data", async () => {
// Use multiple files with varying name lengths to increase the
// chance that the serialized sourcemap offset is not 8-byte aligned.
using dir = tempDir("issue-27276", {
"index.js": `
import { a } from "./a.js";
import { bc } from "./bc.js";
import { def } from "./def.js";
a();
bc();
def();
`,
"a.js": `export function a() { return 1; }`,
"bc.js": `export function bc() { return 2; }`,
"def.js": `export function def() { return 3; }`,
});
const result = await Bun.build({
entrypoints: [join(String(dir), "index.js")],
outdir: String(dir),
compile: true,
sourcemap: "inline",
});
expect(result.success).toBe(true);
expect(result.outputs.length).toBe(1);
const executablePath = result.outputs[0].path;
await using proc = Bun.spawn({
cmd: [executablePath],
env: bunEnv,
cwd: String(dir),
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stderr).toBe("");
expect(exitCode).toBe(0);
});