test_xray_SavedFrame-02.js (2649B)
1 // Test calling SavedFrame getters across wrappers from privileged and 2 // un-privileged globals. 3 4 const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs"); 5 addDebuggerToGlobal(globalThis); 6 7 const lowP = Services.scriptSecurityManager.createNullPrincipal({}); 8 const highP = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal); 9 10 const low = new Cu.Sandbox(lowP); 11 const high = new Cu.Sandbox(highP); 12 13 function run_test() { 14 // Privileged compartment accessing unprivileged stack. 15 high.stack = getSavedFrameInstanceFromSandbox(low); 16 Cu.evalInSandbox("this.parent = stack.parent", high); 17 Cu.evalInSandbox("this.asyncParent = stack.asyncParent", high); 18 Cu.evalInSandbox("this.source = stack.source", high); 19 Cu.evalInSandbox("this.functionDisplayName = stack.functionDisplayName", high); 20 21 // Un-privileged compartment accessing privileged stack. 22 low.stack = getSavedFrameInstanceFromSandbox(high); 23 try { 24 Cu.evalInSandbox("this.parent = stack.parent", low); 25 } catch (e) { } 26 try { 27 Cu.evalInSandbox("this.asyncParent = stack.asyncParent", low); 28 } catch (e) { } 29 try { 30 Cu.evalInSandbox("this.source = stack.source", low); 31 } catch (e) { } 32 try { 33 Cu.evalInSandbox("this.functionDisplayName = stack.functionDisplayName", low); 34 } catch (e) { } 35 36 // Privileged compartment accessing privileged stack. 37 let stack = getSavedFrameInstanceFromSandbox(high); 38 let parent = stack.parent; 39 let asyncParent = stack.asyncParent; 40 let source = stack.source; 41 let functionDisplayName = stack.functionDisplayName; 42 43 ok(true, "Didn't crash"); 44 } 45 46 // Get a SavedFrame instance from inside the given sandbox. 47 // 48 // We can't use Cu.getJSTestingFunctions().saveStack() because Cu isn't 49 // available to sandboxes that don't have the system principal. The easiest way 50 // to get the SavedFrame is to use the Debugger API to track allocation sites 51 // and then do an allocation. 52 function getSavedFrameInstanceFromSandbox(sandbox) { 53 const dbg = new Debugger(sandbox); 54 55 dbg.memory.trackingAllocationSites = true; 56 Cu.evalInSandbox("(function iife() { return new RegExp }())", sandbox); 57 const allocs = dbg.memory.drainAllocationsLog().filter(e => e.class === "RegExp"); 58 dbg.memory.trackingAllocationSites = false; 59 60 ok(allocs[0], "We should observe the allocation"); 61 const { frame } = allocs[0]; 62 63 if (sandbox !== high) { 64 ok(Cu.isXrayWrapper(frame), "`frame` should be an xray..."); 65 equal(Object.prototype.toString.call(Cu.waiveXrays(frame)), 66 "[object SavedFrame]", 67 "...and that xray should wrap a SavedFrame"); 68 } 69 70 return frame; 71 }