blob: f72ed1eaf26932bfc2cba6010b1a72387d749a69 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Location objects' custom [[GetPrototypeOf]] trap permit [[Prototype]] chain cycles to be created through them</title>
<link rel="author" title="Jeff Walden" href="http://whereswalden.com/" />
<link rel="help" href="https://tc39.github.io/ecma262/#sec-ordinarysetprototypeof" />
<link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#location-getprototypeof" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<hr />
<iframe id="same-origin-different-window"></iframe>
<iframe id="cross-origin-joined-via-document-domain"></iframe>
<script>
"use strict";
// Handle same-origin, same-window testing first, before any async-requiring
// testing.
test(function() {
var LocationPrototype = Location.prototype;
var ObjectPrototype = Object.prototype;
var loc = window.location;
var locProto = Object.getPrototypeOf(loc);
assert_equals(locProto, LocationPrototype,
"loc's initial [[Prototype]]");
var originalLocProtoProto = Object.getPrototypeOf(locProto);
assert_equals(originalLocProtoProto, ObjectPrototype,
"Location.prototype's initial [[Prototype]]");
Object.setPrototypeOf(locProto, loc);
assert_equals(Object.getPrototypeOf(locProto), loc,
"LocationPrototype's new [[Prototype]]");
assert_equals(Object.getPrototypeOf(loc), locProto,
"loc's new [[Prototype]]");
// Reset so as not to muck with testharness.js expectations.
Object.setPrototypeOf(locProto, originalLocProtoProto);
}, "same-origin, same-window location cycle");
var pathdir =
location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
var triggerCrossOriginTest = (function() {
var crossOrigin =
document.getElementById("cross-origin-joined-via-document-domain");
var t = async_test("cross-origin location has null prototype");
return new Promise(function(resolve, reject) {
crossOrigin.onload = t.step_func_done(function(e) {
try {
var win = crossOrigin.contentWindow;
var loc = win.location;
// Between un-opted-in windows, location objects appear to have null
// [[Prototype]].
assert_equals(Object.getPrototypeOf(loc), null,
"cross-origin unjoined location's [[Prototype]");
resolve();
} catch (e) {
reject(e);
throw e;
}
});
crossOrigin.src =
"//{{domains[www]}}:" + location.port + pathdir + "cross_origin_joined_frame.sub.html";
})
.catch(t.unreached_func("crossOrigin onload/src setting"));
})();
var triggerSameOriginTest = (function() {
var sameOriginDifferentWindow =
document.getElementById("same-origin-different-window");
var t = async_test("same-origin, different-window location cycle");
return new Promise(function(resolve, reject) {
sameOriginDifferentWindow.onload = t.step_func_done(function() {
try {
var win = sameOriginDifferentWindow.contentWindow;
var loc = win.location;
var LocationPrototype = win.Location.prototype;
var ObjectPrototype = win.Object.prototype;
var locProto = Object.getPrototypeOf(loc);
assert_equals(locProto, LocationPrototype,
"loc's initial [[Prototype]]");
var originalLocProtoProto = Object.getPrototypeOf(locProto);
assert_equals(originalLocProtoProto, ObjectPrototype,
"Location.prototype's initial [[Prototype]]");
Object.setPrototypeOf(locProto, loc);
assert_equals(Object.getPrototypeOf(locProto), loc,
"LocationPrototype's new [[Prototype]]");
assert_equals(Object.getPrototypeOf(loc), locProto,
"loc's new [[Prototype]]");
// Reset so as not to muck with testharness.js expectations.
Object.setPrototypeOf(locProto, originalLocProtoProto);
resolve();
} catch (e) {
reject(e);
throw e;
}
});
sameOriginDifferentWindow.src = "same_origin_frame.html";
})
.catch(t.unreached_func("sameOriginDifferentWindow onload/src setting"));
})();
function crossOriginJoinTest() {
var win =
document.getElementById("cross-origin-joined-via-document-domain")
.contentWindow;
assert_equals(document.domain, "{{host}}");
var loc = win.location;
var threw = false;
try {
// Still cross-origin until the document.domain set below.
win.Location;
} catch (e) {
threw = true;
}
assert_equals(threw, true,
"accessing win.Location before joining win's origin");
// Join with other frames that have set |document.domain| to this same
// value -- namely, this cross-origin frame. Now access between the two
// windows should be permitted.
assert_equals(document.domain, "{{host}}",
"initial document.domain sanity check");
document.domain = "{{host}}";
var LocationPrototype = win.Location.prototype;
var ObjectPrototype = win.Object.prototype;
var locProto = Object.getPrototypeOf(loc);
assert_equals(locProto, LocationPrototype,
"loc's initial [[Prototype]]");
var originalLocProtoProto = Object.getPrototypeOf(locProto);
assert_equals(originalLocProtoProto, ObjectPrototype,
"Location.prototype's initial [[Prototype]]");
Object.setPrototypeOf(locProto, loc);
assert_equals(Object.getPrototypeOf(locProto), loc,
"LocationPrototype's new [[Prototype]]");
assert_equals(Object.getPrototypeOf(loc), locProto,
"loc's new [[Prototype]]");
// Reset so as not to muck with testharness.js expectations.
Object.setPrototypeOf(locProto, originalLocProtoProto);
}
function run() {
var t =
async_test("cross-origin, but joined via document.domain, location cycle");
// The cross-origin/joined case must be tested after both unjoined same-origin
// and unjoined cross-origin tests: by mucking with document.domain, the
// cross-origin/joined case makes it impossible to perform those tests.
t.step(function() {
Promise.all([triggerCrossOriginTest, triggerSameOriginTest])
.then(t.step_func_done(crossOriginJoinTest),
t.unreached_func("cross-origin joined error case"));
});
}
run();
</script>
</body>
</html>