From ea15c275c377dee0bf38a31e5afae5cffaa2e3fe Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Tue, 18 May 2021 19:19:04 +0300 Subject: [PATCH 1/5] WebKit export of https://bugs.webkit.org/show_bug.cgi?id=223758 --- .../global-object-implicit-this-value.any.js | 82 +++++++++++++++++++ ...rprocessor-called-on-globalthis.https.html | 29 +++++++ .../processors/dummy-processor-globalthis.js | 12 +++ 3 files changed, 123 insertions(+) create mode 100644 WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js create mode 100644 webaudio/the-audio-api/the-audioworklet-interface/audioworklet-registerprocessor-called-on-globalthis.https.html create mode 100644 webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js diff --git a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js new file mode 100644 index 00000000000000..8853109b07d01d --- /dev/null +++ b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js @@ -0,0 +1,82 @@ +// META: global=window,worker + +// https://heycam.github.io/webidl/#dfn-attribute-getter (step 1.1.2.1) +// https://heycam.github.io/webidl/#dfn-attribute-setter (step 4.5.1) +// https://heycam.github.io/webidl/#dfn-create-operation-function (step 2.1.2.1) + +const notGlobalObject = Object.create(Object.getPrototypeOf(globalThis)); + +test(() => { + assert_throws_js(TypeError, () => { Object.create(globalThis).self; }); + assert_throws_js(TypeError, () => { getGlobalPropertyDescriptor("location").get.call(notGlobalObject); }); + assert_throws_js(TypeError, () => { Reflect.get(globalThis, "navigator", notGlobalObject); }); + assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).onerror; }); +}, "Global object's getter throws when called on incompatible object"); + +test(() => { + assert_throws_js(TypeError, () => { Object.create(globalThis).origin = origin; }); + assert_throws_js(TypeError, () => { getGlobalPropertyDescriptor("onerror").set.call(notGlobalObject, onerror); }); + assert_throws_js(TypeError, () => { Reflect.set(globalThis, "onoffline", onoffline, notGlobalObject); }); + assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).ononline = ononline; }); +}, "Global object's setter throws when called on incompatible object"); + +test(() => { + assert_throws_js(TypeError, () => { Object.create(globalThis).setTimeout(() => {}, 100); }); + assert_throws_js(TypeError, () => { clearTimeout.call(notGlobalObject, () => {}); }); + assert_throws_js(TypeError, () => { Reflect.apply(btoa, notGlobalObject, [""]); }); + assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).removeEventListener("foo", () => {}); }); +}, "Global object's operation throws when called on incompatible object"); + +if (typeof document !== "undefined") { + test(() => { + assert_throws_js(TypeError, () => { Object.getOwnPropertyDescriptor(window, "document").get.call(document.all); }); + }, "Global object's getter throws when called on incompatible object (document.all)"); + + test(() => { + assert_throws_js(TypeError, () => { Object.getOwnPropertyDescriptor(window, "name").set.call(document.all); }); + }, "Global object's setter throws when called on incompatible object (document.all)"); + + test(() => { + assert_throws_js(TypeError, () => { alert.call(document.all); }); + }, "Global object's operation throws when called on incompatible object (document.all)"); +} + +const locationGetter = getGlobalPropertyDescriptor("location").get; +test(() => { + assert_equals(getGlobalPropertyDescriptor("self").get.call(null), self); + assert_equals((() => locationGetter())(), location); + assert_equals(Reflect.get(globalThis, "origin", null), origin); + assert_equals(Reflect.get(globalThis, "onoffline", undefined), onoffline); +}, "Global object's getter works when called on null / undefined"); + +test(() => { + const fn = () => {}; + + getGlobalPropertyDescriptor("origin").set.call(null, "foo"); + assert_equals(origin, "foo"); + getGlobalPropertyDescriptor("onerror").set.call(undefined, fn); + assert_equals(onerror, fn); + assert_true(Reflect.set(globalThis, "onoffline", fn, null)); + assert_equals(onoffline, fn); + + const ononlineSetter = getGlobalPropertyDescriptor("ononline").set; + (() => { ononlineSetter(fn); })(); + assert_equals(ononline, fn); +}, "Global object's setter works when called on null / undefined"); + +const __addEventListener = addEventListener; +test(() => { + assert_equals(atob.call(null, ""), ""); + assert_equals(typeof (0, setInterval)(() => {}, 100), "number"); + + (() => { __addEventListener("foo", event => { event.preventDefault(); }); })(); + const __dispatchEvent = dispatchEvent; + (() => { assert_false(__dispatchEvent(new Event("foo", { cancelable: true }))); })(); +}, "Global object's operation works when called on null / undefined"); + +function getGlobalPropertyDescriptor(key) { + for (let obj = globalThis; obj; obj = Object.getPrototypeOf(obj)) { + const desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc) return desc; + } +} diff --git a/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-registerprocessor-called-on-globalthis.https.html b/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-registerprocessor-called-on-globalthis.https.html new file mode 100644 index 00000000000000..718cadffc716f0 --- /dev/null +++ b/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-registerprocessor-called-on-globalthis.https.html @@ -0,0 +1,29 @@ + + + + + Test AudioWorkletGlobalScope's registerProcessor() called on globalThis + + + + + + + + + diff --git a/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js b/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js new file mode 100644 index 00000000000000..d1b16cc9aaac4a --- /dev/null +++ b/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js @@ -0,0 +1,12 @@ +class DummyProcessor extends AudioWorkletProcessor { + constructor() { + super(); + } + + process(inputs, outputs, parameters) { + // Doesn't do anything here. + return true; + } +} + +globalThis.registerProcessor('dummy-globalthis', DummyProcessor); From 37dd0df55d746f7774a4bda897a608179bbf480d Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Tue, 18 May 2021 20:12:40 +0300 Subject: [PATCH 2/5] Add a comment on "origin" --- .../ecmascript-binding/global-object-implicit-this-value.any.js | 1 + 1 file changed, 1 insertion(+) diff --git a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js index 8853109b07d01d..9bd51da52c13fe 100644 --- a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js +++ b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js @@ -52,6 +52,7 @@ test(() => { test(() => { const fn = () => {}; + // origin is [Replaceable] getGlobalPropertyDescriptor("origin").set.call(null, "foo"); assert_equals(origin, "foo"); getGlobalPropertyDescriptor("onerror").set.call(undefined, fn); From be6452e4ff68da5332441331026989cb524dc0ed Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Tue, 18 May 2021 20:12:49 +0300 Subject: [PATCH 3/5] alert => focus --- .../ecmascript-binding/global-object-implicit-this-value.any.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js index 9bd51da52c13fe..727c1fe9f2ebe2 100644 --- a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js +++ b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js @@ -37,7 +37,7 @@ if (typeof document !== "undefined") { }, "Global object's setter throws when called on incompatible object (document.all)"); test(() => { - assert_throws_js(TypeError, () => { alert.call(document.all); }); + assert_throws_js(TypeError, () => { focus.call(document.all); }); }, "Global object's operation throws when called on incompatible object (document.all)"); } From a76c5cea0bba8bfbc004b12aa1bd25c81078adb0 Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Tue, 18 May 2021 20:19:54 +0300 Subject: [PATCH 4/5] Add a comment on EvaluateCall --- .../ecmascript-binding/global-object-implicit-this-value.any.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js index 727c1fe9f2ebe2..12416d67ae2e27 100644 --- a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js +++ b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js @@ -41,6 +41,7 @@ if (typeof document !== "undefined") { }, "Global object's operation throws when called on incompatible object (document.all)"); } +// An engine might have different code path for calling a function from outer scope to implement step 1.b.iii of https://tc39.es/ecma262/#sec-evaluatecall const locationGetter = getGlobalPropertyDescriptor("location").get; test(() => { assert_equals(getGlobalPropertyDescriptor("self").get.call(null), self); @@ -65,6 +66,7 @@ test(() => { assert_equals(ononline, fn); }, "Global object's setter works when called on null / undefined"); +// An engine might have different code path for calling a function from outer scope to implement step 1.b.iii of https://tc39.es/ecma262/#sec-evaluatecall const __addEventListener = addEventListener; test(() => { assert_equals(atob.call(null, ""), ""); From 804ab6e348be49d10fa92ef483f0fdd3e0d125f1 Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Thu, 20 May 2021 22:03:36 +0300 Subject: [PATCH 5/5] Fix linter issues --- .../global-object-implicit-this-value.any.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js index 12416d67ae2e27..cc0d08fcbd0d9c 100644 --- a/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js +++ b/WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker // https://heycam.github.io/webidl/#dfn-attribute-getter (step 1.1.2.1) // https://heycam.github.io/webidl/#dfn-attribute-setter (step 4.5.1) @@ -21,7 +21,7 @@ test(() => { }, "Global object's setter throws when called on incompatible object"); test(() => { - assert_throws_js(TypeError, () => { Object.create(globalThis).setTimeout(() => {}, 100); }); + assert_throws_js(TypeError, () => { Object.create(globalThis).setInterval(() => {}, 100); }); assert_throws_js(TypeError, () => { clearTimeout.call(notGlobalObject, () => {}); }); assert_throws_js(TypeError, () => { Reflect.apply(btoa, notGlobalObject, [""]); }); assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).removeEventListener("foo", () => {}); });