summaryrefslogtreecommitdiff
path: root/lib/readline.js
diff options
context:
space:
mode:
authorAntoine du Hamel <duhamelantoine1995@gmail.com>2021-05-02 11:47:01 +0200
committerAntoine du Hamel <duhamelantoine1995@gmail.com>2021-09-16 23:16:42 +0200
commit707dd77d8636399aefb1cad14a56369a77d4db13 (patch)
tree6c2d89584ea90621bcf48e7acf5a64cba3c38772 /lib/readline.js
parent8122d243ae010f3a5c1d50e4d0ef6374d4e407b4 (diff)
downloadnode-new-707dd77d8636399aefb1cad14a56369a77d4db13.tar.gz
readline: validate `AbortSignal`s and remove unused event listeners
PR-URL: https://github.com/nodejs/node/pull/37947 Fixes: https://github.com/nodejs/node/issues/37287 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com>
Diffstat (limited to 'lib/readline.js')
-rw-r--r--lib/readline.js27
1 files changed, 22 insertions, 5 deletions
diff --git a/lib/readline.js b/lib/readline.js
index 1d9e839f2c..759b9ca246 100644
--- a/lib/readline.js
+++ b/lib/readline.js
@@ -48,6 +48,7 @@ const {
inspect,
} = require('internal/util/inspect');
const { promisify } = require('internal/util');
+const { validateAbortSignal } = require('internal/validators');
/**
* @typedef {import('./stream.js').Readable} Readable
@@ -130,13 +131,22 @@ Interface.prototype.question = function(query, options, cb) {
options = typeof options === 'object' && options !== null ? options : {};
if (options.signal) {
+ validateAbortSignal(options.signal, 'options.signal');
if (options.signal.aborted) {
return;
}
- options.signal.addEventListener('abort', () => {
+ const onAbort = () => {
this[kQuestionCancel]();
- }, { once: true });
+ };
+ options.signal.addEventListener('abort', onAbort, { once: true });
+ const cleanup = () => {
+ options.signal.removeEventListener(onAbort);
+ };
+ cb = typeof cb === 'function' ? (answer) => {
+ cleanup();
+ return cb(answer);
+ } : cleanup;
}
if (typeof cb === 'function') {
@@ -151,13 +161,20 @@ Interface.prototype.question[promisify.custom] = function(query, options) {
}
return new Promise((resolve, reject) => {
- this.question(query, options, resolve);
+ let cb = resolve;
if (options.signal) {
- options.signal.addEventListener('abort', () => {
+ const onAbort = () => {
reject(new AbortError());
- }, { once: true });
+ };
+ options.signal.addEventListener('abort', onAbort, { once: true });
+ cb = (answer) => {
+ options.signal.removeEventListener('abort', onAbort);
+ resolve(answer);
+ };
}
+
+ this.question(query, options, cb);
});
};