Skip to content

Commit 35fda91

Browse files
committed
readline: fix question stack overflow
This commit fixes readline interface's question callback wrapping when it is being called with `signal` option. Previous version completely overwrites passed callback and throws "Maximum call stack size exceeded" error.
1 parent 71071f8 commit 35fda91

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

lib/readline.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,10 @@ Interface.prototype.question = function(query, options, cb) {
143143
const cleanup = () => {
144144
options.signal.removeEventListener(onAbort);
145145
};
146+
const originalCb = cb;
146147
cb = typeof cb === 'function' ? (answer) => {
147148
cleanup();
148-
return cb(answer);
149+
return originalCb(answer);
149150
} : cleanup;
150151
}
151152

test/parallel/test-readline-interface.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,17 @@ for (let i = 0; i < 12; i++) {
10061006
rli.close();
10071007
}
10081008

1009+
// Calling the question callback with abort signal
1010+
{
1011+
const [rli] = getInterface({ terminal });
1012+
const signal = new AbortController().signal;
1013+
rli.question('foo?', { signal }, common.mustCall((answer) => {
1014+
assert.strictEqual(answer, 'bar');
1015+
}));
1016+
rli.write('bar\n');
1017+
rli.close();
1018+
}
1019+
10091020
// Calling the question multiple times
10101021
{
10111022
const [rli] = getInterface({ terminal });

test/parallel/test-readline-promises-interface.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,17 @@ for (let i = 0; i < 12; i++) {
909909
rli.close();
910910
}
911911

912+
// Calling the question callback with abort signal
913+
{
914+
const [rli] = getInterface({ terminal });
915+
const signal = new AbortController().signal;
916+
rli.question('foo?', { signal }).then(common.mustCall((answer) => {
917+
assert.strictEqual(answer, 'bar');
918+
}));
919+
rli.write('bar\n');
920+
rli.close();
921+
}
922+
912923
// Aborting a question
913924
{
914925
const ac = new AbortController();

0 commit comments

Comments
 (0)