Title: [186310] releases/WebKitGTK/webkit-2.8/Source/WebCore
Revision
186310
Author
[email protected]
Date
2015-07-06 00:42:50 -0700 (Mon, 06 Jul 2015)

Log Message

Merge r184443 - Crash when uploading huge files to YouTube or Google Drive
https://bugs.webkit.org/show_bug.cgi?id=145083
rdar://problem/15468529

Reviewed by Darin Adler.

This fixes the crash, but uploading will fail.

* fileapi/FileReaderLoader.cpp:
(WebCore::FileReaderLoader::start): Tell SubresourceLoader to not store a copy of
all received data, FileReaderLoader has its own buffer.
(WebCore::FileReaderLoader::didReceiveResponse): Fixed a bounds check - not every
64-bit value that doesn't fit into 32 bits is negative. With this, FileReader fails
on huge files right away, as intended.
(WebCore::FileReaderLoader::didReceiveData): Fixed multiple bugs in code that's
executed when size is not available upfront. This is the code that used to crash,
but with the above fix, it's not executed by YouTube.
Not only overflow was handled incorrectly, but even simply growing a buffer for
append was buggy.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog (186309 => 186310)


--- releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog	2015-07-06 07:41:44 UTC (rev 186309)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog	2015-07-06 07:42:50 UTC (rev 186310)
@@ -1,3 +1,25 @@
+2015-05-17  Alexey Proskuryakov  <[email protected]>
+
+        Crash when uploading huge files to YouTube or Google Drive
+        https://bugs.webkit.org/show_bug.cgi?id=145083
+        rdar://problem/15468529
+
+        Reviewed by Darin Adler.
+
+        This fixes the crash, but uploading will fail.
+
+        * fileapi/FileReaderLoader.cpp:
+        (WebCore::FileReaderLoader::start): Tell SubresourceLoader to not store a copy of
+        all received data, FileReaderLoader has its own buffer.
+        (WebCore::FileReaderLoader::didReceiveResponse): Fixed a bounds check - not every
+        64-bit value that doesn't fit into 32 bits is negative. With this, FileReader fails
+        on huge files right away, as intended.
+        (WebCore::FileReaderLoader::didReceiveData): Fixed multiple bugs in code that's
+        executed when size is not available upfront. This is the code that used to crash,
+        but with the above fix, it's not executed by YouTube.
+        Not only overflow was handled incorrectly, but even simply growing a buffer for
+        append was buggy.
+
 2015-05-16  Zalan Bujtas  <[email protected]>
 
         REGRESSION (Subpixel): Dashed underline is missing when box is positioned at subpixels.

Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/fileapi/FileReaderLoader.cpp (186309 => 186310)


--- releases/WebKitGTK/webkit-2.8/Source/WebCore/fileapi/FileReaderLoader.cpp	2015-07-06 07:41:44 UTC (rev 186309)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/fileapi/FileReaderLoader.cpp	2015-07-06 07:42:50 UTC (rev 186310)
@@ -94,6 +94,7 @@
     ThreadableLoaderOptions options;
     options.setSendLoadCallbacks(SendCallbacks);
     options.setSniffContent(DoNotSniffContent);
+    options.setDataBufferingPolicy(DoNotBufferData);
     options.preflightPolicy = ConsiderPreflight;
     options.setAllowCredentials(AllowStoredCredentials);
     options.crossOriginRequestPolicy = DenyCrossOriginRequests;
@@ -136,11 +137,10 @@
         return;
     }
 
-    unsigned long long length = response.expectedContentLength();
+    long long length = response.expectedContentLength();
 
-    // A value larger than INT_MAX means that the content length wasn't
-    // specified, so the buffer will need to be dynamically grown.
-    if (length > INT_MAX) {
+    // A negative value means that the content length wasn't specified, so the buffer will need to be dynamically grown.
+    if (length < 0) {
         m_variableLength = true;
         if (m_hasRange)
             length = 1 + m_rangeEnd - m_rangeStart;
@@ -188,17 +188,26 @@
             return;
         }
         if (m_variableLength) {
-            unsigned long long newLength = m_totalBytes * 2;
-            if (newLength > std::numeric_limits<unsigned>::max())
-                newLength = std::numeric_limits<unsigned>::max();
-            RefPtr<ArrayBuffer> newData =
-                ArrayBuffer::create(static_cast<unsigned>(newLength), 1);
+            unsigned newLength = m_totalBytes + static_cast<unsigned>(dataLength);
+            if (newLength < m_totalBytes) {
+                failed(FileError::NOT_READABLE_ERR);
+                return;
+            }
+            newLength = std::max(newLength, m_totalBytes + m_totalBytes / 4 + 1);
+            RefPtr<ArrayBuffer> newData = ArrayBuffer::create(newLength, 1);
+            if (!newData) {
+                // Not enough memory.
+                failed(FileError::NOT_READABLE_ERR);
+                return;
+            }
             memcpy(static_cast<char*>(newData->data()), static_cast<char*>(m_rawData->data()), m_bytesLoaded);
 
             m_rawData = newData;
             m_totalBytes = static_cast<unsigned>(newLength);
-        } else
+        } else {
+            // This can only happen if we get more data than indicated in expected content length (i.e. never, unless the networking layer is buggy).
             length = remainingBufferSpace;
+        }
     }
 
     if (length <= 0)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to