summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2023-11-05 12:38:54 +0000
committerMoonchild <moonchild@palemoon.org>2023-11-05 12:38:54 +0000
commitd0d212143a0bd52135ec7a473d5f0a8bf58f8fb5 (patch)
treefcd7bb8f4d2f7235d1f520dca8fc246b1c784ba2
parent7a9e29d580f063e1c76f7ed7c5674d8a742de270 (diff)
parentfc1697622c4086da9606f2f2b1b4886ef8f5c464 (diff)
downloaduxp-d0d212143a0bd52135ec7a473d5f0a8bf58f8fb5.tar.gz
Merge pull request 'No Issue - Structured Clone Spec Compliance and Bugfix' (#2365) from Basilisk-Dev/UXP-contrib:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2365
-rw-r--r--dom/base/test/mochitest.ini1
-rw-r--r--dom/tests/mochitest/bugs/test_bug743615.html3
-rw-r--r--js/src/vm/StructuredClone.cpp45
3 files changed, 43 insertions, 6 deletions
diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini
index 27a970c21a..6f5e0ea835 100644
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -764,6 +764,7 @@ skip-if = debug == false
[test_setting_opener.html]
[test_simplecontentpolicy.html]
skip-if = e10s # Bug 1156489.
+[test_structuredclone_backref.html]
[test_text_wholeText.html]
[test_textnode_normalize_in_selection.html]
[test_textnode_split_in_selection.html]
diff --git a/dom/tests/mochitest/bugs/test_bug743615.html b/dom/tests/mochitest/bugs/test_bug743615.html
index 39e978ddad..044e6509dc 100644
--- a/dom/tests/mochitest/bugs/test_bug743615.html
+++ b/dom/tests/mochitest/bugs/test_bug743615.html
@@ -54,8 +54,7 @@ function windowMessage(evt) {
ok(checkPattern(imageData, pattern),
'postMessage from self worked correctly');
- // We're not spec compliant on this yet.
- todo_is(imageData.data, evt.data.dataRef,
+ is(imageData.data, evt.data.dataRef,
'Should have backrefs for imagedata buffer');
// Make a new pattern, and send it to a worker.
diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp
index e99cfe8f71..daaaf52b92 100644
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1240,7 +1240,16 @@ JSStructuredCloneWriter::traverseObject(HandleObject obj)
ESClass cls;
if (!GetBuiltinClass(context(), obj, &cls))
return false;
- return out.writePair(cls == ESClass::Array ? SCTAG_ARRAY_OBJECT : SCTAG_OBJECT_OBJECT, 0);
+
+ if (cls == ESClass::Array) {
+ uint32_t length = 0;
+ if (!JS_GetArrayLength(context(), obj, &length))
+ return false;
+
+ return out.writePair(SCTAG_ARRAY_OBJECT, NativeEndian::swapToLittleEndian(length));
+ }
+
+ return out.writePair(SCTAG_OBJECT_OBJECT, 0);
}
bool
@@ -2037,6 +2046,7 @@ bool
JSStructuredCloneReader::startRead(MutableHandleValue vp)
{
uint32_t tag, data;
+ bool alreadAppended = false;
if (!in.readPair(&tag, &data))
return false;
@@ -2143,7 +2153,7 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp)
case SCTAG_ARRAY_OBJECT:
case SCTAG_OBJECT_OBJECT: {
JSObject* obj = (tag == SCTAG_ARRAY_OBJECT)
- ? (JSObject*) NewDenseEmptyArray(context())
+ ? (JSObject*) NewDenseUnallocatedArray(context(), NativeEndian::swapFromLittleEndian(data))
: (JSObject*) NewBuiltinClassInstance<PlainObject>(context());
if (!obj || !objs.append(ObjectValue(*obj)))
return false;
@@ -2237,15 +2247,29 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp)
"unsupported type");
return false;
}
+
+ // callbacks->read() might read other objects from the buffer.
+ // In startWrite we always write the object itself before calling
+ // the custom function. We should do the same here to keep
+ // indexing consistent.
+ uint32_t placeholderIndex = allObjs.length();
+ Value dummy = UndefinedValue();
+ if (!allObjs.append(dummy)) {
+ return false;
+ }
+
JSObject* obj = callbacks->read(context(), this, tag, data, closure);
if (!obj)
return false;
vp.setObject(*obj);
+ allObjs[placeholderIndex].set(vp);
+ alreadAppended = true;
}
}
- if (vp.isObject() && !allObjs.append(vp))
+ if (!alreadAppended && vp.isObject() && !allObjs.append(vp)) {
return false;
+ }
return true;
}
@@ -2819,7 +2843,20 @@ JS_WriteTypedArray(JSStructuredCloneWriter* w, HandleValue v)
MOZ_ASSERT(v.isObject());
assertSameCompartment(w->context(), v);
RootedObject obj(w->context(), &v.toObject());
- return w->writeTypedArray(obj);
+
+ // startWrite can write everything, thus we should check here
+ // and report error if the user passes a wrong type.
+ if (!JS_IsTypedArrayObject(obj)) {
+ JS_ReportErrorNumberASCII(w->context(), GetErrorMessage, nullptr,
+ JSMSG_SC_BAD_SERIALIZED_DATA,
+ "expected type array");
+ return false;
+ }
+
+ // We should use startWrite instead of writeTypedArray, because
+ // typed array is an object, we should add it to the |memory|
+ // (allObjs) list. Directly calling writeTypedArray won't add it.
+ return w->startWrite(v);
}
JS_PUBLIC_API(bool)