Title: [291808] trunk/Source/WebCore
Revision
291808
Author
gnavamar...@apple.com
Date
2022-03-24 11:50:14 -0700 (Thu, 24 Mar 2022)

Log Message

FormDataConsumer callback happens more than once with an exception
https://bugs.webkit.org/show_bug.cgi?id=238091

In case of an error, it is not expected for the FormDataConsumer callback to happen
more than once with an exception. To avoid this, we introduce FormDataConsumer::didFail
which cancels/clears everything after reporting an error.

Reviewed by Youenn Fablet.

* Modules/fetch/FormDataConsumer.cpp:
(WebCore::FormDataConsumer::read):
(WebCore::FormDataConsumer::consumeFile):
(WebCore::FormDataConsumer::consumeBlob):
(WebCore::FormDataConsumer::didFail):
(WebCore::FormDataConsumer::cancel):
* Modules/fetch/FormDataConsumer.h:
(WebCore::FormDataConsumer::isCancelled):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (291807 => 291808)


--- trunk/Source/WebCore/ChangeLog	2022-03-24 18:16:20 UTC (rev 291807)
+++ trunk/Source/WebCore/ChangeLog	2022-03-24 18:50:14 UTC (rev 291808)
@@ -1,3 +1,23 @@
+2022-03-24  Gabriel Nava Marino  <gnavamar...@apple.com>
+
+        FormDataConsumer callback happens more than once with an exception
+        https://bugs.webkit.org/show_bug.cgi?id=238091
+
+        In case of an error, it is not expected for the FormDataConsumer callback to happen
+        more than once with an exception. To avoid this, we introduce FormDataConsumer::didFail
+        which cancels/clears everything after reporting an error.
+
+        Reviewed by Youenn Fablet.
+
+        * Modules/fetch/FormDataConsumer.cpp:
+        (WebCore::FormDataConsumer::read):
+        (WebCore::FormDataConsumer::consumeFile):
+        (WebCore::FormDataConsumer::consumeBlob):
+        (WebCore::FormDataConsumer::didFail):
+        (WebCore::FormDataConsumer::cancel):
+        * Modules/fetch/FormDataConsumer.h:
+        (WebCore::FormDataConsumer::isCancelled):
+
 2022-03-24  Matteo Flores  <matteo_flo...@apple.com>
 
         Unreviewed, reverting r291789.

Modified: trunk/Source/WebCore/Modules/fetch/FormDataConsumer.cpp (291807 => 291808)


--- trunk/Source/WebCore/Modules/fetch/FormDataConsumer.cpp	2022-03-24 18:16:20 UTC (rev 291807)
+++ trunk/Source/WebCore/Modules/fetch/FormDataConsumer.cpp	2022-03-24 18:50:14 UTC (rev 291808)
@@ -47,8 +47,10 @@
 
 void FormDataConsumer::read()
 {
+    if (isCancelled())
+        return;
+
     ASSERT(m_callback);
-    ASSERT(m_context);
     ASSERT(!m_blobLoader);
 
     if (m_currentElementIndex >= m_formData->elements().size()) {
@@ -78,8 +80,7 @@
                 return;
 
             if (!content) {
-                if (weakThis->m_callback)
-                    weakThis->m_callback(Exception { InvalidStateError, "Unable to read form data file"_s });
+                weakThis->didFail(Exception { InvalidStateError, "Unable to read form data file"_s });
                 return;
             }
 
@@ -99,8 +100,7 @@
             return;
 
         if (auto optionalErrorCode = loader->errorCode()) {
-            if (weakThis->m_callback)
-                weakThis->m_callback(Exception { InvalidStateError, "Failed to read form data blob"_s });
+            weakThis->didFail(Exception { InvalidStateError, "Failed to read form data blob"_s });
             return;
         }
 
@@ -110,10 +110,8 @@
 
     m_blobLoader->start(blobURL, m_context.get(), FileReaderLoader::ReadAsArrayBuffer);
 
-    if (!m_blobLoader || !m_blobLoader->isLoading()) {
-        m_callback(Exception { InvalidStateError, "Unable to read form data blob"_s });
-        m_blobLoader = nullptr;
-    }
+    if (!m_blobLoader || !m_blobLoader->isLoading())
+        didFail(Exception { InvalidStateError, "Unable to read form data blob"_s });
 }
 
 void FormDataConsumer::consume(Span<const uint8_t> content)
@@ -128,13 +126,19 @@
     read();
 }
 
+void FormDataConsumer::didFail(auto&& exception)
+{
+    auto callback = std::exchange(m_callback, nullptr);
+    cancel();
+    if (callback)
+        callback(WTFMove(exception));
+}
+
 void FormDataConsumer::cancel()
 {
     m_callback = nullptr;
-    if (m_blobLoader) {
-        m_blobLoader->cancel();
-        m_blobLoader = nullptr;
-    }
+    if (auto loader = std::exchange(m_blobLoader, { }))
+        loader->cancel();
     m_context = nullptr;
 }
 

Modified: trunk/Source/WebCore/Modules/fetch/FormDataConsumer.h (291807 => 291808)


--- trunk/Source/WebCore/Modules/fetch/FormDataConsumer.h	2022-03-24 18:16:20 UTC (rev 291807)
+++ trunk/Source/WebCore/Modules/fetch/FormDataConsumer.h	2022-03-24 18:50:14 UTC (rev 291808)
@@ -55,6 +55,8 @@
 
     void consume(Span<const uint8_t>);
     void read();
+    void didFail(auto &&exception);
+    bool isCancelled() { return !m_context; }
 
     Ref<FormData> m_formData;
     RefPtr<ScriptExecutionContext> m_context;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to