Compare commits

...

4 Commits

Author SHA1 Message Date
Don Isaac
1c6db01b3d add test cases 2024-12-06 17:27:41 -08:00
Don Isaac
f1e0ff2c83 fix(node/readline): close input when readline interface closes 2024-12-06 17:10:13 -08:00
Don Isaac
cc72c90ae6 Merge branch 'main' of github.com:oven-sh/bun into don/fix/unbounded-queue-panic 2024-12-06 17:09:17 -08:00
Don Isaac
c7191abb0a fix: gracefully handle missing front in UnboundedQueue 2024-12-05 18:57:52 -08:00
4 changed files with 37 additions and 1 deletions

View File

@@ -30,7 +30,8 @@ pub fn UnboundedQueue(comptime T: type, comptime next_field: meta.FieldEnum(T))
pub fn next(self: *Self.Batch.Iterator) ?*T {
if (self.batch.count == 0) return null;
const front = self.batch.front orelse unreachable;
bun.debugAssert(self.batch.front != null);
const front = self.batch.front orelse return null;
self.batch.front = @field(front, next_name);
self.batch.count -= 1;
return front;

View File

@@ -1583,6 +1583,7 @@ var _Interface = class Interface extends InterfaceConstructor {
this[kSetRawMode](false);
}
this.closed = true;
this.input.close();
this.emit("close");
}

View File

@@ -0,0 +1,8 @@
import readline from "readline";
const rl1 = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl1.close();

View File

@@ -3,6 +3,7 @@ import { createTest } from "node-harness";
import { EventEmitter } from "node:events";
import readline from "node:readline";
import { PassThrough, Writable } from "node:stream";
import path from "path";
const { beforeEach, describe, it, createDoneDotAll, createCallCheckCtx, assert } = createTest(import.meta.path);
var {
@@ -15,6 +16,8 @@ var {
// Helpers
// ----------------------------------------------------------------------------
/** Get an absolute path to a `readline` fixture. */
const fixture = (name: string): string => path.resolve(import.meta.dirname, "fixtures", name);
class TestWritable extends Writable {
data;
constructor() {
@@ -1327,6 +1330,29 @@ describe("readline.Interface", () => {
assert.strictEqual(getStringWidth("\u0301\u200D\u200E"), 0);
});
it("should not hang when stdint is closed", done => {
// const subprocess = Bun.spawn(["bun", "run", fixture("readline-stdin-immediate-close.ts")]);
var timeout: Timer | undefined;
const subprocess = Bun.spawn(["bun", "run", fixture("readline-stdin-immediate-close.ts")]);
// const subprocess = Bun.spawn(["bun", "run", "./fixtures/readline-stdin-immediate-close.ts"]);
timeout = setTimeout(() => {
const error = new Error("readline did not close after 2.5s. This means stdint is keeping the event loop alive.");
subprocess.kill();
done(error);
}, 2_500);
subprocess.exited
.then(() => {
clearTimeout(timeout);
done();
})
.catch(e => {
clearTimeout(timeout);
done(e);
});
});
// // Check if vt control chars are stripped
// assert.strictEqual(stripVTControlCharacters('\u001b[31m> \u001b[39m'), '> ');
// assert.strictEqual(