Source/WebCore: https://bugs.webkit.org/show_bug.cgi?id=73054
authordslomov@google.com <dslomov@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Nov 2011 05:14:24 +0000 (05:14 +0000)
committerdslomov@google.com <dslomov@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Nov 2011 05:14:24 +0000 (05:14 +0000)
[V8][Chromium] Add list of transferred ArrayBuffers to SerializedScriptValue::create.

Reviewed by David Levin.

* bindings/scripts/CodeGeneratorV8.pm:
(GenerateParametersCheck):
* bindings/scripts/test/V8/V8TestObj.cpp:
(WebCore::TestObjInternal::serializedValueCallback):
       * bindings/v8/OptionsObject.cpp:
* bindings/v8/SerializedScriptValue.cpp:
(WebCore::SerializedScriptValue::create):
* bindings/v8/SerializedScriptValue.h:
* bindings/v8/V8Utilities.cpp:
(WebCore::extractTransferables):
(WebCore::getMessagePortArray):
* bindings/v8/V8Utilities.h:
* bindings/v8/custom/V8DOMWindowCustom.cpp:
(WebCore::handlePostMessageCallback):
* bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp:
(WebCore::handlePostMessageCallback):
* bindings/v8/custom/V8HistoryCustom.cpp:
(WebCore::V8History::pushStateCallback):
(WebCore::V8History::replaceStateCallback):
* bindings/v8/custom/V8MessageEventCustom.cpp:
* bindings/v8/custom/V8MessagePortCustom.cpp:
(WebCore::handlePostMessageCallback):
* bindings/v8/custom/V8MessagePortCustom.h: Removed.
* bindings/v8/custom/V8WorkerCustom.cpp:
(WebCore::handlePostMessageCallback):

Source/WebKit/chromium: https://bugs.webkit.org/show_bug.cgi?id=73054
[V8][Chromium] Add list of transferred ArrayBuffers to SerializedScriptValue::create.

Reviewed by David Levin.

* src/WebSerializedScriptValue.cpp:
(WebKit::WebSerializedScriptValue::serialize):

LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=73054
[V8][Chromium] Add list of transferred ArrayBuffers to SerializedScriptValue::create.
Tests rebaselined to reflect new error message.

Reviewed by David Levin.

* platform/chromium/fast/dom/Window/window-postmessage-args-expected.txt:
* platform/chromium/fast/events/constructors/message-event-constructor-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@101118 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/chromium/fast/dom/Window/window-postmessage-args-expected.txt
LayoutTests/platform/chromium/fast/events/constructors/message-event-constructor-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
Source/WebCore/bindings/v8/OptionsObject.cpp
Source/WebCore/bindings/v8/SerializedScriptValue.cpp
Source/WebCore/bindings/v8/SerializedScriptValue.h
Source/WebCore/bindings/v8/V8Utilities.cpp
Source/WebCore/bindings/v8/V8Utilities.h
Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
Source/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
Source/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
Source/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
Source/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
Source/WebCore/bindings/v8/custom/V8MessagePortCustom.h [deleted file]
Source/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebSerializedScriptValue.cpp

index 0960649..096de7c 100644 (file)
@@ -1,3 +1,14 @@
+2011-11-23  Dmitry Lomov  <dslomov@google.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=73054
+        [V8][Chromium] Add list of transferred ArrayBuffers to SerializedScriptValue::create.
+        Tests rebaselined to reflect new error message.
+
+        Reviewed by David Levin.
+
+        * platform/chromium/fast/dom/Window/window-postmessage-args-expected.txt:
+        * platform/chromium/fast/events/constructors/message-event-constructor-expected.txt:
+
 2011-11-23  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: Remove stylesheet links from layout tests
index b0d78fb..0e81f8f 100644 (file)
@@ -1,11 +1,11 @@
 Test that the second argument of window.postMessage is ignored or triggers an error if it is not a message port. You should see PASS message '1' through '7', followed by 'done', with messages 4-7 received below.
 
-PASS: Posting message ('1', 1): threw exception TypeError: MessagePortArray argument must be an object
-PASS: Posting message ('1', 1): threw exception TypeError: MessagePortArray argument must be an object
-PASS: Posting message ('2', ): threw exception TypeError: MessagePortArray argument must be an object
-PASS: Posting message ('2', ): threw exception TypeError: MessagePortArray argument must be an object
-PASS: Posting message ('3', [object Object]): threw exception TypeError: MessagePortArray argument has no length attribute
-PASS: Posting message ('3', [object Object]): threw exception TypeError: MessagePortArray argument has no length attribute
+PASS: Posting message ('1', 1): threw exception TypeError: TransferArray argument must be an object
+PASS: Posting message ('1', 1): threw exception TypeError: TransferArray argument must be an object
+PASS: Posting message ('2', ): threw exception TypeError: TransferArray argument must be an object
+PASS: Posting message ('2', ): threw exception TypeError: TransferArray argument must be an object
+PASS: Posting message ('3', [object Object]): threw exception TypeError: TransferArray argument has no length attribute
+PASS: Posting message ('3', [object Object]): threw exception TypeError: TransferArray argument has no length attribute
 PASS: Posting message ('4', [object DOMWindow]) did not throw an exception
 PASS: Posting message ('4', [object DOMWindow]) did not throw an exception
 PASS: Posting message ('5', null) did not throw an exception
index 3716bef..7fe521e 100644 (file)
@@ -80,19 +80,19 @@ PASS new MessageEvent('eventType', { ports: [channel.port1, channel.port2, chann
 PASS new MessageEvent('eventType', { ports: [] }).ports is []
 PASS new MessageEvent('eventType', { ports: undefined }).ports is []
 PASS new MessageEvent('eventType', { ports: null }).ports is []
-PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: MessagePortArray argument must contain only MessagePorts.
-PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: MessagePortArray argument has no length attribute.
-PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: MessagePortArray argument has no length attribute.
-PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: MessagePortArray argument must be an object.
-PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: MessagePortArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: TransferArray argument must contain only Transferables.
+PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: TransferArray argument has no length attribute.
+PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: TransferArray argument has no length attribute.
+PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: TransferArray argument must be an object.
+PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: TransferArray argument must be an object.
 PASS new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error.
-PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: MessagePortArray argument has no length attribute.
+PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: TransferArray argument has no length attribute.
 PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).bubbles is true
 PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).cancelable is true
 PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel.port2] }).data is test_object
index f311539..a61300c 100644 (file)
@@ -1,3 +1,36 @@
+2011-11-23  Dmitry Lomov  <dslomov@google.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=73054
+        [V8][Chromium] Add list of transferred ArrayBuffers to SerializedScriptValue::create.
+
+        Reviewed by David Levin.
+
+        * bindings/scripts/CodeGeneratorV8.pm:
+        (GenerateParametersCheck):
+        * bindings/scripts/test/V8/V8TestObj.cpp:
+        (WebCore::TestObjInternal::serializedValueCallback):
+       * bindings/v8/OptionsObject.cpp:
+        * bindings/v8/SerializedScriptValue.cpp:
+        (WebCore::SerializedScriptValue::create):
+        * bindings/v8/SerializedScriptValue.h:
+        * bindings/v8/V8Utilities.cpp:
+        (WebCore::extractTransferables):
+        (WebCore::getMessagePortArray):
+        * bindings/v8/V8Utilities.h:
+        * bindings/v8/custom/V8DOMWindowCustom.cpp:
+        (WebCore::handlePostMessageCallback):
+        * bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp:
+        (WebCore::handlePostMessageCallback):
+        * bindings/v8/custom/V8HistoryCustom.cpp:
+        (WebCore::V8History::pushStateCallback):
+        (WebCore::V8History::replaceStateCallback):
+        * bindings/v8/custom/V8MessageEventCustom.cpp:
+        * bindings/v8/custom/V8MessagePortCustom.cpp:
+        (WebCore::handlePostMessageCallback):
+        * bindings/v8/custom/V8MessagePortCustom.h: Removed.
+        * bindings/v8/custom/V8WorkerCustom.cpp:
+        (WebCore::handlePostMessageCallback):
+
 2011-11-23  Rafael Weinstein  <rafaelw@chromium.org>
 
         Cleanup #if usage in V8GCController
index 0b3d898..7abe63b 100644 (file)
@@ -1472,7 +1472,7 @@ sub GenerateParametersCheck
         } elsif ($parameter->type eq "SerializedScriptValue") {
             AddToImplIncludes("SerializedScriptValue.h");
             $parameterCheckString .= "    bool ${parameterName}DidThrow = false;\n";
-            $parameterCheckString .= "    $nativeType $parameterName = SerializedScriptValue::create(args[$paramIndex], 0, ${parameterName}DidThrow);\n";
+            $parameterCheckString .= "    $nativeType $parameterName = SerializedScriptValue::create(args[$paramIndex], 0, 0, ${parameterName}DidThrow);\n";
             $parameterCheckString .= "    if (${parameterName}DidThrow)\n";
             $parameterCheckString .= "        return v8::Undefined();\n";
         } elsif (TypeCanFailConversion($parameter)) {
index 908e75c..f8d68f2 100644 (file)
@@ -799,7 +799,7 @@ static v8::Handle<v8::Value> serializedValueCallback(const v8::Arguments& args)
         return throwError("Not enough arguments", V8Proxy::TypeError);
     TestObj* imp = V8TestObj::toNative(args.Holder());
     bool serializedArgDidThrow = false;
-    RefPtr<SerializedScriptValue> serializedArg = SerializedScriptValue::create(args[0], 0, serializedArgDidThrow);
+    RefPtr<SerializedScriptValue> serializedArg = SerializedScriptValue::create(args[0], 0, 0, serializedArgDidThrow);
     if (serializedArgDidThrow)
         return v8::Undefined();
     imp->serializedValue(serializedArg);
index f80270d..2a97460 100644 (file)
@@ -29,7 +29,7 @@
 #include "DOMStringList.h"
 #include "V8Binding.h"
 #include "V8DOMWindow.h"
-#include "V8MessagePortCustom.h"
+#include "V8Utilities.h"
 #include <wtf/MathExtras.h>
 
 #if ENABLE(INDEXED_DATABASE)
index c1a6817..d3a4b1d 100644 (file)
@@ -1988,7 +1988,9 @@ void SerializedScriptValue::deserializeAndSetProperty(v8::Handle<v8::Object> obj
     deserializeAndSetProperty(object, propertyName, attribute, value.get());
 }
 
-PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, bool& didThrow)
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value,
+                                                                MessagePortArray* messagePorts, ArrayBufferArray*,
+                                                                bool& didThrow)
 {
     return adoptRef(new SerializedScriptValue(value, messagePorts, didThrow));
 }
index c65bb2d..1b56ed2 100644 (file)
 #include <v8.h>
 #include <wtf/Threading.h>
 
+namespace WTF {
+class ArrayBuffer;
+}
+
 namespace WebCore {
 
 class MessagePort;
 
 typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
+typedef Vector<RefPtr<WTF::ArrayBuffer>, 1> ArrayBufferArray;
 
 class SerializedScriptValue : public ThreadSafeRefCounted<SerializedScriptValue> {
 public:
@@ -53,7 +58,9 @@ public:
     // be thrown using v8::ThrowException(), and sets |didThrow|. In this case
     // the caller must not invoke any V8 operations until control returns to
     // V8. When serialization is successful, |didThrow| is false.
-    static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value>, MessagePortArray*, bool& didThrow);
+    static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value>,
+                                                    MessagePortArray*, ArrayBufferArray*,
+                                                    bool& didThrow);
     static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value>);
     static PassRefPtr<SerializedScriptValue> createFromWire(const String& data);
     static PassRefPtr<SerializedScriptValue> create(const String& data);
index 4f783b6..a5cf6d9 100644 (file)
 #include "config.h"
 #include "V8Utilities.h"
 
-#include <v8.h>
-
+#include "ArrayBuffer.h"
 #include "Document.h"
+#include "ExceptionCode.h"
 #include "Frame.h"
+#include "MessagePort.h"
 #include "ScriptExecutionContext.h"
 #include "ScriptState.h"
+#include "V8ArrayBuffer.h"
 #include "V8Binding.h"
 #include "V8BindingState.h"
+#include "V8MessagePort.h"
 #include "V8Proxy.h"
 #include "WorkerContext.h"
 #include "WorkerContextExecutionProxy.h"
@@ -46,6 +49,8 @@
 #include <wtf/Assertions.h>
 #include "Frame.h"
 
+#include <v8.h>
+
 namespace WebCore {
 
 V8LocalContext::V8LocalContext()
@@ -76,6 +81,68 @@ void createHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value>
     cacheArray->Set(v8::Integer::New(cacheArray->Length()), value);
 }
 
+bool extractTransferables(v8::Local<v8::Value> value, MessagePortArray& ports, ArrayBufferArray& arrayBuffers)
+{
+    if (isUndefinedOrNull(value)) {
+        ports.resize(0);
+        arrayBuffers.resize(0);
+        return true;
+    }
+
+    if (!value->IsObject()) {
+        throwError("TransferArray argument must be an object");
+        return false;
+    }
+    uint32_t length = 0;
+    v8::Local<v8::Object> transferrables = v8::Local<v8::Object>::Cast(value);
+
+    if (value->IsArray()) {
+        v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
+        length = array->Length();
+    } else {
+        // Sequence-type object - get the length attribute
+        v8::Local<v8::Value> sequenceLength = transferrables->Get(v8::String::New("length"));
+        if (!sequenceLength->IsNumber()) {
+            throwError("TransferArray argument has no length attribute");
+            return false;
+        }
+        length = sequenceLength->Uint32Value();
+    }
+
+    // Validate the passed array of transferrables.
+    for (unsigned int i = 0; i < length; ++i) {
+        v8::Local<v8::Value> transferrable = transferrables->Get(i);
+        // Validation of non-null objects, per HTML5 spec 10.3.3.
+        if (isUndefinedOrNull(transferrable)) {
+            throwError(DATA_CLONE_ERR);
+            return false;
+        }
+        // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
+        if (V8MessagePort::HasInstance(transferrable))
+            ports.append(V8MessagePort::toNative(v8::Handle<v8::Object>::Cast(transferrable)));
+        else if (V8ArrayBuffer::HasInstance(transferrable))
+            arrayBuffers.append(V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(transferrable)));
+        else {
+            throwError("TransferArray argument must contain only Transferables");
+            return false;
+        }
+    }
+    return true;
+}
+
+bool getMessagePortArray(v8::Local<v8::Value> value, MessagePortArray& ports)
+{
+    ArrayBufferArray arrayBuffers;
+    bool result = extractTransferables(value, ports, arrayBuffers);
+    if (!result)
+        return false;
+    if (arrayBuffers.size() > 0) {
+        throwError("MessagePortArray argument must contain only MessagePorts");
+        return false;
+    }
+    return true;
+}
+
 void removeHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
 {
     v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
index bea7d0f..9956fa5 100644 (file)
 
 #include "OwnHandle.h"
 
+namespace WTF {
+class ArrayBuffer;
+}
+
 namespace WebCore {
 
     class EventListener;
     class Frame;
     class KURL;
+    class MessagePort;
     class ScriptExecutionContext;
     class ScriptState;
 
@@ -74,6 +79,16 @@ namespace WebCore {
         v8::Persistent<v8::Context> m_context;
     };
 
+    typedef WTF::Vector<RefPtr<MessagePort>, 1> MessagePortArray;
+    typedef WTF::Vector<RefPtr<ArrayBuffer>, 1> ArrayBufferArray;
+
+    // Helper function which pulls the values out of a JS sequence and into a MessagePortArray.
+    // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3 
+    // of the HTML5 spec and generates exceptions as appropriate.
+    // Returns true if the array was filled, or false if the passed value was not of an appropriate type.
+    bool extractTransferables(v8::Local<v8::Value>, MessagePortArray&, ArrayBufferArray&); 
+    bool getMessagePortArray(v8::Local<v8::Value>, MessagePortArray&);
+
     // 'FunctionOnly' is assumed for the created callback.
     template <typename V8CallbackType>
     PassRefPtr<V8CallbackType> createFunctionOnlyCallback(v8::Local<v8::Value> value, bool& succeeded, CallbackAllowedValueFlags acceptedValues = 0)
index 19f7c51..8b1f2d8 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "V8DOMWindow.h"
 
+#include "ArrayBuffer.h"
 #include "Chrome.h"
 #include "ContentSecurityPolicy.h"
 #include "DOMTimer.h"
@@ -42,6 +43,7 @@
 #include "HTMLCollection.h"
 #include "HTMLDocument.h"
 #include "MediaPlayer.h"
+#include "MessagePort.h"
 #include "Page.h"
 #include "PlatformScreen.h"
 #include "ScheduledAction.h"
@@ -57,7 +59,6 @@
 #include "V8GCForContextDispose.h"
 #include "V8HiddenPropertyName.h"
 #include "V8HTMLCollection.h"
-#include "V8MessagePortCustom.h"
 #include "V8Node.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
@@ -297,11 +298,12 @@ static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args
     // or
     //   postMessage(message, targetOrigin);
     MessagePortArray portArray;
+    ArrayBufferArray arrayBufferArray;
     String targetOrigin;
     {
         v8::TryCatch tryCatch;
         if (args.Length() > 2) {
-            if (!getMessagePortArray(args[1], portArray))
+            if (!extractTransferables(args[1], portArray, arrayBufferArray))
                 return v8::Undefined();
             targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
         } else
@@ -313,7 +315,11 @@ static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args
 
 
     bool didThrow = false;
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], doTransfer ? &portArray : 0, didThrow);
+    RefPtr<SerializedScriptValue> message =
+        SerializedScriptValue::create(args[0],
+                                      doTransfer ? &portArray : 0,
+                                      doTransfer ? &arrayBufferArray : 0,
+                                      didThrow);
     if (didThrow)
         return v8::Undefined();
 
index 95a69d4..d7a4f57 100644 (file)
 #if ENABLE(WORKERS)
 #include "V8DedicatedWorkerContext.h"
 
+#include "ArrayBuffer.h"
 #include "DedicatedWorkerContext.h"
 #include "WorkerContextExecutionProxy.h"
 #include "V8Binding.h"
-#include "V8MessagePortCustom.h"
 #include "V8Proxy.h"
+#include "V8Utilities.h"
 #include "V8WorkerContextEventListener.h"
 
 namespace WebCore {
@@ -45,17 +46,22 @@ namespace WebCore {
 static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args, bool doTransfer)
 {
     DedicatedWorkerContext* workerContext = V8DedicatedWorkerContext::toNative(args.Holder());
-    MessagePortArray portArray;
+    MessagePortArray ports;
+    ArrayBufferArray arrayBuffers;
     if (args.Length() > 1) {
-        if (!getMessagePortArray(args[1], portArray))
+        if (!extractTransferables(args[1], ports, arrayBuffers))
             return v8::Undefined();
     }
     bool didThrow = false;
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], doTransfer ? &portArray : 0, didThrow);
+    RefPtr<SerializedScriptValue> message =
+        SerializedScriptValue::create(args[0],
+                                      doTransfer ? &ports : 0,
+                                      doTransfer ? &arrayBuffers : 0,
+                                      didThrow);
     if (didThrow)
         return v8::Undefined();
-     ExceptionCode ec = 0;
-    workerContext->postMessage(message.release(), &portArray, ec);
+    ExceptionCode ec = 0;
+    workerContext->postMessage(message.release(), &ports, ec);
     return throwError(ec);
 }
 
index bf9815a..8956109 100644 (file)
@@ -44,7 +44,7 @@ namespace WebCore {
 v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
 {
     bool didThrow = false;
-    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], 0, didThrow);
+    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], 0, 0, didThrow);
     if (didThrow)
         return v8::Undefined();
 
@@ -68,7 +68,7 @@ v8::Handle<v8::Value> V8History::pushStateCallback(const v8::Arguments& args)
 v8::Handle<v8::Value> V8History::replaceStateCallback(const v8::Arguments& args)
 {
     bool didThrow = false;
-    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], 0, didThrow);
+    RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(args[0], 0, 0, didThrow);
     if (didThrow)
         return v8::Undefined();
 
index 5d175e3..64abe40 100644 (file)
@@ -39,7 +39,6 @@
 #include "V8Blob.h"
 #include "V8DOMWindow.h"
 #include "V8MessagePort.h"
-#include "V8MessagePortCustom.h"
 #include "V8Proxy.h"
 
 namespace WebCore {
index dd997b1..ed6f788 100644 (file)
 
 #include "config.h"
 
+#include "ArrayBuffer.h"
 #include "ExceptionCode.h"
 #include "MessagePort.h"
 #include "SerializedScriptValue.h"
 #include "V8Binding.h"
-#include "V8MessagePortCustom.h"
 #include "V8MessagePort.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
@@ -46,12 +46,17 @@ static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args
 {
     MessagePort* messagePort = V8MessagePort::toNative(args.Holder());
     MessagePortArray portArray;
+    ArrayBufferArray arrayBufferArray;
     if (args.Length() > 1) {
-        if (!getMessagePortArray(args[1], portArray))
+        if (!extractTransferables(args[1], portArray, arrayBufferArray))
             return v8::Undefined();
     }
     bool didThrow = false;
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], doTransfer ? &portArray : 0, didThrow);
+    RefPtr<SerializedScriptValue> message =
+        SerializedScriptValue::create(args[0],
+                                      doTransfer ? &portArray : 0,
+                                      doTransfer ? &arrayBufferArray : 0,
+                                      didThrow);
     if (didThrow)
         return v8::Undefined();
     ExceptionCode ec = 0;
@@ -71,49 +76,4 @@ v8::Handle<v8::Value> V8MessagePort::webkitPostMessageCallback(const v8::Argumen
     return handlePostMessageCallback(args, true);
 }
 
-bool getMessagePortArray(v8::Local<v8::Value> value, MessagePortArray& portArray)
-{
-    if (isUndefinedOrNull(value)) {
-        portArray.resize(0);
-        return true;
-    }
-
-    if (!value->IsObject()) {
-        throwError("MessagePortArray argument must be an object");
-        return false;
-    }
-    uint32_t length = 0;
-    v8::Local<v8::Object> ports = v8::Local<v8::Object>::Cast(value);
-
-    if (value->IsArray()) {
-        v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
-        length = array->Length();
-    } else {
-        // Sequence-type object - get the length attribute
-        v8::Local<v8::Value> sequenceLength = ports->Get(v8::String::New("length"));
-        if (!sequenceLength->IsNumber()) {
-            throwError("MessagePortArray argument has no length attribute");
-            return false;
-        }
-        length = sequenceLength->Uint32Value();
-    }
-
-    // Validate the passed array of ports.
-    for (unsigned int i = 0; i < length; ++i) {
-        v8::Local<v8::Value> port = ports->Get(i);
-        // Validation of non-null objects, per HTML5 spec 10.3.3.
-        if (isUndefinedOrNull(port)) {
-            throwError(DATA_CLONE_ERR);
-            return false;
-        }
-        // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
-        if (!V8MessagePort::HasInstance(port)) {
-            throwError("MessagePortArray argument must contain only MessagePorts");
-            return false;
-        }
-        portArray.append(V8MessagePort::toNative(v8::Handle<v8::Object>::Cast(port)));
-    }
-    return true;
-}
-
 } // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/custom/V8MessagePortCustom.h b/Source/WebCore/bindings/v8/custom/V8MessagePortCustom.h
deleted file mode 100644 (file)
index 7ab502b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2008, 2009 Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef V8MessagePortCustom_h
-#define V8MessagePortCustom_h
-
-#include <v8.h>
-
-#include "MessagePort.h"
-
-namespace WebCore {
-
-    // Helper function which pulls the values out of a JS sequence and into a MessagePortArray.
-    // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3 of the HTML5 spec and generates exceptions as appropriate.
-    // Returns true if the array was filled, or false if the passed value was not of an appropriate type.
-    bool getMessagePortArray(v8::Local<v8::Value>, MessagePortArray&);
-
-} // namespace WebCore
-
-#endif // V8MessagePortCustom_h
index 430972b..f5ccdcb 100644 (file)
 
 #include "Worker.h"
 
+#include "ArrayBuffer.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
 #include "SerializedScriptValue.h"
 #include "V8Binding.h"
-#include "V8MessagePortCustom.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
 #include "WorkerContext.h"
@@ -51,17 +51,22 @@ static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args
 {
     INC_STATS("DOM.Worker.postMessage");
     Worker* worker = V8Worker::toNative(args.Holder());
-    MessagePortArray portArray;
+    MessagePortArray ports;
+    ArrayBufferArray arrayBuffers;
     if (args.Length() > 1) {
-        if (!getMessagePortArray(args[1], portArray))
+        if (!extractTransferables(args[1], ports, arrayBuffers))
             return v8::Undefined();
     }
     bool didThrow = false;
-    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], doTransfer ? &portArray : 0, didThrow);
+    RefPtr<SerializedScriptValue> message =
+        SerializedScriptValue::create(args[0],
+                                      doTransfer ? &ports : 0,
+                                      doTransfer ? &arrayBuffers : 0,
+                                      didThrow);
     if (didThrow)
         return v8::Undefined();
     ExceptionCode ec = 0;
-    worker->postMessage(message.release(), &portArray, ec);
+    worker->postMessage(message.release(), &ports, ec);
     return throwError(ec);
 }
 
index db2f79e..20ef2d5 100644 (file)
@@ -1,3 +1,13 @@
+2011-11-23  Dmitry Lomov  <dslomov@google.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=73054
+        [V8][Chromium] Add list of transferred ArrayBuffers to SerializedScriptValue::create.
+
+        Reviewed by David Levin.
+
+        * src/WebSerializedScriptValue.cpp:
+        (WebKit::WebSerializedScriptValue::serialize):
+
 2011-11-23  Ami Fischman  <fischman@chromium.org>
 
         Teach VideoLayerChromium how to render native texture (to support HW video decode).
index 9f3bc63..8f46b48 100644 (file)
@@ -47,7 +47,7 @@ WebSerializedScriptValue WebSerializedScriptValue::fromString(const WebString& s
 WebSerializedScriptValue WebSerializedScriptValue::serialize(v8::Handle<v8::Value> value)
 {
     bool didThrow;
-    WebSerializedScriptValue serializedValue = SerializedScriptValue::create(value, 0, didThrow);
+    WebSerializedScriptValue serializedValue = SerializedScriptValue::create(value, 0, 0, didThrow);
     if (didThrow)
         return createInvalid();
     return serializedValue;