[JSC] SerializedScriptValue::create() should throw a DataCloneError if input is an unsupported object
https://bugs.webkit.org/show_bug.cgi?id=94493
Patch by Christophe Dumez <christophe.dumez@intel.com> on 2012-08-20
Reviewed by Oliver Hunt.
Source/WebCore:
Update JSC implementation for SerializedScriptValue::create() so that
a DataCloneError is thrown when the input value is an unsupported
object. The previous implementation was not throwing any error.
This change is according to the structured clone specification at:
http://www.w3.org/TR/html5/common-dom-interfaces.html#structured-clone
This also matches the corresponding V8 implementation.
Test: fast/events/message-port-multi.html.
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneSerializer::serialize):
(WebCore::SerializedScriptValue::maybeThrowExceptionIfSerializationFailed):
* bindings/js/SerializedScriptValue.h:
LayoutTests:
Add checks for Function, Error and host objects arguments to
MessagePort.postMessage() in fast/events/message-port-multi.html.
According to the structured clone specification, we should throw
a DataCloneError for such input types.
* fast/dom/Window/anonymous-slot-with-changes-expected.txt:
* fast/dom/Window/anonymous-slot-with-changes.html: Update test to expect
an exception when passing a function to postMessage().
* fast/events/message-port-multi-expected.txt: Update expected result
accordingly.
* fast/events/resources/message-port-multi.js:
(testTransfers.try.f1):
* platform/chromium/fast/events/message-port-multi-expected.txt: Removed.
Now identical to global expectation.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126067 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/Source/WebCore/bindings/js/SerializedScriptValue.cpp
index 2b47d4b..9d5ca65 100644
--- a/Source/WebCore/bindings/js/SerializedScriptValue.cpp
+++ b/Source/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -582,13 +582,6 @@
if (isArray(value))
return false;
-
- // Object cannot be serialized because the act of walking the object creates new objects
- if (value.isObject() && asObject(value)->inherits(&JSNavigator::s_info)) {
- fail();
- write(NullTag);
- return true;
- }
if (value.isObject()) {
JSObject* obj = asObject(value);
@@ -677,9 +670,7 @@
return success;
}
- CallData unusedData;
- if (getCallData(value, unusedData) == CallTypeNone)
- return false;
+ return false;
}
// Any other types are expected to serialize as null.
write(NullTag);
@@ -898,6 +889,12 @@
JSObject* inObject = asObject(inValue);
if (!startObject(inObject))
break;
+ // At this point, all supported objects other than Object
+ // objects have been handled. If we reach this point and
+ // the input is not an Object object then we should throw
+ // a DataCloneError.
+ if (inObject->classInfo() != &JSFinalObject::s_info)
+ return DataCloneError;
inputObjectStack.append(inObject);
indexStack.append(0);
propertyStack.append(PropertyNameArray(m_exec));
@@ -1920,6 +1917,9 @@
case ValidationError:
throwError(exec, createTypeError(exec, "Unable to deserialize data."));
break;
+ case DataCloneError:
+ setDOMException(exec, DATA_CLONE_ERR);
+ break;
case ExistingExceptionError:
break;
case UnspecifiedError: