Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions test/js/web/fetch/blob-oom.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,43 @@ describe.skipIf(os.totalmem() < 10 * 1024 ** 3)("byte sources at the 2 GiB strin
expect(exitCode).toBe(0);
});

// A typed-array body is stored as an InternalBlob (bytes copied into a Vec),
// which converts to a string through Internal::to_string_owned rather than
// the Blob store path above, so it exercises a different guard call site.
test("Response(typedArray).text() and .json() at 2^31 bytes throw ERR_STRING_TOO_LONG instead of aborting", async () => {
await using proc = Bun.spawn({
cmd: [
bunExe(),
"-e",
`
const results = [];
const report = e => ({ name: e.name, code: e.code, message: e.message });
const bytes = new Uint8Array(2 ** 31);
await new Response(bytes).text().then(() => results.push("TEXT_UNEXPECTED_SUCCESS"), e => results.push(report(e)));
await new Response(bytes).json().then(() => results.push("JSON_UNEXPECTED_SUCCESS"), e => results.push(report(e)));
console.log(JSON.stringify(results));
`,
],
env: bunEnv,
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(JSON.parse(stdout.trim() || JSON.stringify({ stdout, stderr, exitCode }))).toEqual([
Comment on lines +211 to +215

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Inherit stderr for this oversized-allocation child.

stderr is piped and consumed, but it is not preserved when stdout contains valid JSON. If the child emits the expected result and then aborts or writes a native/ASAN diagnostic, the test loses that diagnostic and reports only the exit-code mismatch. Use stderr: "inherit" and remove proc.stderr.text() from the Promise.all call.

Proposed fix
-      stderr: "pipe",
+      stderr: "inherit",
...
-    const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
-    expect(JSON.parse(stdout.trim() || JSON.stringify({ stdout, stderr, exitCode }))).toEqual([
+    const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
+    expect(JSON.parse(stdout.trim() || JSON.stringify({ stdout, exitCode }))).toEqual([

Based on learnings, oversized-allocation subprocesses should inherit stderr so native diagnostics remain visible in the runner log.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(JSON.parse(stdout.trim() || JSON.stringify({ stdout, stderr, exitCode }))).toEqual([
stdout: "pipe",
stderr: "inherit",
});
const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
expect(JSON.parse(stdout.trim() || JSON.stringify({ stdout, exitCode }))).toEqual([
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/js/web/fetch/blob-oom.test.ts` around lines 211 - 215, Update the
oversized-allocation subprocess setup to use stderr: "inherit" instead of piping
stderr, and remove proc.stderr.text() from the Promise.all collection and
related parsing fallback. Preserve stdout consumption and exitCode handling so
native or ASAN diagnostics remain visible in the runner log.

Source: Learnings

{
name: "Error",
code: "ERR_STRING_TOO_LONG",
message: "Cannot create a string longer than 2147483647 characters",
},
{
name: "Error",
code: "ERR_STRING_TOO_LONG",
message: "Cannot parse a JSON string longer than 2147483647 characters",
},
]);
expect(exitCode).toBe(0);
});

test("Bun.file().text() at 2^31 bytes throws ERR_STRING_TOO_LONG instead of aborting", async () => {
using dir = tempDir("blob-2gib", {});
const file = path.join(String(dir), "big.txt");
Expand Down