Skip to content

Commit d7470ad

Browse files
dnalborczykRafaelGSS
authored andcommitted
lib: fix AbortSignal.timeout parameter validation
PR-URL: #42856 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Zijian Liu <[email protected]>
1 parent f10f2c1 commit d7470ad

8 files changed

+207
-3
lines changed

lib/internal/abort_controller.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class AbortSignal extends EventTarget {
170170
* @returns {AbortSignal}
171171
*/
172172
static timeout(delay) {
173-
validateUint32(delay, 'delay', true);
173+
validateUint32(delay, 'delay', false);
174174
const signal = createAbortSignal();
175175
signal[kTimeout] = true;
176176
clearTimeoutRegistry.register(

test/fixtures/wpt/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Last update:
1212

1313
- common: https://github.com/web-platform-tests/wpt/tree/03c5072aff/common
1414
- console: https://github.com/web-platform-tests/wpt/tree/767ae35464/console
15-
- dom/abort: https://github.com/web-platform-tests/wpt/tree/c49cafb491/dom/abort
15+
- dom/abort: https://github.com/web-platform-tests/wpt/tree/8fadb38120/dom/abort
1616
- dom/events: https://github.com/web-platform-tests/wpt/tree/f8821adb28/dom/events
1717
- encoding: https://github.com/web-platform-tests/wpt/tree/c1b24fce6e/encoding
1818
- fetch/data-urls/resources: https://github.com/web-platform-tests/wpt/tree/7c79d998ff/fetch/data-urls/resources

test/fixtures/wpt/dom/abort/AbortSignal.any.js

+28
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,31 @@ async_test(t => {
1010
s.onabort = t.unreached_func("abort event handler called");
1111
t.step_timeout(() => { t.done(); }, 2000);
1212
}, "signal returned by AbortSignal.abort() should not fire abort event");
13+
14+
test(t => {
15+
const signal = AbortSignal.timeout(0);
16+
assert_true(signal instanceof AbortSignal, "returned object is an AbortSignal");
17+
assert_false(signal.aborted, "returned signal is not already aborted");
18+
}, "AbortSignal.timeout() returns a non-aborted signal");
19+
20+
async_test(t => {
21+
const signal = AbortSignal.timeout(5);
22+
signal.onabort = t.step_func_done(() => {
23+
assert_true(signal.aborted, "signal is aborted");
24+
assert_true(signal.reason instanceof DOMException, "signal.reason is a DOMException");
25+
assert_equals(signal.reason.name, "TimeoutError", "signal.reason is a TimeoutError");
26+
});
27+
}, "Signal returned by AbortSignal.timeout() times out");
28+
29+
async_test(t => {
30+
let result = "";
31+
for (const value of ["1", "2", "3"]) {
32+
const signal = AbortSignal.timeout(5);
33+
signal.onabort = t.step_func(() => { result += value; });
34+
}
35+
36+
const signal = AbortSignal.timeout(5);
37+
signal.onabort = t.step_func_done(() => {
38+
assert_equals(result, "123", "Timeout order should be 123");
39+
});
40+
}, "AbortSignal timeouts fire in order");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE HTML>
2+
<meta charset=utf-8>
3+
<title>AbortSignal.timeout frame detach</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<iframe id="iframe"></iframe>
7+
<script>
8+
async_test(t => {
9+
const signal = iframe.contentWindow.AbortSignal.timeout(5);
10+
signal.onabort = t.unreached_func("abort must not fire");
11+
12+
iframe.remove();
13+
14+
t.step_timeout(() => {
15+
assert_false(signal.aborted);
16+
t.done();
17+
}, 10);
18+
}, "Signal returned by AbortSignal.timeout() is not aborted after frame detach");
19+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html class="test-wait">
3+
<meta charset="utf-8">
4+
<iframe id="iframe"></iframe>
5+
<script>
6+
const srcdoc = `
7+
<!DOCTYPE html>
8+
<meta charset="utf-8">
9+
<script>
10+
const xhr = new XMLHttpRequest()
11+
setTimeout(() => {
12+
xhr.open('GET', '/', false)
13+
xhr.send()
14+
AbortSignal.timeout(41.62684667994843)
15+
}, 1)
16+
setTimeout(() => {
17+
location.href = "about:blank"
18+
parent.document.documentElement.classList.remove("test-wait")
19+
}, 0)
20+
</` + "script>";
21+
iframe.srcdoc = srcdoc;
22+
</script>

test/fixtures/wpt/dom/abort/event.any.js

+123
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ test(t => {
44
let state = "begin";
55

66
assert_false(s.aborted);
7+
assert_true("reason" in s, "signal has reason property");
8+
assert_equals(s.reason, undefined, "signal.reason is initially undefined");
79

810
s.addEventListener("abort",
911
t.step_func(e => {
@@ -15,6 +17,8 @@ test(t => {
1517

1618
assert_equals(state, "aborted");
1719
assert_true(s.aborted);
20+
assert_true(s.reason instanceof DOMException, "signal.reason is DOMException");
21+
assert_equals(s.reason.name, "AbortError", "signal.reason is AbortError");
1822

1923
c.abort();
2024
}, "AbortController abort() should fire event synchronously");
@@ -64,4 +68,123 @@ test(t => {
6468
controller.abort();
6569
}, "the abort event should have the right properties");
6670

71+
test(t => {
72+
const controller = new AbortController();
73+
const signal = controller.signal;
74+
75+
assert_true("reason" in signal, "signal has reason property");
76+
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
77+
78+
const reason = Error("hello");
79+
controller.abort(reason);
80+
81+
assert_true(signal.aborted, "signal.aborted");
82+
assert_equals(signal.reason, reason, "signal.reason");
83+
}, "AbortController abort(reason) should set signal.reason");
84+
85+
test(t => {
86+
const controller = new AbortController();
87+
const signal = controller.signal;
88+
89+
assert_true("reason" in signal, "signal has reason property");
90+
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
91+
92+
controller.abort();
93+
94+
assert_true(signal.aborted, "signal.aborted");
95+
assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException");
96+
assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError");
97+
}, "aborting AbortController without reason creates an \"AbortError\" DOMException");
98+
99+
test(t => {
100+
const controller = new AbortController();
101+
const signal = controller.signal;
102+
103+
assert_true("reason" in signal, "signal has reason property");
104+
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
105+
106+
controller.abort(undefined);
107+
108+
assert_true(signal.aborted, "signal.aborted");
109+
assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException");
110+
assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError");
111+
}, "AbortController abort(undefined) creates an \"AbortError\" DOMException");
112+
113+
test(t => {
114+
const controller = new AbortController();
115+
const signal = controller.signal;
116+
117+
assert_true("reason" in signal, "signal has reason property");
118+
assert_equals(signal.reason, undefined, "signal.reason is initially undefined");
119+
120+
controller.abort(null);
121+
122+
assert_true(signal.aborted, "signal.aborted");
123+
assert_equals(signal.reason, null, "signal.reason");
124+
}, "AbortController abort(null) should set signal.reason");
125+
126+
test(t => {
127+
const signal = AbortSignal.abort();
128+
129+
assert_true(signal.aborted, "signal.aborted");
130+
assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException");
131+
assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError");
132+
}, "static aborting signal should have right properties");
133+
134+
test(t => {
135+
const reason = Error("hello");
136+
const signal = AbortSignal.abort(reason);
137+
138+
assert_true(signal.aborted, "signal.aborted");
139+
assert_equals(signal.reason, reason, "signal.reason");
140+
}, "static aborting signal with reason should set signal.reason");
141+
142+
test(t => {
143+
const reason = new Error('boom');
144+
const signal = AbortSignal.abort(reason);
145+
assert_true(signal.aborted);
146+
assert_throws_exactly(reason, () => signal.throwIfAborted());
147+
}, "throwIfAborted() should throw abort.reason if signal aborted");
148+
149+
test(t => {
150+
const signal = AbortSignal.abort('hello');
151+
assert_true(signal.aborted);
152+
assert_throws_exactly('hello', () => signal.throwIfAborted());
153+
}, "throwIfAborted() should throw primitive abort.reason if signal aborted");
154+
155+
test(t => {
156+
const controller = new AbortController();
157+
assert_false(controller.signal.aborted);
158+
controller.signal.throwIfAborted();
159+
}, "throwIfAborted() should not throw if signal not aborted");
160+
161+
test(t => {
162+
const signal = AbortSignal.abort();
163+
164+
assert_true(
165+
signal.reason instanceof DOMException,
166+
"signal.reason is a DOMException"
167+
);
168+
assert_equals(
169+
signal.reason,
170+
signal.reason,
171+
"signal.reason returns the same DOMException"
172+
);
173+
}, "AbortSignal.reason returns the same DOMException");
174+
175+
test(t => {
176+
const controller = new AbortController();
177+
controller.abort();
178+
179+
assert_true(
180+
controller.signal.reason instanceof DOMException,
181+
"signal.reason is a DOMException"
182+
);
183+
assert_equals(
184+
controller.signal.reason,
185+
controller.signal.reason,
186+
"signal.reason returns the same DOMException"
187+
);
188+
}, "AbortController.signal.reason returns the same DOMException");
189+
67190
done();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE HTML>
2+
<meta charset=utf-8>
3+
<title>AbortSignal.reason constructor</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<iframe id="iframe"></iframe>
7+
<script>
8+
test(() => {
9+
const aborted = iframe.contentWindow.AbortSignal.abort();
10+
assert_equals(aborted.reason.constructor, iframe.contentWindow.DOMException, "DOMException is using the correct global");
11+
}, "AbortSignal.reason.constructor should be from iframe");
12+
</script>

test/fixtures/wpt/versions.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"path": "console"
99
},
1010
"dom/abort": {
11-
"commit": "c49cafb491d99d6318f8f24a26936cc66501f412",
11+
"commit": "8fadb381209a215280dc3ad96d0f135b6005f176",
1212
"path": "dom/abort"
1313
},
1414
"dom/events": {

0 commit comments

Comments
 (0)