Bug 1915045 Ensure decode tasks are scheduled on BufferingState::Enter() r=media...
[gecko.git] / js / xpconnect / tests / unit / test_xray_SavedFrame.js
blob85c91a2aa1ea899f5d59c4ddc70baf46fde0c8ba
1 // Bug 1117242: Test calling SavedFrame getters from globals that don't subsume
2 // that frame's principals.
4 const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs");
5 addDebuggerToGlobal(globalThis);
7 const lowP = Services.scriptSecurityManager.createNullPrincipal({});
8 const midP = [lowP, "http://other.com"];
9 const highP = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
11 const low  = new Cu.Sandbox(lowP);
12 const mid  = new Cu.Sandbox(midP);
13 const high = new Cu.Sandbox(highP);
15 function run_test() {
16   // Test that the priveleged view of a SavedFrame from a subsumed compartment
17   // is the same view that the subsumed compartment gets. Create the following
18   // chain of function calls (with some intermediate system-principaled frames
19   // due to implementation):
20   //
21   //     low.lowF -> mid.midF -> high.highF -> high.saveStack
22   //
23   // Where high.saveStack gets monkey patched to create stacks in each of our
24   // sandboxes.
26   Cu.evalInSandbox("function highF() { return saveStack(); }", high);
28   mid.highF = () => high.highF();
29   Cu.evalInSandbox("function midF() { return highF(); }", mid);
31   low.midF = () => mid.midF();
32   Cu.evalInSandbox("function lowF() { return midF(); }", low);
34   const expected = [
35     {
36       sandbox: low,
37       frames: ["lowF"],
38     },
39     {
40       sandbox: mid,
41       frames: ["midF", "lowF"],
42     },
43     {
44       sandbox: high,
45       frames: ["getSavedFrameInstanceFromSandbox",
46                "saveStack",
47                "highF",
48                "run_test/mid.highF",
49                "midF",
50                "run_test/low.midF",
51                "lowF",
52                "run_test",
53                "_execute_test",
54                null],
55     }
56   ];
58   for (let { sandbox, frames } of expected) {
59     high.saveStack = function saveStack() {
60       return getSavedFrameInstanceFromSandbox(sandbox);
61     };
63     const xrayStack = low.lowF();
64     equal(xrayStack.functionDisplayName, "getSavedFrameInstanceFromSandbox",
65           "Xrays should always be able to see everything.");
67     let waived = Cu.waiveXrays(xrayStack);
68     do {
69       ok(frames.length,
70          "There should still be more expected frames while we have actual frames.");
71       equal(waived.functionDisplayName, frames.shift(),
72             "The waived wrapper should give us the stack's compartment's view.");
73       waived = waived.parent;
74     } while (waived);
75   }
78 // Get a SavedFrame instance from inside the given sandbox.
80 // We can't use Cu.getJSTestingFunctions().saveStack() because Cu isn't
81 // available to sandboxes that don't have the system principal. The easiest way
82 // to get the SavedFrame is to use the Debugger API to track allocation sites
83 // and then do an allocation.
84 function getSavedFrameInstanceFromSandbox(sandbox) {
85   const dbg = new Debugger(sandbox);
87   dbg.memory.trackingAllocationSites = true;
88   Cu.evalInSandbox("new Object", sandbox);
89   const allocs = dbg.memory.drainAllocationsLog();
90   dbg.memory.trackingAllocationSites = false;
92   ok(allocs[0], "We should observe the allocation");
93   const { frame } = allocs[0];
95   if (sandbox !== high) {
96     ok(Cu.isXrayWrapper(frame), "`frame` should be an xray...");
97     equal(Object.prototype.toString.call(Cu.waiveXrays(frame)),
98           "[object SavedFrame]",
99           "...and that xray should wrap a SavedFrame");
100   }
102   return frame;