Bug 1248865 - Some small changes to JSXray and tests. r=bz

This commit is contained in:
Tom Schuster 2016-10-25 10:18:40 +02:00
parent d3d6b4b949
commit 13263ee62f
2 changed files with 46 additions and 29 deletions

View File

@ -146,6 +146,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
testPromise();
testArrayBuffer();
// We could also test DataView and Iterator here for completeness, but it's
// more trouble than it's worth.
@ -250,6 +252,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
gConstructorProperties['Promise'] =
constructorProps(["resolve", "reject", "all", "race", Symbol.species]);
gPrototypeProperties['ArrayBuffer'] =
["constructor", "byteLength", "slice", Symbol.toStringTag];
gConstructorProperties['ArrayBuffer'] =
constructorProps(["isView", "slice", Symbol.species]);
// Sort an array that may contain symbols as well as strings.
function sortProperties(arr) {
function sortKey(prop) {
@ -304,14 +311,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
"Xray and local method results stringify identically");
// If invoking this method returns something non-Xrayable, the
// stringification is going to return [object Opaque]. This happens for
// xrayedTypedArray.buffer, for instance, since we don't have Xrays
// to ArrayBuffers. Just check for that case.
if (!/Opaque/.test(method.call(xray))) {
is(method.call(xray) + "",
lookupCallable(xray.wrappedJSObject).call(xray.wrappedJSObject) + "",
"Xray and waived method results stringify identically");
}
// stringification is going to return [object Opaque].
ok(!/Opaque/.test(method.call(xray)), "Method result is xrayable");
is(method.call(xray) + "",
lookupCallable(xray.wrappedJSObject).call(xray.wrappedJSObject) + "",
"Xray and waived method results stringify identically");
}
}
}
@ -888,6 +892,36 @@ for (var prop of props) {
is(Cu.getGlobalForObject(pr.wrappedJSObject.then), iwin, "Underlying global is correct");
}
function testArrayBuffer() {
testXray('ArrayBuffer', new iwin.ArrayBuffer(0), new iwin.ArrayBuffer(12));
var t = new iwin.ArrayBuffer(12);
is(t.byteLength, 12, "ArrayBuffer byteLength is correct");
is(t.slice(4).byteLength, 8, "ArrayBuffer byteLength is correct after slicing");
is(Cu.getGlobalForObject(t.slice(4)), iwin, "Slice results lives in the target compartment");
is(Object.getPrototypeOf(t.slice(4)), iwin.ArrayBuffer.prototype, "Slice results proto lives in target compartment")
is(ArrayBuffer.slice(t, 4).byteLength, 8, "ArrayBuffer.slice (deprecated) works");
var i32Array = new Int32Array(t);
// i32Array is going to be created in the buffer's target compartment,
// but usually this is unobservable, because the proto is set to
// the current compartment's prototype.
// However Xrays ignore the object's proto and claim its proto is
// the default proto for that class in the relevant compartment,
// so see through this proto hack.
todo_is(Object.getPrototypeOf(i32Array), Int32Array.prototype, "Int32Array has correct proto");
is(i32Array.length, 3, "Int32Array created from Xray ArrayBuffer has the correct length");
is(i32Array.buffer, t, "Int32Array has the correct buffer that we passed in");
i32Array = new iwin.Int32Array(t);
is(Object.getPrototypeOf(i32Array), iwin.Int32Array.prototype, "Xray Int32Array has correct proto");
is(i32Array.length, 3, "Xray Int32Array created from Xray ArrayBuffer has the correct length");
is(i32Array.buffer, t, "Xray Int32Array has the correct buffer that we passed in");
t = (new iwin.Int32Array(2)).buffer;
is(t.byteLength, 8, "Can access ArrayBuffer returned by buffer property");
}
]]>
</script>
<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" />

View File

@ -87,6 +87,7 @@ IsJSXraySupported(JSProtoKey key)
case JSProto_SavedFrame:
case JSProto_RegExp:
case JSProto_Promise:
case JSProto_ArrayBuffer:
return true;
default:
return false;
@ -324,29 +325,11 @@ bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not same-origin with target");
}
// Disallow (most) non-Xrayable objects.
// Disallow non-Xrayable objects.
XrayType xrayType = GetXrayType(propObj);
if (xrayType == NotXray || xrayType == XrayForOpaqueObject) {
if (IdentifyStandardInstance(propObj) == JSProto_ArrayBuffer) {
// Given that non-Xrayable objects are now opaque by default,
// this restriction is somewhat more draconian than it needs to
// be. It's true that script can't do much with an opaque
// object, so in general it doesn't make much of a difference.
// But one place it _does_ make a difference is in the
// structured clone algorithm. When traversing an object to
// clone it, the algorithm dutifully traverses inspects the
// security wrapper without unwrapping it, so it won't see
// properties we restrict here. But there are some object types
// that the structured clone algorithm can handle safely even
// without Xrays (i.e. ArrayBuffer, where it just clones the
// underlying byte array).
//
// So we make some special cases here for such situations. Pass
// them through.
} else {
JSAutoCompartment ac(cx, wrapper);
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not Xrayable");
}
JSAutoCompartment ac(cx, wrapper);
return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not Xrayable");
}
// Disallow callables.