1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
<!DOCTYPE html>
<meta charset="utf-8">
<title>Cross-realm [[Set]] to window.location and location.href throws an error of correct realm</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/#window">
<link rel="help" href="https://webidl.spec.whatwg.org/#Unforgeable">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body>
<script>
const URL_SAME_ORIGIN = get_host_info().ORIGINAL_HOST;
const URL_CROSS_ORIGIN = get_host_info().HTTP_REMOTE_ORIGIN;
const URL_VALID = "#foo";
const URL_INVALID = "http://#";
const { get: locationGet, set: locationSet } = Object.getOwnPropertyDescriptor(window, "location");
const { get: hrefGet, set: hrefSet } = Object.getOwnPropertyDescriptor(location, "href");
promise_test(async t => {
const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow).location; });
assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.get(sameOriginWindow, "location", {}); });
assert_throws_js(TypeError, () => { locationGet.call({}); });
}, "Same-origin window.location getter throws TypeError in holder's realm on invalid |this| value");
promise_test(async t => {
const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow.location).href; });
assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.get(sameOriginWindow.location, "href", {}); });
assert_throws_js(TypeError, () => { hrefGet(); });
}, "Same-origin location.href getter throws TypeError in holder's realm on invalid |this| value");
promise_test(async t => {
const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
assert_throws_dom("SECURITY_ERR", () => { crossOriginWindow.location.href; });
assert_throws_dom("SECURITY_ERR", () => { hrefGet.call(crossOriginWindow.location); });
assert_equals(Object.getOwnPropertyDescriptor(crossOriginWindow.location, "href").get, undefined);
}, "Cross-origin location.href getter throws SecurityError in lexical realm");
promise_test(async t => {
const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow).location = URL_VALID; });
assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.set(sameOriginWindow, "location", URL_VALID, {}); });
assert_throws_js(TypeError, () => { locationSet.call(() => {}, URL_VALID); });
}, "Same-origin window.location setter throws TypeError in holder's realm on invalid |this| value");
promise_test(async t => {
const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow.location).href = URL_VALID; });
assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.set(sameOriginWindow.location, "href", URL_VALID, {}); });
assert_throws_js(TypeError, () => { hrefSet.call(undefined, URL_VALID); });
}, "Same-origin location.href setter throws TypeError in holder's realm on invalid |this| value");
promise_test(async t => {
const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
assert_throws_js(TypeError, () => { Object.create(crossOriginWindow).location = URL_VALID; });
assert_throws_js(TypeError, () => { Reflect.set(crossOriginWindow, "location", URL_VALID, {}); });
assert_throws_js(TypeError, () => { locationSet.call([], URL_VALID); });
}, "Cross-origin window.location setter throws TypeError in lexical realm on invalid |this| value");
promise_test(async t => {
const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
assert_throws_js(TypeError, () => { Object.create(crossOriginWindow.location).href = URL_VALID; });
assert_throws_js(TypeError, () => { Reflect.set(crossOriginWindow.location, "href", URL_VALID, {}); });
assert_throws_js(TypeError, () => { hrefSet.call(null, URL_VALID); });
}, "Cross-origin location.href setter throws TypeError in lexical realm on invalid |this| value");
promise_test(async t => {
const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
assert_throws_js(sameOriginWindow.TypeError, () => { sameOriginWindow.location = Symbol(); });
// The error originates in sameOriginWindow.location.href setter, hence it's not in realm of locationSet.
assert_throws_js(sameOriginWindow.TypeError, () => { locationSet.call(sameOriginWindow, Symbol()); });
}, "Same-origin window.location` setter throws TypeError in holder's realm on non-coercible URL argument");
promise_test(async t => {
const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
assert_throws_js(sameOriginWindow.TypeError, () => { sameOriginWindow.location.href = Symbol(); });
assert_throws_js(TypeError, () => { hrefSet.call(sameOriginWindow.location, Symbol()); });
}, "Same-origin location.href setter throws TypeError in holder's realm on non-coercible URL argument");
promise_test(async t => {
const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
assert_throws_js(TypeError, () => { crossOriginWindow.location = Symbol(); });
assert_throws_js(TypeError, () => { locationSet.call(crossOriginWindow, Symbol()); });
}, "Cross-origin window.location setter throws TypeError in lexical realm on non-coercible URL argument");
promise_test(async t => {
const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
assert_throws_js(TypeError, () => { crossOriginWindow.location.href = Symbol(); });
assert_throws_js(TypeError, () => { hrefSet.call(crossOriginWindow.location, Symbol()); });
}, "Cross-origin location.href setter throws TypeError in lexical realm on non-coercible URL argument");
function makeWindow(t, src) {
return new Promise(resolve => {
const iframe = document.createElement("iframe");
t.add_cleanup(() => { iframe.remove(); });
iframe.onload = () => { resolve(iframe.contentWindow); };
iframe.src = src;
document.body.append(iframe);
});
}
</script>
|