From 4e12ba331b3436159f0488b6a2e1eb66b11503c7 Mon Sep 17 00:00:00 2001 From: Pip Date: Tue, 19 Apr 2016 10:26:00 +0200 Subject: [PATCH] Bug 1264613 - Allow object-to-nonobject serialization. r=baku Fix the Structured Clone API to avoid assigning a numeric back-reference id to objects that are serialized as non-objects; in particular, this fixes incorrect serialization and crashes upon deserialization when a DedicatedWorkerGlobalScope is serialized twice in the same serialization packet. --- dom/base/Console.cpp | 4 ++++ js/public/StructuredClone.h | 3 +++ js/src/vm/StructuredClone.cpp | 11 ++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dom/base/Console.cpp b/dom/base/Console.cpp index 0c8278fc70e4..389aa15932bc 100644 --- a/dom/base/Console.cpp +++ b/dom/base/Console.cpp @@ -546,6 +546,10 @@ protected: return true; } + if (!JS_ObjectNotWritten(aWriter, aObj)) { + return false; + } + JS::Rooted value(aCx, JS::ObjectOrNullValue(aObj)); JS::Rooted jsString(aCx, JS::ToString(aCx, value)); if (NS_WARN_IF(!jsString)) { diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index e3077c72a595..821b0ee205ff 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -281,4 +281,7 @@ JS_WriteString(JSStructuredCloneWriter* w, JS::HandleString str); JS_PUBLIC_API(bool) JS_WriteTypedArray(JSStructuredCloneWriter* w, JS::HandleValue v); +JS_PUBLIC_API(bool) +JS_ObjectNotWritten(JSStructuredCloneWriter* w, JS::HandleObject obj); + #endif /* js_StructuredClone_h */ diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index cba80ce8c2cb..246e11c35dee 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -356,6 +356,7 @@ struct JSStructuredCloneWriter { friend bool JS_WriteString(JSStructuredCloneWriter* w, HandleString str); friend bool JS_WriteTypedArray(JSStructuredCloneWriter* w, HandleValue v); + friend bool JS_ObjectNotWritten(JSStructuredCloneWriter* w, HandleObject obj); }; JS_FRIEND_API(uint64_t) @@ -1763,7 +1764,7 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp) } case SCTAG_BACK_REFERENCE_OBJECT: { - if (data >= allObjs.length()) { + if (data >= allObjs.length() || !allObjs[data].isObject()) { JS_ReportErrorNumber(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, "invalid back reference in input"); @@ -2422,3 +2423,11 @@ JS_WriteTypedArray(JSStructuredCloneWriter* w, HandleValue v) RootedObject obj(w->context(), &v.toObject()); return w->writeTypedArray(obj); } + +JS_PUBLIC_API(bool) +JS_ObjectNotWritten(JSStructuredCloneWriter* w, HandleObject obj) +{ + w->memory.remove(w->memory.lookup(obj)); + + return true; +}