summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorFranklinDM <mrmineshafter17@gmail.com>2023-04-07 21:45:15 +0800
committerFranklinDM <mrmineshafter17@gmail.com>2023-04-07 23:41:57 +0800
commitc660c6f699d69dbf5adaaa833b78ce9a57affeff (patch)
tree41583f4082725a76d6cf1607853cbd08d51fa6f1 /js
parent84af6181e707073baff354c2ddc763570c39cb92 (diff)
downloaduxp-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.cpp44
-rw-r--r--js/xpconnect/src/xpcprivate.h1
-rw-r--r--js/xpconnect/tests/unit/test_structuredClone.js25
-rw-r--r--js/xpconnect/tests/unit/xpcshell.ini1
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]