159 lines
3.6 KiB
JavaScript
159 lines
3.6 KiB
JavaScript
"use strict";
|
|
|
|
const global = this;
|
|
|
|
add_task(async function test_structuredCloneHolder() {
|
|
let principal = Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI("http://example.com/"),
|
|
{}
|
|
);
|
|
|
|
let sandbox = Cu.Sandbox(principal);
|
|
|
|
const obj = { foo: [{ bar: "baz" }] };
|
|
|
|
let holder = new StructuredCloneHolder("", "", obj);
|
|
|
|
// Test same-compartment deserialization
|
|
|
|
let res = holder.deserialize(global, true);
|
|
|
|
notEqual(
|
|
res,
|
|
obj,
|
|
"Deserialized result is a different object from the original"
|
|
);
|
|
|
|
deepEqual(
|
|
res,
|
|
obj,
|
|
"Deserialized result is deeply equivalent to the original"
|
|
);
|
|
|
|
equal(
|
|
Cu.getObjectPrincipal(res),
|
|
Cu.getObjectPrincipal(global),
|
|
"Deserialized result has the correct principal"
|
|
);
|
|
|
|
// Test non-object-value round-trip.
|
|
|
|
equal(
|
|
new StructuredCloneHolder("", "", "foo").deserialize(global),
|
|
"foo",
|
|
"Round-tripping non-object values works as expected"
|
|
);
|
|
|
|
// Test cross-compartment deserialization
|
|
|
|
res = holder.deserialize(sandbox, true);
|
|
|
|
notEqual(
|
|
res,
|
|
obj,
|
|
"Cross-compartment-deserialized result is a different object from the original"
|
|
);
|
|
|
|
deepEqual(
|
|
res,
|
|
obj,
|
|
"Cross-compartment-deserialized result is deeply equivalent to the original"
|
|
);
|
|
|
|
equal(
|
|
Cu.getObjectPrincipal(res),
|
|
principal,
|
|
"Cross-compartment-deserialized result has the correct principal"
|
|
);
|
|
|
|
// Test message manager transportability
|
|
|
|
const MSG = "StructuredCloneHolder";
|
|
|
|
let resultPromise = new Promise(resolve => {
|
|
Services.ppmm.addMessageListener(MSG, resolve);
|
|
});
|
|
|
|
Services.cpmm.sendAsyncMessage(MSG, holder);
|
|
|
|
res = await resultPromise;
|
|
|
|
ok(
|
|
StructuredCloneHolder.isInstance(res.data),
|
|
"Sending structured clone holders through message managers works as expected"
|
|
);
|
|
|
|
deepEqual(
|
|
res.data.deserialize(global, true),
|
|
obj,
|
|
"Sending structured clone holders through message managers works as expected"
|
|
);
|
|
|
|
// Test that attempting to deserialize a neutered holder throws.
|
|
|
|
deepEqual(
|
|
holder.deserialize(global),
|
|
obj,
|
|
"Deserialized result is correct when discarding data"
|
|
);
|
|
|
|
Assert.throws(
|
|
() => holder.deserialize(global),
|
|
err => err.result == Cr.NS_ERROR_NOT_INITIALIZED,
|
|
"Attempting to deserialize neutered holder throws"
|
|
);
|
|
|
|
Assert.throws(
|
|
() => holder.deserialize(global, true),
|
|
err => err.result == Cr.NS_ERROR_NOT_INITIALIZED,
|
|
"Attempting to deserialize neutered holder throws"
|
|
);
|
|
});
|
|
|
|
// Test that X-rays passed to an exported function are serialized
|
|
// through their exported wrappers.
|
|
add_task(async function test_structuredCloneHolder_xray() {
|
|
let principal = Services.scriptSecurityManager.createContentPrincipal(
|
|
Services.io.newURI("http://example.com/"),
|
|
{}
|
|
);
|
|
|
|
let sandbox1 = Cu.Sandbox(principal, { wantXrays: true });
|
|
|
|
let sandbox2 = Cu.Sandbox(principal, { wantXrays: true });
|
|
Cu.evalInSandbox(`this.x = {y: "z", get z() { return "q" }}`, sandbox2);
|
|
|
|
sandbox1.x = sandbox2.x;
|
|
|
|
let holder;
|
|
Cu.exportFunction(
|
|
function serialize(val) {
|
|
holder = new StructuredCloneHolder("", "", val, sandbox1);
|
|
},
|
|
sandbox1,
|
|
{ defineAs: "serialize" }
|
|
);
|
|
|
|
Cu.evalInSandbox(`serialize(x)`, sandbox1);
|
|
|
|
const obj = { y: "z" };
|
|
|
|
let res = holder.deserialize(global);
|
|
|
|
deepEqual(
|
|
res,
|
|
obj,
|
|
"Deserialized result is deeply equivalent to the expected object"
|
|
);
|
|
deepEqual(
|
|
res,
|
|
sandbox2.x,
|
|
"Deserialized result is deeply equivalent to the X-ray-wrapped object"
|
|
);
|
|
|
|
equal(
|
|
Cu.getObjectPrincipal(res),
|
|
Cu.getObjectPrincipal(global),
|
|
"Deserialized result has the correct principal"
|
|
);
|
|
});
|