fix: use Array.from instead of Buffer.from for native processStreamChunk state (#2348)
The napi StreamState fields (utf8Pending, ansiPending) expect plain arrays (Vec<u8>), not Buffers. Passing Buffer.from() caused 'Given napi value is not an array on StreamState.utf8Pending' crash on multi-chunk bash output. Added regression test for multi-chunk state passing. AI-assisted: This change was authored with Claude (AI pair programming).
This commit is contained in:
parent
5b0c24a92c
commit
f4ecf9d11a
2 changed files with 36 additions and 2 deletions
34
packages/native/src/__tests__/stream-process.test.mjs
Normal file
34
packages/native/src/__tests__/stream-process.test.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { test, describe } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { processStreamChunk } from "../stream-process/index.ts";
|
||||
|
||||
describe("processStreamChunk", () => {
|
||||
test("processes a single chunk without state", () => {
|
||||
const result = processStreamChunk(Buffer.from("hello world\n"));
|
||||
assert.equal(result.text, "hello world\n");
|
||||
assert.ok(Array.isArray(result.state.utf8Pending));
|
||||
assert.ok(Array.isArray(result.state.ansiPending));
|
||||
});
|
||||
|
||||
test("processes multiple chunks passing state between calls", () => {
|
||||
const result1 = processStreamChunk(Buffer.from("first\n"));
|
||||
assert.equal(result1.text, "first\n");
|
||||
|
||||
// This was the crash: passing state back caused
|
||||
// "Given napi value is not an array on StreamState.utf8Pending"
|
||||
// when state arrays were wrapped in Buffer.from() instead of Array.from()
|
||||
const result2 = processStreamChunk(Buffer.from("second\n"), result1.state);
|
||||
assert.equal(result2.text, "second\n");
|
||||
|
||||
const result3 = processStreamChunk(Buffer.from("third\n"), result2.state);
|
||||
assert.equal(result3.text, "third\n");
|
||||
});
|
||||
|
||||
test("state fields are plain arrays, not Buffers", () => {
|
||||
const result = processStreamChunk(Buffer.from("test\n"));
|
||||
assert.ok(Array.isArray(result.state.utf8Pending), "utf8Pending should be a plain array");
|
||||
assert.ok(Array.isArray(result.state.ansiPending), "ansiPending should be a plain array");
|
||||
assert.ok(!(result.state.utf8Pending instanceof Buffer), "utf8Pending should not be a Buffer");
|
||||
assert.ok(!(result.state.ansiPending instanceof Buffer), "ansiPending should not be a Buffer");
|
||||
});
|
||||
});
|
||||
|
|
@ -33,8 +33,8 @@ export function processStreamChunk(
|
|||
// Convert StreamState arrays to the format napi expects (Vec<u8>)
|
||||
const napiState = state
|
||||
? {
|
||||
utf8Pending: Buffer.from(state.utf8Pending),
|
||||
ansiPending: Buffer.from(state.ansiPending),
|
||||
utf8Pending: Array.from(state.utf8Pending),
|
||||
ansiPending: Array.from(state.ansiPending),
|
||||
}
|
||||
: undefined;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue