RTCDataChannel connectivity issues in Safari 11
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Sep 2017 19:45:31 +0000 (19:45 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Sep 2017 19:45:31 +0000 (19:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173052
<rdar://problem/32712143>

Patch by Youenn Fablet <youenn@apple.com> on 2017-09-14
Reviewed by Alex Christensen.

Source/WebCore:

Covered by updated test.

Before the patch, when sending an ArrayBufferView, RTCDataChannel was sending the whole ArrayBuffer backing the ArrayBufferView.
With this patch, RTCDataChannel will now send only the bytes the ArrayBufferView is exposing.

* Modules/mediastream/RTCDataChannel.cpp:
(WebCore::RTCDataChannel::send): Correctly handling sending of ArrayBufferView.
(WebCore::RTCDataChannel::sendRawData): Helper routine for raw data sending.
* Modules/mediastream/RTCDataChannel.h:

LayoutTests:

* webrtc/datachannel/binary-expected.txt:
* webrtc/datachannel/binary.html:

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

LayoutTests/ChangeLog
LayoutTests/webrtc/datachannel/binary-expected.txt
LayoutTests/webrtc/datachannel/binary.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/RTCDataChannel.cpp
Source/WebCore/Modules/mediastream/RTCDataChannel.h

index 12ba15e..48777e5 100644 (file)
@@ -1,3 +1,14 @@
+2017-09-14  Youenn Fablet  <youenn@apple.com>
+
+        RTCDataChannel connectivity issues in Safari 11
+        https://bugs.webkit.org/show_bug.cgi?id=173052
+        <rdar://problem/32712143>
+
+        Reviewed by Alex Christensen.
+
+        * webrtc/datachannel/binary-expected.txt:
+        * webrtc/datachannel/binary.html:
+
 2017-09-14  Antti Koivisto  <antti@apple.com>
 
         Computing animated style should not require renderers
index 2ed28ed..d690358 100644 (file)
@@ -1,3 +1,11 @@
 
 PASS Basic binary data channel exchange from offerer to receiver 
+PASS test array buffer 1 
+PASS test array buffer 2 
+PASS test array buffer 3 
+PASS test array buffer 4 
+PASS test array buffer view 1 
+PASS test array buffer view 2 
+PASS test array buffer view 3 
+PASS test array buffer view 4 
 
index ab92eca..8274593 100644 (file)
@@ -26,6 +26,11 @@ function createArrayBuffer(length)
     return array;
 }
 
+function createArrayBufferView(length)
+{
+    return createArrayBuffer(2 * length).subarray(length, 2 * length);
+}
+
 function checkArrayBuffer(array, length)
 {
     if (array.byteLength !== length)
@@ -39,16 +44,51 @@ function checkArrayBuffer(array, length)
     return true;
 }
 
+function checkArrayBufferView(array, length)
+{
+    if (array.byteLength !== length)
+        return false;
+
+    var a = new Uint8Array(array);
+    for (var cptr = 0; cptr < length; cptr++) {
+        if (a[cptr] !== cptr + length + 1)
+             return false;
+    }
+    return true;
+}
+
+function testArrayBuffer(array, length)
+{
+    test(() => {
+        assert_true(checkArrayBuffer(array, length));
+    }, "test array buffer " + length);
+}
+
+function testArrayBufferView(array, length)
+{
+    test(() => {
+        assert_true(checkArrayBufferView(array, length));
+    }, "test array buffer view " + length);
+}
+
 function receiveMessages(event) {
     try {
         if (++counter === 1)
-            assert_true(checkArrayBuffer(event.data, 1));
+            testArrayBuffer(event.data, 1);
         else if (counter === 2)
-            assert_true(checkArrayBuffer(event.data, 2));
+            testArrayBuffer(event.data, 2);
         else if (counter === 3)
-            assert_true(checkArrayBuffer(event.data, 3));
-        else if (counter === 4) {
-            assert_true(checkArrayBuffer(event.data, 4));
+            testArrayBuffer(event.data, 3);
+        else if (counter === 4)
+            testArrayBuffer(event.data, 4);
+        else if (counter === 5)
+            testArrayBufferView(event.data, 1);
+        else if (counter === 6)
+            testArrayBufferView(event.data, 2);
+        else if (counter === 7)
+            testArrayBufferView(event.data, 3);
+        else if (counter === 8) {
+            testArrayBufferView(event.data, 4);
             closeDataChannels();
             finishTest();
         } else
@@ -64,6 +104,10 @@ function sendMessages(channel)
     channel.send(createArrayBuffer(2));
     channel.send(createArrayBuffer(3));
     channel.send(createArrayBuffer(4));
+    channel.send(createArrayBufferView(1));
+    channel.send(createArrayBufferView(2));
+    channel.send(createArrayBufferView(3));
+    channel.send(createArrayBufferView(4));
 }
 
 var finishTest;
index c3a1006..afa8851 100644 (file)
@@ -1,3 +1,21 @@
+2017-09-14  Youenn Fablet  <youenn@apple.com>
+
+        RTCDataChannel connectivity issues in Safari 11
+        https://bugs.webkit.org/show_bug.cgi?id=173052
+        <rdar://problem/32712143>
+
+        Reviewed by Alex Christensen.
+
+        Covered by updated test.
+
+        Before the patch, when sending an ArrayBufferView, RTCDataChannel was sending the whole ArrayBuffer backing the ArrayBufferView.
+        With this patch, RTCDataChannel will now send only the bytes the ArrayBufferView is exposing.
+
+        * Modules/mediastream/RTCDataChannel.cpp:
+        (WebCore::RTCDataChannel::send): Correctly handling sending of ArrayBufferView.
+        (WebCore::RTCDataChannel::sendRawData): Helper routine for raw data sending.
+        * Modules/mediastream/RTCDataChannel.h:
+
 2017-09-14  Antti Koivisto  <antti@apple.com>
 
         Computing animated style should not require renderers
index cc0e9b5..88aaf1e 100644 (file)
@@ -105,7 +105,6 @@ ExceptionOr<void> RTCDataChannel::setBinaryType(const AtomicString& binaryType)
 
 ExceptionOr<void> RTCDataChannel::send(const String& data)
 {
-    // FIXME: We should only throw in Connected state.
     if (m_readyState != RTCDataChannelState::Open)
         return Exception { InvalidStateError };
 
@@ -117,19 +116,15 @@ ExceptionOr<void> RTCDataChannel::send(const String& data)
     return { };
 }
 
-ExceptionOr<void> RTCDataChannel::send(ArrayBuffer& data)
+ExceptionOr<void> RTCDataChannel::sendRawData(const char* data, size_t length)
 {
-    // FIXME: We should only throw in Connected state.
     if (m_readyState != RTCDataChannelState::Open)
         return Exception { InvalidStateError };
 
-    size_t dataLength = data.byteLength();
-    if (!dataLength)
+    if (!length)
         return { };
 
-    const char* dataPointer = static_cast<const char*>(data.data());
-
-    if (!m_handler->sendRawData(dataPointer, dataLength)) {
+    if (!m_handler->sendRawData(data, length)) {
         // FIXME: Decide what the right exception here is.
         return Exception { SyntaxError };
     }
@@ -137,10 +132,15 @@ ExceptionOr<void> RTCDataChannel::send(ArrayBuffer& data)
     return { };
 }
 
+
+ExceptionOr<void> RTCDataChannel::send(ArrayBuffer& data)
+{
+    return sendRawData(static_cast<const char*>(data.data()), data.byteLength());
+}
+
 ExceptionOr<void> RTCDataChannel::send(ArrayBufferView& data)
 {
-    // FIXME: We should only throw in Connected state.
-    return send(*data.unsharedBuffer());
+    return sendRawData(static_cast<const char*>(data.baseAddress()), data.byteLength());
 }
 
 ExceptionOr<void> RTCDataChannel::send(Blob&)
index a3bb5c6..620adb4 100644 (file)
@@ -88,6 +88,8 @@ private:
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
 
+    ExceptionOr<void> sendRawData(const char* data, size_t length);
+
     // ActiveDOMObject API
     void stop() final;
     const char* activeDOMObjectName() const final { return "RTCDataChannel"; }