From e80e61c9a381e3473dd09da80089c27ca77ba27f Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Fri, 29 Mar 2024 13:51:45 -0700 Subject: [PATCH] Allow 0-length ArrayBuffer & Blob in `Bun.spawn` stdio (#9557) Co-authored-by: Zack Radisic --- src/bun.js/api/bun/spawn/stdio.zig | 13 +++++++-- .../spawn-empty-arrayBufferOrBlob.test.ts | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/js/bun/spawn/spawn-empty-arrayBufferOrBlob.test.ts diff --git a/src/bun.js/api/bun/spawn/stdio.zig b/src/bun.js/api/bun/spawn/stdio.zig index 8ff7b2acf9..de3d25f085 100644 --- a/src/bun.js/api/bun/spawn/stdio.zig +++ b/src/bun.js/api/bun/spawn/stdio.zig @@ -409,9 +409,10 @@ pub const Stdio = union(enum) { } } } else if (value.asArrayBuffer(globalThis)) |array_buffer| { - if (array_buffer.slice().len == 0) { - globalThis.throwInvalidArguments("ArrayBuffer cannot be empty", .{}); - return false; + // Change in Bun v1.0.34: don't throw for empty ArrayBuffer + if (array_buffer.byteSlice().len == 0) { + out_stdio.* = .{ .ignore = {} }; + return true; } out_stdio.* = .{ @@ -475,6 +476,12 @@ pub const Stdio = union(enum) { return false; } + // Instead of writing an empty blob, lets just make it /dev/null + if (blob.fastSize() == 0) { + stdio.* = .{ .ignore = {} }; + return true; + } + stdio.* = .{ .blob = blob }; return true; } diff --git a/test/js/bun/spawn/spawn-empty-arrayBufferOrBlob.test.ts b/test/js/bun/spawn/spawn-empty-arrayBufferOrBlob.test.ts new file mode 100644 index 0000000000..b7f8a45be4 --- /dev/null +++ b/test/js/bun/spawn/spawn-empty-arrayBufferOrBlob.test.ts @@ -0,0 +1,29 @@ +import { describe, test, expect } from "bun:test"; +import { bunEnv, bunExe } from "harness"; + +describe("spawn with empty", () => { + for (const [stdin, label] of [ + [new ArrayBuffer(0), "ArrayBuffer"], + [new Uint8Array(0), "Uint8Array"], + [new Blob([]), "Blob"], + ] as const) { + test(label + " for stdin", async () => { + const proc = Bun.spawn({ + cmd: [bunExe(), "-e", "process.stdin.pipe(process.stdout)"], + stdin, + stdout: "pipe", + stderr: "pipe", + env: bunEnv, + }); + + const [exited, stdout, stderr] = await Promise.all([ + proc.exited, + new Response(proc.stdout).text(), + new Response(proc.stderr).text(), + ]); + expect(exited).toBe(0); + expect(stdout).toBeEmpty(); + expect(stderr).toBeEmpty(); + }); + } +});