Skip to content

Commit 4d36383

Browse files
Alexey Shvaykawebkit-commit-queue
Alexey Shvayka
authored andcommitted
Some WebIDL operations / attributes incorrectly use _current_ realm instead of _relevant_
https://bugs.webkit.org/show_bug.cgi?id=230941 Patch by Alexey Shvayka <[email protected]> on 2021-12-10 Reviewed by Sam Weinig. LayoutTests/imported/w3c: Import WPT tests from web-platform-tests/wpt#32012. * web-platform-tests/dom/events/Event-timestamp-cross-realm-getter-expected.txt: Added. * web-platform-tests/dom/events/Event-timestamp-cross-realm-getter.html: Added. * web-platform-tests/html/browsers/history/the-history-interface/history_back_cross_realm_method-expected.txt: Added. * web-platform-tests/html/browsers/history/the-history-interface/history_back_cross_realm_method.html: Added. * web-platform-tests/html/browsers/history/the-history-interface/history_forward_cross_realm_method-expected.txt: Added. * web-platform-tests/html/browsers/history/the-history-interface/history_forward_cross_realm_method.html: Added. * web-platform-tests/html/browsers/history/the-history-interface/history_go_cross_realm_method-expected.txt: Added. * web-platform-tests/html/browsers/history/the-history-interface/history_go_cross_realm_method.html: Added. * web-platform-tests/html/webappapis/scripting/reporterror-cross-realm-method-expected.txt: Added. * web-platform-tests/html/webappapis/scripting/reporterror-cross-realm-method.html: Added. * web-platform-tests/html/webappapis/structured-clone/structured-clone-cross-realm-method-expected.txt: Added. * web-platform-tests/html/webappapis/structured-clone/structured-clone-cross-realm-method.html: Added. * web-platform-tests/requestidlecallback/callback-timeRemaining-cross-realm-method-expected.txt: Added. * web-platform-tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html: Added. Source/WebCore: This patch replaces _current_ global object with _relevant_, as per recommendation for spec authors [1], for select WebIDL operations / attributes that satisfy all the following conditions: 1) it's an instance member: static ones and constructors can't use _relevant_; 2) it's on standards track (not deprecated / WebKit-only / internal); 3) the change is directly observable: global object is used for something beyond lifecycle / event loop / parsing CSS etc; 4) the change either aligns WebKit with both Blink and Gecko, or the spec explicitly requires _relevant_ realm / settings object. Most of the remaining [CallWith=GlobalObject] instances are correctly used for converting JS arguments to WebIDL values; the rest, along with _current_ Document and ScriptExecutionContext, either match the spec or replacing them with _relevant_ global object is not directly observable (see condition #3). This change is aimed at fixing web-exposed APIs rather than performing a global cleanup. [1] https://html.spec.whatwg.org/multipage/webappapis.html#concept-current-everything Tests: imported/w3c/web-platform-tests/dom/events/Event-timestamp-cross-realm-getter.html imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/history_back_cross_realm_method.html imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/history_forward_cross_realm_method.html imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/history_go_cross_realm_method.html imported/w3c/web-platform-tests/html/webappapis/scripting/reporterror-cross-realm-method.html imported/w3c/web-platform-tests/html/webappapis/structured-clone/structured-clone-cross-realm-method.html imported/w3c/web-platform-tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html * Modules/indexeddb/IDBFactory.idl: https://www.w3.org/TR/IndexedDB/#dom-idbfactory-open (step 2) https://www.w3.org/TR/IndexedDB/#dom-idbfactory-deletedatabase (step 1) https://www.w3.org/TR/IndexedDB/#dom-idbfactory-databases (step 1) * Modules/paymentrequest/PaymentRequest.idl: https://www.w3.org/TR/payment-request/#show-method (steps 2-4) https://www.w3.org/TR/payment-request/#can-make-payment-algorithm (before step 1) * bindings/scripts/CodeGeneratorJS.pm: (GenerateCallWith): * bindings/scripts/IDLAttributes.json: * bindings/scripts/test/JS/JSTestObj.cpp: * bindings/scripts/test/TestObj.idl: * dom/Event.idl: https://dom.spec.whatwg.org/#inner-event-creation-steps (step 3) * dom/IdleDeadline.idl: https://w3c.github.io/requestidlecallback/#the-requestidlecallback-method (step 1) * page/History.idl: https://html.spec.whatwg.org/multipage/history.html#dom-history-go (step 1) https://html.spec.whatwg.org/multipage/history.html#dom-history-back (step 1) https://html.spec.whatwg.org/multipage/history.html#dom-history-forward (step 1) * page/DOMWindow.cpp: (WebCore::DOMWindow::setTimeout): (WebCore::DOMWindow::setInterval): * page/DOMWindow.h: * workers/WorkerGlobalScope.cpp: (WebCore::WorkerGlobalScope::setTimeout): (WebCore::WorkerGlobalScope::setInterval): * workers/WorkerGlobalScope.h: Although condition #4 isn't satisfied for setTimeout() / setInterval() because _current_ global object is used only for logging, replacing it with _relevant_ nicely cleans up method signatures. * page/WindowOrWorkerGlobalScope.cpp: (WebCore::WindowOrWorkerGlobalScope::structuredClone): * page/WindowOrWorkerGlobalScope.h: * page/WindowOrWorkerGlobalScope.idl: https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception https://html.spec.whatwg.org/multipage/structured-data.html#structured-cloning (step 2) Canonical link: https://commits.webkit.org/245123@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286895 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 131cc3c commit 4d36383

32 files changed

+434
-33
lines changed

LayoutTests/imported/w3c/ChangeLog

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
2021-12-10 Alexey Shvayka <[email protected]>
2+
3+
Some WebIDL operations / attributes incorrectly use _current_ realm instead of _relevant_
4+
https://bugs.webkit.org/show_bug.cgi?id=230941
5+
6+
Reviewed by Sam Weinig.
7+
8+
Import WPT tests from https://github.com/web-platform-tests/wpt/pull/32012.
9+
10+
* web-platform-tests/dom/events/Event-timestamp-cross-realm-getter-expected.txt: Added.
11+
* web-platform-tests/dom/events/Event-timestamp-cross-realm-getter.html: Added.
12+
* web-platform-tests/html/browsers/history/the-history-interface/history_back_cross_realm_method-expected.txt: Added.
13+
* web-platform-tests/html/browsers/history/the-history-interface/history_back_cross_realm_method.html: Added.
14+
* web-platform-tests/html/browsers/history/the-history-interface/history_forward_cross_realm_method-expected.txt: Added.
15+
* web-platform-tests/html/browsers/history/the-history-interface/history_forward_cross_realm_method.html: Added.
16+
* web-platform-tests/html/browsers/history/the-history-interface/history_go_cross_realm_method-expected.txt: Added.
17+
* web-platform-tests/html/browsers/history/the-history-interface/history_go_cross_realm_method.html: Added.
18+
* web-platform-tests/html/webappapis/scripting/reporterror-cross-realm-method-expected.txt: Added.
19+
* web-platform-tests/html/webappapis/scripting/reporterror-cross-realm-method.html: Added.
20+
* web-platform-tests/html/webappapis/structured-clone/structured-clone-cross-realm-method-expected.txt: Added.
21+
* web-platform-tests/html/webappapis/structured-clone/structured-clone-cross-realm-method.html: Added.
22+
* web-platform-tests/requestidlecallback/callback-timeRemaining-cross-realm-method-expected.txt: Added.
23+
* web-platform-tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html: Added.
24+
125
2021-12-10 Alexey Shvayka <[email protected]>
226

327
Extend the scope where the Window's current event is set
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
PASS event.timeStamp is initialized using event's relevant global object
4+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!doctype html>
2+
<meta charset="utf-8">
3+
<title>event.timeStamp is initialized using event's relevant global object</title>
4+
<link rel="help" href="https://dom.spec.whatwg.org/#ref-for-dom-event-timestamp%E2%91%A1">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
8+
<body>
9+
<script>
10+
const t = async_test();
11+
t.step_timeout(() => {
12+
const iframeDelayed = document.createElement("iframe");
13+
iframeDelayed.onload = t.step_func_done(() => {
14+
// Use eval() to eliminate false-positive test result for WebKit builds before r280256,
15+
// which invoked WebIDL accessors in context of lexical (caller) global object.
16+
const timeStampExpected = iframeDelayed.contentWindow.eval(`new Event("foo").timeStamp`);
17+
const eventDelayed = new iframeDelayed.contentWindow.Event("foo");
18+
19+
const {get} = Object.getOwnPropertyDescriptor(Event.prototype, "timeStamp");
20+
assert_approx_equals(get.call(eventDelayed), timeStampExpected, 5, "via Object.getOwnPropertyDescriptor");
21+
22+
Object.setPrototypeOf(eventDelayed, Event.prototype);
23+
assert_approx_equals(eventDelayed.timeStamp, timeStampExpected, 5, "via Object.setPrototypeOf");
24+
});
25+
document.body.append(iframeDelayed);
26+
}, 1000);
27+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
PASS history.back() uses this's associated document's browsing context to determine if navigation is allowed
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!doctype html>
2+
<meta charset="utf-8">
3+
<title>history.back() uses this's associated document's browsing context to determine if navigation is allowed</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/history.html#dom-history-back">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
8+
<iframe id="sandboxedIframe" srcdoc="hello" sandbox="allow-scripts allow-same-origin"></iframe>
9+
<script>
10+
const t = async_test();
11+
12+
t.step(() => {
13+
history.pushState({}, null, "?prev");
14+
history.pushState({}, null, "?current");
15+
16+
sandboxedIframe.contentWindow.history.back.call(history);
17+
});
18+
19+
window.onpopstate = t.step_func_done(() => {
20+
assert_equals(location.search, "?prev");
21+
});
22+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
PASS history.forward() uses this's associated document's browsing context to determine if navigation is allowed
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!doctype html>
2+
<meta charset="utf-8">
3+
<title>history.forward() uses this's associated document's browsing context to determine if navigation is allowed</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/history.html#dom-history-forward">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
8+
<iframe id="sandboxedIframe" srcdoc="hello" sandbox="allow-scripts allow-same-origin"></iframe>
9+
<script>
10+
const t = async_test();
11+
12+
t.step(() => {
13+
history.pushState({}, null, "?prev");
14+
history.pushState({}, null, "?current");
15+
history.back();
16+
});
17+
18+
let isCrossRealmForward = false;
19+
window.onpopstate = t.step_func(() => {
20+
if (isCrossRealmForward) {
21+
assert_equals(location.search, "?current");
22+
t.done();
23+
} else {
24+
sandboxedIframe.contentWindow.history.forward.call(history);
25+
isCrossRealmForward = true;
26+
}
27+
});
28+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
PASS history.go() uses this's associated document's browsing context to determine if navigation is allowed
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!doctype html>
2+
<meta charset="utf-8">
3+
<title>history.go() uses this's associated document's browsing context to determine if navigation is allowed</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/history.html#dom-history-go">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
8+
<iframe id="sandboxedIframe" srcdoc="hello" sandbox="allow-scripts allow-same-origin"></iframe>
9+
<script>
10+
const t = async_test();
11+
12+
t.step(() => {
13+
history.pushState({}, null, "?prev=2");
14+
history.pushState({}, null, "?prev=1");
15+
history.pushState({}, null, "?current");
16+
17+
sandboxedIframe.contentWindow.history.go.call(history, -2);
18+
});
19+
20+
window.onpopstate = t.step_func_done(() => {
21+
assert_equals(location.search, "?prev=2");
22+
});
23+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CONSOLE MESSAGE: TypeError: foo
2+
3+
4+
PASS self.reportError() dispatches an "error" event for this's relevant global object
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!doctype html>
2+
<meta charset="utf-8">
3+
<title>self.reportError() dispatches an "error" event for this's relevant global object</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#dom-reporterror">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
8+
<body>
9+
<script>
10+
setup({ allow_uncaught_exception: true });
11+
12+
async_test(t => {
13+
window.addEventListener("error", t.unreached_func("'error' event should not be dispatched for top window!"));
14+
15+
const iframe = document.createElement("iframe");
16+
iframe.onload = t.step_func_done(() => {
17+
let eventFired = false;
18+
const error = new TypeError("foo");
19+
const otherWindow = iframe.contentWindow;
20+
otherWindow.addEventListener("error", t.step_func(event => {
21+
assert_equals(event.error, error);
22+
eventFired = true;
23+
}));
24+
25+
window.reportError.call(otherWindow, error);
26+
assert_true(eventFired);
27+
});
28+
document.body.append(iframe);
29+
});
30+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
3+
PASS Object instance
4+
PASS Array instance
5+
PASS Date instance
6+
PASS RegExp instance
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!doctype html>
2+
<title>self.structuredClone() uses this's relevant Realm for deserialization</title>
3+
<link rel="help" href="https://html.spec.whatwg.org/multipage/structured-data.html#structured-cloning">
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
7+
<body>
8+
<script>
9+
const iframe = document.createElement("iframe");
10+
iframe.onload = () => {
11+
const otherWindow = iframe.contentWindow;
12+
for (const key of ["Object", "Array", "Date", "RegExp"]) {
13+
test(() => {
14+
const cloned = otherWindow.structuredClone.call(window, new otherWindow[key]);
15+
assert_true(cloned instanceof window[key]);
16+
}, `${key} instance`);
17+
}
18+
};
19+
document.body.append(iframe);
20+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
PASS IdleDeadline::timeRemaining() uses relevant global object as a high-res timestamp origin
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!doctype html><!-- webkit-test-runner [ RequestIdleCallbackEnabled=true ] -->
2+
<meta charset="utf-8">
3+
<meta name="timeout" content="long">
4+
<title>IdleDeadline::timeRemaining() uses relevant global object as a high-res timestamp origin</title>
5+
<link rel="help" href="https://w3c.github.io/requestidlecallback/#dom-idledeadline-timeremaining">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
9+
<body>
10+
<script>
11+
const t = async_test();
12+
t.step_timeout(() => {
13+
const iframeDelayed = document.createElement("iframe");
14+
iframeDelayed.onload = t.step_func(() => {
15+
requestIdleCallback(t.step_func_done(deadline => {
16+
assert_approx_equals(
17+
iframeDelayed.contentWindow.IdleDeadline.prototype.timeRemaining.call(deadline),
18+
deadline.timeRemaining(),
19+
5,
20+
);
21+
}));
22+
});
23+
document.body.append(iframeDelayed);
24+
}, 1000);
25+
</script>

Source/WebCore/ChangeLog

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,82 @@
1+
2021-12-10 Alexey Shvayka <[email protected]>
2+
3+
Some WebIDL operations / attributes incorrectly use _current_ realm instead of _relevant_
4+
https://bugs.webkit.org/show_bug.cgi?id=230941
5+
6+
Reviewed by Sam Weinig.
7+
8+
This patch replaces _current_ global object with _relevant_, as per recommendation
9+
for spec authors [1], for select WebIDL operations / attributes that satisfy all
10+
the following conditions:
11+
12+
1) it's an instance member: static ones and constructors can't use _relevant_;
13+
2) it's on standards track (not deprecated / WebKit-only / internal);
14+
3) the change is directly observable: global object is used for something
15+
beyond lifecycle / event loop / parsing CSS etc;
16+
4) the change either aligns WebKit with both Blink and Gecko,
17+
or the spec explicitly requires _relevant_ realm / settings object.
18+
19+
Most of the remaining [CallWith=GlobalObject] instances are correctly used for
20+
converting JS arguments to WebIDL values; the rest, along with _current_ Document
21+
and ScriptExecutionContext, either match the spec or replacing them with _relevant_
22+
global object is not directly observable (see condition #3).
23+
24+
This change is aimed at fixing web-exposed APIs rather than performing a global cleanup.
25+
26+
[1] https://html.spec.whatwg.org/multipage/webappapis.html#concept-current-everything
27+
28+
Tests: imported/w3c/web-platform-tests/dom/events/Event-timestamp-cross-realm-getter.html
29+
imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/history_back_cross_realm_method.html
30+
imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/history_forward_cross_realm_method.html
31+
imported/w3c/web-platform-tests/html/browsers/history/the-history-interface/history_go_cross_realm_method.html
32+
imported/w3c/web-platform-tests/html/webappapis/scripting/reporterror-cross-realm-method.html
33+
imported/w3c/web-platform-tests/html/webappapis/structured-clone/structured-clone-cross-realm-method.html
34+
imported/w3c/web-platform-tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html
35+
36+
* Modules/indexeddb/IDBFactory.idl:
37+
https://www.w3.org/TR/IndexedDB/#dom-idbfactory-open (step 2)
38+
https://www.w3.org/TR/IndexedDB/#dom-idbfactory-deletedatabase (step 1)
39+
https://www.w3.org/TR/IndexedDB/#dom-idbfactory-databases (step 1)
40+
41+
* Modules/paymentrequest/PaymentRequest.idl:
42+
https://www.w3.org/TR/payment-request/#show-method (steps 2-4)
43+
https://www.w3.org/TR/payment-request/#can-make-payment-algorithm (before step 1)
44+
45+
* bindings/scripts/CodeGeneratorJS.pm:
46+
(GenerateCallWith):
47+
* bindings/scripts/IDLAttributes.json:
48+
* bindings/scripts/test/JS/JSTestObj.cpp:
49+
* bindings/scripts/test/TestObj.idl:
50+
* dom/Event.idl:
51+
https://dom.spec.whatwg.org/#inner-event-creation-steps (step 3)
52+
53+
* dom/IdleDeadline.idl:
54+
https://w3c.github.io/requestidlecallback/#the-requestidlecallback-method (step 1)
55+
56+
* page/History.idl:
57+
https://html.spec.whatwg.org/multipage/history.html#dom-history-go (step 1)
58+
https://html.spec.whatwg.org/multipage/history.html#dom-history-back (step 1)
59+
https://html.spec.whatwg.org/multipage/history.html#dom-history-forward (step 1)
60+
61+
* page/DOMWindow.cpp:
62+
(WebCore::DOMWindow::setTimeout):
63+
(WebCore::DOMWindow::setInterval):
64+
* page/DOMWindow.h:
65+
* workers/WorkerGlobalScope.cpp:
66+
(WebCore::WorkerGlobalScope::setTimeout):
67+
(WebCore::WorkerGlobalScope::setInterval):
68+
* workers/WorkerGlobalScope.h:
69+
Although condition #4 isn't satisfied for setTimeout() / setInterval() because
70+
_current_ global object is used only for logging, replacing it with _relevant_
71+
nicely cleans up method signatures.
72+
73+
* page/WindowOrWorkerGlobalScope.cpp:
74+
(WebCore::WindowOrWorkerGlobalScope::structuredClone):
75+
* page/WindowOrWorkerGlobalScope.h:
76+
* page/WindowOrWorkerGlobalScope.idl:
77+
https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception
78+
https://html.spec.whatwg.org/multipage/structured-data.html#structured-cloning (step 2)
79+
180
2021-12-10 Devin Rousso <[email protected]>
281

382
WKWebView doesn’t respond to -copyFont: and -pasteFont:

Source/WebCore/Modules/indexeddb/IDBFactory.idl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
SkipVTableValidation,
2828
Exposed=(Window,Worker)
2929
] interface IDBFactory {
30-
[NewObject, CallWith=ScriptExecutionContext] IDBOpenDBRequest open(DOMString name, optional [EnforceRange] unsigned long long version);
31-
[NewObject, CallWith=ScriptExecutionContext] IDBOpenDBRequest deleteDatabase(DOMString name);
30+
[NewObject, CallWith=RelevantScriptExecutionContext] IDBOpenDBRequest open(DOMString name, optional [EnforceRange] unsigned long long version);
31+
[NewObject, CallWith=RelevantScriptExecutionContext] IDBOpenDBRequest deleteDatabase(DOMString name);
3232

33-
[CallWith=ScriptExecutionContext] Promise<sequence<IDBDatabaseInfo>> databases();
33+
[CallWith=RelevantScriptExecutionContext] Promise<sequence<IDBDatabaseInfo>> databases();
3434

3535
[CallWith=GlobalObject] short cmp(any first, any second);
3636
};

Source/WebCore/Modules/paymentrequest/PaymentRequest.idl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
] interface PaymentRequest : EventTarget {
3434
[CallWith=Document] constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options);
3535

36-
[CallWith=Document] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise);
36+
[CallWith=RelevantDocument] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise);
3737
Promise<undefined> abort();
38-
[CallWith=Document] Promise<boolean> canMakePayment();
38+
[CallWith=RelevantDocument] Promise<boolean> canMakePayment();
3939

4040
readonly attribute DOMString id;
4141
readonly attribute PaymentAddress? shippingAddress;

0 commit comments

Comments
 (0)