Compare commits

...

2 Commits

Author SHA1 Message Date
Claude Bot
7735063aa0 test: remove ineffective stderr panic assertion
Checking stderr for "panic" is redundant since a panic causes a
non-zero exit code, which is already asserted.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 23:39:48 +00:00
Claude Bot
b6a6c880b5 fix(standalone): remove incorrect @alignCast on sourcemap bytes (#27383)
The `LazySourceMap` union's payload is aligned to the maximum variant
alignment (8 bytes due to the `*SourceMap.ParsedSourceMap` pointer).
When initializing the `serialized` variant, `@alignCast` promoted the
alignment of the sourcemap byte slice from 1 to 8. However, serialized
sourcemap data in standalone binaries can be at any offset, not
necessarily 8-byte aligned. On Windows ARM64 ReleaseSafe builds, this
causes `panic: incorrect alignment`.

Remove the unnecessary `@alignCast()` calls since `SerializedSourceMap.bytes`
is `[]const u8` which naturally has alignment 1.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-23 23:21:34 +00:00
2 changed files with 63 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,61 @@
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/27383
// Standalone executables with inline sourcemaps could crash with
// "panic: incorrect alignment" on Windows ARM64 (ReleaseSafe builds)
// because @alignCast promoted the alignment of sourcemap byte slices
// inside the LazySourceMap union from 1 to 8, but serialized sourcemap
// data in standalone binaries can be at any offset.
test("standalone compile with inline sourcemap does not crash from alignment", async () => {
// Use files with varying name lengths to increase the chance of
// non-8-byte-aligned sourcemap offsets in the standalone binary.
using dir = tempDir("issue-27383", {
"a.js": `export function a() { throw new Error("error from a"); }`,
"bb.js": `export function bb() { throw new Error("error from bb"); }`,
"ccc.js": `export function ccc() { throw new Error("error from ccc"); }`,
"ddddd.js": `export function ddddd() { throw new Error("error from ddddd"); }`,
"entry.js": `
import { a } from "./a.js";
import { bb } from "./bb.js";
import { ccc } from "./ccc.js";
import { ddddd } from "./ddddd.js";
const fns = [a, bb, ccc, ddddd];
const fn = fns[Math.floor(Math.random() * fns.length)];
try { fn(); } catch (e) {
// Accessing the stack triggers sourcemap parsing
console.log(e.stack);
}
`,
});
const result = await Bun.build({
entrypoints: [join(String(dir), "entry.js")],
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]);
// The stack trace should contain original file names (sourcemap worked)
expect(stdout).toMatch(/error from (a|bb|ccc|ddddd)/);
// Should not crash
expect(exitCode).toBe(0);
});