mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-06 08:23:19 +08:00
Pass a Buffer to a patched stdio write from an encoded data listener
A byte write to a replaced process.stdout.write or process.stderr.write
was boxed with the 'data' chunk helper, which answers a string while a
listener of a socket or HTTP response with setEncoding("utf8") runs. A
`process.stdout.write(buffer)` from such a listener reached the
replacement as a string. Node passes the Buffer it was given.
The stdio hook now boxes a byte write as a Buffer whatever listener is
running.
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/stdout-patch-buffer-from-encoded-data/patch.mjs",
|
||||
"<repo>/tests/corpus/stdout-patch-buffer-from-encoded-data/main.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -1534,9 +1534,12 @@ static bool scr_stdio_intercept(int fd, const void *data, size_t length, int fla
|
||||
}
|
||||
ScrDyn *chunk;
|
||||
if (flags & SCR_STDIO_HOOK_BYTES) {
|
||||
/* Always a Buffer: a write from a 'data' listener of a stream with an
|
||||
* encoding set is still the bytes it was given. */
|
||||
ScrBytes *b = scr_bytes_new(SCR_BYTES_U8, (double)length);
|
||||
memcpy(b->data, data, length);
|
||||
chunk = scr_dyn_new_chunk(b);
|
||||
b->is_buffer = true;
|
||||
chunk = scr_dyn_new_bytes(b);
|
||||
scr_bytes_release(b);
|
||||
} else {
|
||||
ScrStr *text = scr_str_new(data, length);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// A Buffer written to a replaced process.stdout.write from a 'data' listener
|
||||
// of a socket or an HTTP response with setEncoding("utf8") arrives as a
|
||||
// Buffer; the listener's own chunks are strings. patch.mjs installs the
|
||||
// replacement and prints what it received at exit.
|
||||
import * as http from "node:http";
|
||||
import * as net from "node:net";
|
||||
import "./patch.mjs";
|
||||
|
||||
const tcp = net.createServer((socket) => socket.end("tcp-data"));
|
||||
tcp.listen(0, "127.0.0.1", () => {
|
||||
const port = (tcp.address() as net.AddressInfo).port;
|
||||
const client = net.connect(port, "127.0.0.1");
|
||||
client.setEncoding("utf8");
|
||||
client.on("data", (text: string) => {
|
||||
process.stdout.write(Buffer.from(`socket ${typeof text} ${text}`));
|
||||
process.stdout.write(`socket text ${text}`);
|
||||
});
|
||||
client.on("end", () => {
|
||||
tcp.close();
|
||||
const server = http.createServer((req, res) => res.end("http-data"));
|
||||
server.listen(0, "127.0.0.1", () => {
|
||||
const httpPort = (server.address() as net.AddressInfo).port;
|
||||
http.get(`http://127.0.0.1:${httpPort}/`, (res) => {
|
||||
res.setEncoding("utf8");
|
||||
res.on("data", (text: string) => {
|
||||
process.stdout.write(Buffer.from(`response ${typeof text} ${text}`));
|
||||
});
|
||||
res.on("end", () => server.close());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
// Replaces process.stdout.write with a recorder; an exit handler prints what it saw.
|
||||
const seen = [];
|
||||
process.stdout.write = function (chunk) {
|
||||
const kind = typeof chunk === "string" ? "string" : Buffer.isBuffer(chunk) ? "Buffer" : typeof chunk;
|
||||
seen.push(`${kind}:${String(chunk)}`);
|
||||
return true;
|
||||
};
|
||||
process.on("exit", () => process.stderr.write(`${seen.join("\n")}\n`));
|
||||
@@ -0,0 +1 @@
|
||||
{ "plain": 5044, "san": 13845 }
|
||||
Reference in New Issue
Block a user