diff options
author | FranklinDM <mrmineshafter17@gmail.com> | 2023-04-07 21:45:15 +0800 |
---|---|---|
committer | FranklinDM <mrmineshafter17@gmail.com> | 2023-04-07 23:41:57 +0800 |
commit | c660c6f699d69dbf5adaaa833b78ce9a57affeff (patch) | |
tree | 41583f4082725a76d6cf1607853cbd08d51fa6f1 /js | |
parent | 84af6181e707073baff354c2ddc763570c39cb92 (diff) | |
download | uxp-c660c6f699d69dbf5adaaa833b78ce9a57affeff.tar.gz |
Issue #2197 - Part 4: Expose structuredClone in Sandbox
Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1734320
Diffstat (limited to 'js')
-rw-r--r-- | js/xpconnect/src/Sandbox.cpp | 44 | ||||
-rw-r--r-- | js/xpconnect/src/xpcprivate.h | 1 | ||||
-rw-r--r-- | js/xpconnect/tests/unit/test_structuredClone.js | 25 | ||||
-rw-r--r-- | js/xpconnect/tests/unit/xpcshell.ini | 1 |
4 files changed, 71 insertions, 0 deletions
diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index a34870269a..3c2145a1f7 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -322,6 +322,45 @@ SandboxCreateFetch(JSContext* cx, HandleObject obj) dom::HeadersBinding::GetConstructorObject(cx); } +static bool SandboxStructuredClone(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + if (!args.requireAtLeast(cx, "structuredClone", 1)) { + return false; + } + + RootedDictionary<dom::StructuredSerializeOptions> options(cx); + if (!options.Init(cx, args.hasDefined(1) ? args[1] : JS::NullHandleValue, + "Argument 2", false)) { + return false; + } + + nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(cx)); + if (!global) { + JS_ReportErrorASCII(cx, "structuredClone: Missing global"); + return false; + } + + JS::Rooted<JS::Value> result(cx); + ErrorResult rv; + nsContentUtils::StructuredClone(cx, global, args[0], options, &result, rv); + if (rv.MaybeSetPendingException(cx)) { + return false; + } + + MOZ_ASSERT_IF(result.isGCThing(), + !JS::GCThingIsMarkedGray(result.toGCCellPtr())); + args.rval().set(result); + return true; +} + +static bool SandboxCreateStructuredClone(JSContext* cx, HandleObject obj) { + MOZ_ASSERT(JS_IsGlobalObject(obj)); + + return JS_DefineFunction(cx, obj, "structuredClone", SandboxStructuredClone, + 1, 0); +} + static bool SandboxIsProxy(JSContext* cx, unsigned argc, Value* vp) { @@ -927,6 +966,8 @@ xpc::GlobalProperties::Parse(JSContext* cx, JS::HandleObject obj) #endif } else if (!strcmp(name.ptr(), "fetch")) { fetch = true; + } else if (!strcmp(name.ptr(), "structuredClone")) { + structuredClone = true; } else if (!strcmp(name.ptr(), "caches")) { caches = true; } else if (!strcmp(name.ptr(), "FileReader")) { @@ -1002,6 +1043,9 @@ xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj) if (fetch && !SandboxCreateFetch(cx, obj)) return false; + if (structuredClone && !SandboxCreateStructuredClone(cx, obj)) + return false; + if (caches && !dom::cache::CacheStorage::DefineCaches(cx, obj)) return false; diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 724c8db3a9..6c2711210a 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2879,6 +2879,7 @@ struct GlobalProperties { bool crypto : 1; bool rtcIdentityProvider : 1; bool fetch : 1; + bool structuredClone : 1; bool caches : 1; bool fileReader: 1; private: diff --git a/js/xpconnect/tests/unit/test_structuredClone.js b/js/xpconnect/tests/unit/test_structuredClone.js new file mode 100644 index 0000000000..6b9b2d776a --- /dev/null +++ b/js/xpconnect/tests/unit/test_structuredClone.js @@ -0,0 +1,25 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["structuredClone"] }); + + sb.equal = equal; + + sb.testing = Components.utils.cloneInto({xyz: 123}, sb); + Cu.evalInSandbox(` + equal(structuredClone("abc"), "abc"); + + var obj = {a: 1}; + obj.self = obj; + var clone = structuredClone(obj); + equal(clone.a, 1); + equal(clone.self, clone); + + var ab = new ArrayBuffer(1); + clone = structuredClone(ab, {transfer: [ab]}); + equal(clone.byteLength, 1); + equal(ab.byteLength, 0); + + clone = structuredClone(testing); + equal(clone.xyz, 123); + `, sb); +} diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini index 12648d3ecc..b13d8d455f 100644 --- a/js/xpconnect/tests/unit/xpcshell.ini +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -114,6 +114,7 @@ skip-if = os == "android" # native test components aren't available on Android [test_css.js] [test_rtcIdentityProvider.js] [test_sandbox_atob.js] +[test_structuredClone.js] [test_isProxy.js] [test_getObjectPrincipal.js] [test_sandbox_name.js] |