diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /js/xpconnect/tests/unit/test_xray_SavedFrame-02.js | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/xpconnect/tests/unit/test_xray_SavedFrame-02.js')
-rw-r--r-- | js/xpconnect/tests/unit/test_xray_SavedFrame-02.js | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/js/xpconnect/tests/unit/test_xray_SavedFrame-02.js b/js/xpconnect/tests/unit/test_xray_SavedFrame-02.js new file mode 100644 index 0000000000..e9b5752044 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xray_SavedFrame-02.js @@ -0,0 +1,71 @@ +// Test calling SavedFrame getters across wrappers from privileged and +// un-privileged globals. + +const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs"); +addDebuggerToGlobal(globalThis); + +const lowP = Services.scriptSecurityManager.createNullPrincipal({}); +const highP = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal); + +const low = new Cu.Sandbox(lowP); +const high = new Cu.Sandbox(highP); + +function run_test() { + // Privileged compartment accessing unprivileged stack. + high.stack = getSavedFrameInstanceFromSandbox(low); + Cu.evalInSandbox("this.parent = stack.parent", high); + Cu.evalInSandbox("this.asyncParent = stack.asyncParent", high); + Cu.evalInSandbox("this.source = stack.source", high); + Cu.evalInSandbox("this.functionDisplayName = stack.functionDisplayName", high); + + // Un-privileged compartment accessing privileged stack. + low.stack = getSavedFrameInstanceFromSandbox(high); + try { + Cu.evalInSandbox("this.parent = stack.parent", low); + } catch (e) { } + try { + Cu.evalInSandbox("this.asyncParent = stack.asyncParent", low); + } catch (e) { } + try { + Cu.evalInSandbox("this.source = stack.source", low); + } catch (e) { } + try { + Cu.evalInSandbox("this.functionDisplayName = stack.functionDisplayName", low); + } catch (e) { } + + // Privileged compartment accessing privileged stack. + let stack = getSavedFrameInstanceFromSandbox(high); + let parent = stack.parent; + let asyncParent = stack.asyncParent; + let source = stack.source; + let functionDisplayName = stack.functionDisplayName; + + ok(true, "Didn't crash"); +} + +// Get a SavedFrame instance from inside the given sandbox. +// +// We can't use Cu.getJSTestingFunctions().saveStack() because Cu isn't +// available to sandboxes that don't have the system principal. The easiest way +// to get the SavedFrame is to use the Debugger API to track allocation sites +// and then do an allocation. +function getSavedFrameInstanceFromSandbox(sandbox) { + const dbg = new Debugger(sandbox); + + dbg.memory.trackingAllocationSites = true; + Cu.evalInSandbox("(function iife() { return new RegExp }())", sandbox); + const allocs = dbg.memory.drainAllocationsLog().filter(e => e.class === "RegExp"); + dbg.memory.trackingAllocationSites = false; + + ok(allocs[0], "We should observe the allocation"); + const { frame } = allocs[0]; + + if (sandbox !== high) { + ok(Cu.isXrayWrapper(frame), "`frame` should be an xray..."); + equal(Object.prototype.toString.call(Cu.waiveXrays(frame)), + "[object SavedFrame]", + "...and that xray should wrap a SavedFrame"); + } + + return frame; +} |