mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
lib: fix AbortSignal.timeout parameter validation
PR-URL: https://github.com/nodejs/node/pull/42856 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
This commit is contained in:
@@ -170,7 +170,7 @@ class AbortSignal extends EventTarget {
|
||||
* @returns {AbortSignal}
|
||||
*/
|
||||
static timeout(delay) {
|
||||
validateUint32(delay, 'delay', true);
|
||||
validateUint32(delay, 'delay', false);
|
||||
const signal = createAbortSignal();
|
||||
signal[kTimeout] = true;
|
||||
clearTimeoutRegistry.register(
|
||||
|
||||
2
test/fixtures/wpt/README.md
vendored
2
test/fixtures/wpt/README.md
vendored
@@ -12,7 +12,7 @@ Last update:
|
||||
|
||||
- common: https://github.com/web-platform-tests/wpt/tree/03c5072aff/common
|
||||
- console: https://github.com/web-platform-tests/wpt/tree/767ae35464/console
|
||||
- dom/abort: https://github.com/web-platform-tests/wpt/tree/c49cafb491/dom/abort
|
||||
- dom/abort: https://github.com/web-platform-tests/wpt/tree/8fadb38120/dom/abort
|
||||
- dom/events: https://github.com/web-platform-tests/wpt/tree/f8821adb28/dom/events
|
||||
- encoding: https://github.com/web-platform-tests/wpt/tree/c1b24fce6e/encoding
|
||||
- fetch/data-urls/resources: https://github.com/web-platform-tests/wpt/tree/7c79d998ff/fetch/data-urls/resources
|
||||
|
||||
28
test/fixtures/wpt/dom/abort/AbortSignal.any.js
vendored
28
test/fixtures/wpt/dom/abort/AbortSignal.any.js
vendored
@@ -10,3 +10,31 @@ async_test(t => {
|
||||
s.onabort = t.unreached_func("abort event handler called");
|
||||
t.step_timeout(() => { t.done(); }, 2000);
|
||||
}, "signal returned by AbortSignal.abort() should not fire abort event");
|
||||
|
||||
test(t => {
|
||||
const signal = AbortSignal.timeout(0);
|
||||
assert_true(signal instanceof AbortSignal, "returned object is an AbortSignal");
|
||||
assert_false(signal.aborted, "returned signal is not already aborted");
|
||||
}, "AbortSignal.timeout() returns a non-aborted signal");
|
||||
|
||||
async_test(t => {
|
||||
const signal = AbortSignal.timeout(5);
|
||||
signal.onabort = t.step_func_done(() => {
|
||||
assert_true(signal.aborted, "signal is aborted");
|
||||
assert_true(signal.reason instanceof DOMException, "signal.reason is a DOMException");
|
||||
assert_equals(signal.reason.name, "TimeoutError", "signal.reason is a TimeoutError");
|
||||
});
|
||||
}, "Signal returned by AbortSignal.timeout() times out");
|
||||
|
||||
async_test(t => {
|
||||
let result = "";
|
||||
for (const value of ["1", "2", "3"]) {
|
||||
const signal = AbortSignal.timeout(5);
|
||||
signal.onabort = t.step_func(() => { result += value; });
|
||||
}
|
||||
|
||||
const signal = AbortSignal.timeout(5);
|
||||
signal.onabort = t.step_func_done(() => {
|
||||
assert_equals(result, "123", "Timeout order should be 123");
|
||||
});
|
||||
}, "AbortSignal timeouts fire in order");
|
||||
|
||||
19
test/fixtures/wpt/dom/abort/abort-signal-timeout.html
vendored
Normal file
19
test/fixtures/wpt/dom/abort/abort-signal-timeout.html
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>AbortSignal.timeout frame detach</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<iframe id="iframe"></iframe>
|
||||
<script>
|
||||
async_test(t => {
|
||||
const signal = iframe.contentWindow.AbortSignal.timeout(5);
|
||||
signal.onabort = t.unreached_func("abort must not fire");
|
||||
|
||||
iframe.remove();
|
||||
|
||||
t.step_timeout(() => {
|
||||
assert_false(signal.aborted);
|
||||
t.done();
|
||||
}, 10);
|
||||
}, "Signal returned by AbortSignal.timeout() is not aborted after frame detach");
|
||||
</script>
|
||||
22
test/fixtures/wpt/dom/abort/crashtests/timeout-close.html
vendored
Normal file
22
test/fixtures/wpt/dom/abort/crashtests/timeout-close.html
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="test-wait">
|
||||
<meta charset="utf-8">
|
||||
<iframe id="iframe"></iframe>
|
||||
<script>
|
||||
const srcdoc = `
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
const xhr = new XMLHttpRequest()
|
||||
setTimeout(() => {
|
||||
xhr.open('GET', '/', false)
|
||||
xhr.send()
|
||||
AbortSignal.timeout(41.62684667994843)
|
||||
}, 1)
|
||||
setTimeout(() => {
|
||||
location.href = "about:blank"
|
||||
parent.document.documentElement.classList.remove("test-wait")
|
||||
}, 0)
|
||||
</` + "script>";
|
||||
iframe.srcdoc = srcdoc;
|
||||
</script>
|
||||
123
test/fixtures/wpt/dom/abort/event.any.js
vendored
123
test/fixtures/wpt/dom/abort/event.any.js
vendored
@@ -4,6 +4,8 @@ test(t => {
|
||||
let state = "begin";
|
||||
|
||||
assert_false(s.aborted);
|
||||
assert_true("reason" in s, "signal has reason property");
|
||||
assert_equals(s.reason, undefined, "signal.reason is initially undefined");
|
||||
|
||||
s.addEventListener("abort",
|
||||
t.step_func(e => {
|
||||
@@ -15,6 +17,8 @@ test(t => {
|
||||
|
||||
assert_equals(state, "aborted");
|
||||
assert_true(s.aborted);
|
||||
assert_true(s.reason instanceof DOMException, "signal.reason is DOMException");
|
||||
assert_equals(s.reason.name, "AbortError", "signal.reason is AbortError");
|
||||
|
||||
c.abort();
|
||||
}, "AbortController abort() should fire event synchronously");
|
||||
@@ -64,4 +68,123 @@ test(t => {
|
||||
controller.abort();
|
||||
}, "the abort event should have the right properties");
|
||||
|
||||
test(t => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
assert_true("reason" in signal, "signal has reason property");
|
||||
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
|
||||
|
||||
const reason = Error("hello");
|
||||
controller.abort(reason);
|
||||
|
||||
assert_true(signal.aborted, "signal.aborted");
|
||||
assert_equals(signal.reason, reason, "signal.reason");
|
||||
}, "AbortController abort(reason) should set signal.reason");
|
||||
|
||||
test(t => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
assert_true("reason" in signal, "signal has reason property");
|
||||
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
|
||||
|
||||
controller.abort();
|
||||
|
||||
assert_true(signal.aborted, "signal.aborted");
|
||||
assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException");
|
||||
assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError");
|
||||
}, "aborting AbortController without reason creates an \"AbortError\" DOMException");
|
||||
|
||||
test(t => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
assert_true("reason" in signal, "signal has reason property");
|
||||
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
|
||||
|
||||
controller.abort(undefined);
|
||||
|
||||
assert_true(signal.aborted, "signal.aborted");
|
||||
assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException");
|
||||
assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError");
|
||||
}, "AbortController abort(undefined) creates an \"AbortError\" DOMException");
|
||||
|
||||
test(t => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
||||
assert_true("reason" in signal, "signal has reason property");
|
||||
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
|
||||
|
||||
controller.abort(null);
|
||||
|
||||
assert_true(signal.aborted, "signal.aborted");
|
||||
assert_equals(signal.reason, null, "signal.reason");
|
||||
}, "AbortController abort(null) should set signal.reason");
|
||||
|
||||
test(t => {
|
||||
const signal = AbortSignal.abort();
|
||||
|
||||
assert_true(signal.aborted, "signal.aborted");
|
||||
assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException");
|
||||
assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError");
|
||||
}, "static aborting signal should have right properties");
|
||||
|
||||
test(t => {
|
||||
const reason = Error("hello");
|
||||
const signal = AbortSignal.abort(reason);
|
||||
|
||||
assert_true(signal.aborted, "signal.aborted");
|
||||
assert_equals(signal.reason, reason, "signal.reason");
|
||||
}, "static aborting signal with reason should set signal.reason");
|
||||
|
||||
test(t => {
|
||||
const reason = new Error('boom');
|
||||
const signal = AbortSignal.abort(reason);
|
||||
assert_true(signal.aborted);
|
||||
assert_throws_exactly(reason, () => signal.throwIfAborted());
|
||||
}, "throwIfAborted() should throw abort.reason if signal aborted");
|
||||
|
||||
test(t => {
|
||||
const signal = AbortSignal.abort('hello');
|
||||
assert_true(signal.aborted);
|
||||
assert_throws_exactly('hello', () => signal.throwIfAborted());
|
||||
}, "throwIfAborted() should throw primitive abort.reason if signal aborted");
|
||||
|
||||
test(t => {
|
||||
const controller = new AbortController();
|
||||
assert_false(controller.signal.aborted);
|
||||
controller.signal.throwIfAborted();
|
||||
}, "throwIfAborted() should not throw if signal not aborted");
|
||||
|
||||
test(t => {
|
||||
const signal = AbortSignal.abort();
|
||||
|
||||
assert_true(
|
||||
signal.reason instanceof DOMException,
|
||||
"signal.reason is a DOMException"
|
||||
);
|
||||
assert_equals(
|
||||
signal.reason,
|
||||
signal.reason,
|
||||
"signal.reason returns the same DOMException"
|
||||
);
|
||||
}, "AbortSignal.reason returns the same DOMException");
|
||||
|
||||
test(t => {
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
|
||||
assert_true(
|
||||
controller.signal.reason instanceof DOMException,
|
||||
"signal.reason is a DOMException"
|
||||
);
|
||||
assert_equals(
|
||||
controller.signal.reason,
|
||||
controller.signal.reason,
|
||||
"signal.reason returns the same DOMException"
|
||||
);
|
||||
}, "AbortController.signal.reason returns the same DOMException");
|
||||
|
||||
done();
|
||||
|
||||
12
test/fixtures/wpt/dom/abort/reason-constructor.html
vendored
Normal file
12
test/fixtures/wpt/dom/abort/reason-constructor.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>AbortSignal.reason constructor</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<iframe id="iframe"></iframe>
|
||||
<script>
|
||||
test(() => {
|
||||
const aborted = iframe.contentWindow.AbortSignal.abort();
|
||||
assert_equals(aborted.reason.constructor, iframe.contentWindow.DOMException, "DOMException is using the correct global");
|
||||
}, "AbortSignal.reason.constructor should be from iframe");
|
||||
</script>
|
||||
2
test/fixtures/wpt/versions.json
vendored
2
test/fixtures/wpt/versions.json
vendored
@@ -8,7 +8,7 @@
|
||||
"path": "console"
|
||||
},
|
||||
"dom/abort": {
|
||||
"commit": "c49cafb491d99d6318f8f24a26936cc66501f412",
|
||||
"commit": "8fadb381209a215280dc3ad96d0f135b6005f176",
|
||||
"path": "dom/abort"
|
||||
},
|
||||
"dom/events": {
|
||||
|
||||
Reference in New Issue
Block a user