// Test cases when a SavedFrame or one of its ancestors have a principal that is // not subsumed by the caller's principal, when async parents are present.
function checkVisibleStack(stackFrame, expectedFrames) { // We check toString separately from properties like asyncCause to check that // it walks the physical SavedFrame chain consistently with the properties. var stringFrames = stackFrame.toString().split("\n");
while (expectedFrames.length) {
let expectedFrame = expectedFrames.shift();
let stringFrame = stringFrames.shift();
// Check the frame properties.
assertEq(stackFrame.functionDisplayName, expectedFrame.name);
assertEq(stackFrame.asyncCause, expectedFrame.asyncCause);
// Check the stringified version.
let expectedStart =
(expectedFrame.asyncCause ? expectedFrame.asyncCause + "*" : "") +
expectedFrame.name;
assertEq(stringFrame.replace(/@.*$/, ""), expectedStart);
// If the next frame has an asyncCause, it should be an asyncParent. if (expectedFrames.length && expectedFrames[0].asyncCause) {
assertEq(stackFrame.parent, null);
stackFrame = stackFrame.asyncParent;
} else {
assertEq(stackFrame.asyncParent, null);
stackFrame = stackFrame.parent;
}
}
}
var low = newGlobal({ principal: 0 }); var high = newGlobal({ principal: 0xfffff });
// Test with synchronous cross-compartment calls. // // With arrows representing child-to-parent links, and fat arrows representing // child-to-async-parent links, create a SavedFrame stack like this: // // low.e -> high.d => high.c => high.b -> low.a // // This stack captured in function `e` would be seen in its complete version if // accessed by `high`'s compartment, while in `low`'s compartment it would look // like this: // // low.e => low.a // // The asyncCause seen on `low.a` above should not leak information about the // real asyncCause on `high.c` and `high.d`. // // The stack captured in function `d` would be seen in its complete version if // accessed by `high`'s compartment, while in `low`'s compartment it would look // like this: // // low.a
// We'll move these functions into the right globals below before invoking them. function a() {
b();
} function b() {
callFunctionWithAsyncStack(c, saveStack(), "BtoC");
} function c() {
callFunctionWithAsyncStack(d, saveStack(), "CtoD");
} function d() {
let stackD = saveStack();
// Test with asynchronous cross-compartment calls and shared frames. // // With arrows representing child-to-parent links, and fat arrows representing // child-to-async-parent links, create a SavedFrame stack like this: // // low.x => high.v => low.u // low.y -> high.v => low.u // low.z => high.w -> low.u // // This stack captured in functions `x`, `y`, and `z` would be seen in its // complete version if accessed by `high`'s compartment, while in `low`'s // compartment it would look like this: // // low.x => low.u // low.y => low.u // low.z => low.u // // The stack captured in function `v` would be seen in its complete version if // accessed by `high`'s compartment, while in `low`'s compartment it would look // like this: // // low.u
// We'll move these functions into the right globals below before invoking them. function u() {
callFunctionWithAsyncStack(v, saveStack(), "UtoV");
w();
} function v() {
let stackV = saveStack();
print("high.checkVisibleStack(stackV)");
checkVisibleStack(stackV, [
{ name: "v", asyncCause: null },
{ name: "u", asyncCause: "UtoV" },
]);
let stack = saveStack(0, low); function xToCall() { return x(stack);};
let stackX = callFunctionWithAsyncStack(xToCall, saveStack(), "VtoX");
// Split the functions in their respective globals.
low .eval(a.toString());
high.eval(b.toString());
high.eval(c.toString());
high.eval(d.toString());
low .eval(e.toString());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.