diff --git a/lib/internal/abort_controller.js b/lib/internal/abort_controller.js index a24b5b556e1a5e..1f63779a6e4efd 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'); @@ -295,7 +295,7 @@ class AbortSignal extends EventTarget { * @returns {AbortSignal} */ static timeout(delay) { - validateUint32(delay, 'delay', false); + delay = convertToInt('delay', delay, 64, { __proto__: null, enforceRange: true }); 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 948bd208cd2b90..ad407cbcef976f 100644 --- a/test/parallel/test-abortcontroller.js +++ b/test/parallel/test-abortcontroller.js @@ -225,6 +225,16 @@ test('AbortSignal with a timeout is not collected while there is an active liste assert.strictEqual(ref.deref(), undefined); }); +test('AbortSignal.timeout() correctly validates delay argument', () => { + for (const value of [0, -0, -0.9, Number.MAX_SAFE_INTEGER]) { + AbortSignal.timeout(value); + } + + for (const value of [-1, Number.MAX_SAFE_INTEGER + 1, Number.NaN]) { + assert.throws(() => AbortSignal.timeout(value), { code: 'ERR_INVALID_ARG_VALUE' }); + } +}); + test('Setting a long timeout should not keep the process open', () => { AbortSignal.timeout(1_200_000); });