diff --git a/doc/api/globals.md b/doc/api/globals.md index 8e002eb897a221..b8d29fdbb9343f 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -117,6 +117,10 @@ Returns a new already aborted `AbortSignal`. added: - v17.3.0 - v16.14.0 +changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/58594 + description: Change validation of `delay` to allow non-integer. --> * `delay` {number} The number of milliseconds to wait before triggering diff --git a/lib/internal/abort_controller.js b/lib/internal/abort_controller.js index 4fbed3bfa7399a..17a2c5fff4b649 100644 --- a/lib/internal/abort_controller.js +++ b/lib/internal/abort_controller.js @@ -44,13 +44,13 @@ const { } = require('internal/errors'); const { converters, + convertToInt, createInterfaceConverter, createSequenceConverter, } = require('internal/webidl'); const { validateObject, - validateUint32, kValidateObjectAllowObjects, } = require('internal/validators'); @@ -236,7 +236,15 @@ class AbortSignal extends EventTarget { * @returns {AbortSignal} */ static timeout(delay) { - validateUint32(delay, 'delay', false); + const opts = { __proto__: null, enforceRange: true }; + try { + delay = convertToInt('delay', delay, 32, opts); + } catch (err) { + // this is so that the validation error change is not a semver-major + // TODO: remove this try/catch and validateUint32 as semver-major + validateUint32(delay, 'delay', false); + throw err; + } const signal = new AbortSignal(kDontThrowSymbol); signal[kTimeout] = true; clearTimeoutRegistry.register( diff --git a/test/parallel/test-abortcontroller.js b/test/parallel/test-abortcontroller.js index 87781f849ffb52..6834636c48d082 100644 --- a/test/parallel/test-abortcontroller.js +++ b/test/parallel/test-abortcontroller.js @@ -274,3 +274,35 @@ test('abortSignal.throwIfAobrted() works as expected (3)', () => { throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason); Reflect.defineProperty(AbortSignal.prototype, 'reason', originalDesc); }); + +test('abortSignal.timeout() works with special \'delay\' value', async () => { + const inputs = [ + null, + true, + false, + '', + [], + 0, + 0.0, + 0.1, + 0.5, + 1, + 1.0, + 2147483648, + 12345678901234, + ]; + + const signals = []; + + for (let i = 0; i < inputs.length; i++) { + signals[i] = AbortSignal.timeout(inputs[i]); + } + + await sleep(2); + + for (let i = 0; i < inputs.length; i++) { + ok(signals[i].aborted); + ok(signals[i].reason instanceof DOMException); + strictEqual(signals[i].reason.name, 'TimeoutError'); + } +});