mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
make sure ipc with json serialization still works when bun is parent and not the child (#14756)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
This commit is contained in:
@@ -194,21 +194,19 @@ const json = struct {
|
||||
// 1 is regular
|
||||
// 2 is internal
|
||||
|
||||
pub fn decodeIPCMessage(
|
||||
data: []const u8,
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
) IPCDecodeError!DecodeIPCMessageResult {
|
||||
pub fn decodeIPCMessage(data: []const u8, globalThis: *JSC.JSGlobalObject) IPCDecodeError!DecodeIPCMessageResult {
|
||||
if (bun.strings.indexOfChar(data, '\n')) |idx| {
|
||||
var kind = data[0];
|
||||
var json_data = data[1..idx];
|
||||
var json_data = data[0..idx];
|
||||
|
||||
switch (kind) {
|
||||
1, 2 => {},
|
||||
2 => {
|
||||
json_data = data[1..idx];
|
||||
},
|
||||
else => {
|
||||
// if the message being recieved is from a node process then it wont have the leading marker byte
|
||||
// assume full message will be json
|
||||
// assume it's valid json with no header
|
||||
// any error will be thrown by toJSByParseJSON below
|
||||
kind = 1;
|
||||
json_data = data[0..idx];
|
||||
},
|
||||
}
|
||||
|
||||
@@ -230,6 +228,7 @@ const json = struct {
|
||||
}
|
||||
|
||||
const deserialized = str.toJSByParseJSON(globalThis);
|
||||
if (deserialized == .zero) return error.InvalidFormat;
|
||||
|
||||
return switch (kind) {
|
||||
1 => .{
|
||||
@@ -259,13 +258,12 @@ const json = struct {
|
||||
|
||||
const slice = str.slice();
|
||||
|
||||
try writer.ensureUnusedCapacity(1 + slice.len + 1);
|
||||
try writer.ensureUnusedCapacity(slice.len + 1);
|
||||
|
||||
writer.writeAssumeCapacity(&.{1});
|
||||
writer.writeAssumeCapacity(slice);
|
||||
writer.writeAssumeCapacity("\n");
|
||||
|
||||
return 1 + slice.len + 1;
|
||||
return slice.len + 1;
|
||||
}
|
||||
|
||||
pub fn serializeInternal(_: *IPCData, writer: anytype, global: *JSC.JSGlobalObject, value: JSValue) !usize {
|
||||
@@ -860,7 +858,7 @@ fn NewNamedPipeIPCHandler(comptime Context: type) type {
|
||||
// copy the remaining bytes to the start of the buffer
|
||||
bun.copy(u8, ipc.incoming.ptr[0..slice.len], slice);
|
||||
ipc.incoming.len = @truncate(slice.len);
|
||||
log("hit NotEnoughBytes2", .{});
|
||||
log("hit NotEnoughBytes3", .{});
|
||||
return;
|
||||
},
|
||||
error.InvalidFormat => {
|
||||
|
||||
7
test/js/bun/spawn/fixtures/ipc-child-bun.js
Normal file
7
test/js/bun/spawn/fixtures/ipc-child-bun.js
Normal file
@@ -0,0 +1,7 @@
|
||||
console.log("c start");
|
||||
process.on("message", message => {
|
||||
console.log("c", message);
|
||||
process.send(message);
|
||||
process.exit(0);
|
||||
});
|
||||
console.log("c end");
|
||||
7
test/js/bun/spawn/fixtures/ipc-child-node.js
Normal file
7
test/js/bun/spawn/fixtures/ipc-child-node.js
Normal file
@@ -0,0 +1,7 @@
|
||||
console.log("c start");
|
||||
process.on("message", message => {
|
||||
console.log("c", message);
|
||||
process.send(message);
|
||||
process.exit(0);
|
||||
});
|
||||
console.log("c end");
|
||||
14
test/js/bun/spawn/fixtures/ipc-parent-bun.js
Normal file
14
test/js/bun/spawn/fixtures/ipc-parent-bun.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const path = require("node:path");
|
||||
|
||||
console.log("p start");
|
||||
const child = Bun.spawn(["node", path.resolve(import.meta.dir, "ipc-child-node.js")], {
|
||||
ipc(message) {
|
||||
console.log("p", message);
|
||||
process.exit(0);
|
||||
},
|
||||
stdio: ["ignore", "inherit", "inherit"],
|
||||
serialization: "json",
|
||||
});
|
||||
|
||||
child.send("I am your father");
|
||||
console.log("p end");
|
||||
15
test/js/bun/spawn/fixtures/ipc-parent-node.js
Normal file
15
test/js/bun/spawn/fixtures/ipc-parent-node.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const path = require("node:path");
|
||||
const child_process = require("node:child_process");
|
||||
|
||||
console.log("p start");
|
||||
|
||||
const child = child_process.spawn(process.argv[2], [path.resolve(__dirname, "ipc-child-bun.js")], {
|
||||
stdio: ["ignore", "inherit", "inherit", "ipc"],
|
||||
});
|
||||
child.on("message", message => {
|
||||
console.log("p", message);
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
child.send("I am your father");
|
||||
console.log("p end");
|
||||
21
test/js/bun/spawn/spawn.ipc.bun-node.test.ts
Normal file
21
test/js/bun/spawn/spawn.ipc.bun-node.test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { spawn } from "bun";
|
||||
import { test, expect, it } from "bun:test";
|
||||
import { bunExe } from "harness";
|
||||
import path from "path";
|
||||
|
||||
test("ipc with json serialization still works when bun is parent and not the child", async () => {
|
||||
const child = Bun.spawn([bunExe(), path.resolve(import.meta.dir, "fixtures", "ipc-parent-bun.js")], {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
await child.exited;
|
||||
expect(await new Response(child.stdout).text()).toEqual(
|
||||
`p start
|
||||
p end
|
||||
c start
|
||||
c end
|
||||
c I am your father
|
||||
p I am your father
|
||||
`,
|
||||
);
|
||||
expect(await new Response(child.stderr).text()).toEqual("");
|
||||
});
|
||||
22
test/js/bun/spawn/spawn.ipc.node-bun.test.ts
Normal file
22
test/js/bun/spawn/spawn.ipc.node-bun.test.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { spawn } from "bun";
|
||||
import { test, expect, it } from "bun:test";
|
||||
import { bunExe, nodeExe } from "harness";
|
||||
import path from "path";
|
||||
|
||||
test("ipc with json serialization still works when bun is not the parent and the child", async () => {
|
||||
// prettier-ignore
|
||||
const child = Bun.spawn(["node", "--no-warnings", path.resolve(import.meta.dir, "fixtures", "ipc-parent-node.js"), bunExe()], {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
await child.exited;
|
||||
expect(await new Response(child.stderr).text()).toEqual("");
|
||||
expect(await new Response(child.stdout).text()).toEqual(
|
||||
`p start
|
||||
p end
|
||||
c start
|
||||
c end
|
||||
c I am your father
|
||||
p I am your father
|
||||
`,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user