diff options
author | Antoine du Hamel <duhamelantoine1995@gmail.com> | 2021-05-02 11:47:01 +0200 |
---|---|---|
committer | Antoine du Hamel <duhamelantoine1995@gmail.com> | 2021-09-16 23:16:42 +0200 |
commit | 707dd77d8636399aefb1cad14a56369a77d4db13 (patch) | |
tree | 6c2d89584ea90621bcf48e7acf5a64cba3c38772 /lib/readline.js | |
parent | 8122d243ae010f3a5c1d50e4d0ef6374d4e407b4 (diff) | |
download | node-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.js | 27 |
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); }); }; |