tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

global-object-implicit-this-value.any.js (4436B)


      1 // META: global=window,worker
      2 
      3 // https://webidl.spec.whatwg.org/#dfn-attribute-getter (step 1.1.2.1)
      4 // https://webidl.spec.whatwg.org/#dfn-attribute-setter (step 4.5.1)
      5 // https://webidl.spec.whatwg.org/#dfn-create-operation-function (step 2.1.2.1)
      6 
      7 const notGlobalObject = Object.create(Object.getPrototypeOf(globalThis));
      8 
      9 test(() => {
     10    assert_throws_js(TypeError, () => { Object.create(globalThis).self; });
     11    assert_throws_js(TypeError, () => { getGlobalPropertyDescriptor("location").get.call(notGlobalObject); });
     12    assert_throws_js(TypeError, () => { Reflect.get(globalThis, "navigator", notGlobalObject); });
     13    assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).onerror; });
     14 }, "Global object's getter throws when called on incompatible object");
     15 
     16 test(() => {
     17    assert_throws_js(TypeError, () => { Object.create(globalThis).origin = origin; });
     18    assert_throws_js(TypeError, () => { getGlobalPropertyDescriptor("onerror").set.call(notGlobalObject, onerror); });
     19    assert_throws_js(TypeError, () => { Reflect.set(globalThis, "onoffline", onoffline, notGlobalObject); });
     20    assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).ononline = ononline; });
     21 }, "Global object's setter throws when called on incompatible object");
     22 
     23 test(() => {
     24    assert_throws_js(TypeError, () => { Object.create(globalThis).setInterval(() => {}, 100); });
     25    assert_throws_js(TypeError, () => { clearTimeout.call(notGlobalObject, () => {}); });
     26    assert_throws_js(TypeError, () => { Reflect.apply(btoa, notGlobalObject, [""]); });
     27    assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).removeEventListener("foo", () => {}); });
     28 }, "Global object's operation throws when called on incompatible object");
     29 
     30 if (typeof document !== "undefined") {
     31    test(() => {
     32        assert_throws_js(TypeError, () => { Object.getOwnPropertyDescriptor(window, "document").get.call(document.all); });
     33    }, "Global object's getter throws when called on incompatible object (document.all)");
     34 
     35    test(() => {
     36        assert_throws_js(TypeError, () => { Object.getOwnPropertyDescriptor(window, "name").set.call(document.all); });
     37    }, "Global object's setter throws when called on incompatible object (document.all)");
     38 
     39    test(() => {
     40        assert_throws_js(TypeError, () => { focus.call(document.all); });
     41    }, "Global object's operation throws when called on incompatible object (document.all)");
     42 }
     43 
     44 // 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
     45 const locationGetter = getGlobalPropertyDescriptor("location").get;
     46 test(() => {
     47    assert_equals(getGlobalPropertyDescriptor("self").get.call(null), self);
     48    assert_equals((() => locationGetter())(), location);
     49    assert_equals(Reflect.get(globalThis, "origin", null), origin);
     50    assert_equals(Reflect.get(globalThis, "onoffline", undefined), onoffline);
     51 }, "Global object's getter works when called on null / undefined");
     52 
     53 test(() => {
     54    const fn = () => {};
     55 
     56    // origin is [Replaceable]
     57    getGlobalPropertyDescriptor("origin").set.call(null, "foo");
     58    assert_equals(origin, "foo");
     59    getGlobalPropertyDescriptor("onerror").set.call(undefined, fn);
     60    assert_equals(onerror, fn);
     61    assert_true(Reflect.set(globalThis, "onoffline", fn, null));
     62    assert_equals(onoffline, fn);
     63 
     64    const ononlineSetter = getGlobalPropertyDescriptor("ononline").set;
     65    (() => { ononlineSetter(fn); })();
     66    assert_equals(ononline, fn);
     67 }, "Global object's setter works when called on null / undefined");
     68 
     69 // 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
     70 const __addEventListener = addEventListener;
     71 test(() => {
     72    assert_equals(atob.call(null, ""), "");
     73    assert_equals(typeof (0, setInterval)(() => {}, 100), "number");
     74 
     75    (() => { __addEventListener("foo", event => { event.preventDefault(); }); })();
     76    const __dispatchEvent = dispatchEvent;
     77    (() => { assert_false(__dispatchEvent(new Event("foo", { cancelable: true }))); })();
     78 }, "Global object's operation works when called on null / undefined");
     79 
     80 function getGlobalPropertyDescriptor(key) {
     81    for (let obj = globalThis; obj; obj = Object.getPrototypeOf(obj)) {
     82        const desc = Object.getOwnPropertyDescriptor(obj, key);
     83        if (desc) return desc;
     84    }
     85 }