Bug 1332592 - FileReader should dispatch onerror+onloadend when OOM occurs, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 20 Jan 2017 13:45:35 +0100
changeset 358369 8ccb35efc96fd51be71e315ea0085a113235f7e6
parent 358368 bb868860dfc35876d2d9c421c037c75a4fb9b3d2
child 358370 d1f678120c11c025067e0cc5eca58d23e60e2bee
push id10621
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 16:02:43 +0000
treeherdermozilla-aurora@dca7b42e6c67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1332592
milestone53.0a1
Bug 1332592 - FileReader should dispatch onerror+onloadend when OOM occurs, r=smaug
dom/file/FileReader.cpp
dom/file/FileReader.h
--- a/dom/file/FileReader.cpp
+++ b/dom/file/FileReader.cpp
@@ -198,19 +198,17 @@ ReadFuncBinaryString(nsIInputStream* in,
     ++source;
   }
   *writeCount = count;
 
   return NS_OK;
 }
 
 nsresult
-FileReader::DoOnLoadEnd(nsresult aStatus,
-                        nsAString& aSuccessEvent,
-                        nsAString& aTerminationEvent)
+FileReader::DoOnLoadEnd(nsresult aStatus)
 {
   // Make sure we drop all the objects that could hold files open now.
   nsCOMPtr<nsIAsyncInputStream> stream;
   mAsyncStream.swap(stream);
 
   RefPtr<Blob> blob;
   mBlob.swap(blob);
 
@@ -218,24 +216,20 @@ FileReader::DoOnLoadEnd(nsresult aStatus
   if (NS_FAILED(aStatus)) {
     FreeFileData();
     return NS_OK;
   }
 
   // In case we read a different number of bytes, we can assume that the
   // underlying storage has changed. We should not continue.
   if (mDataLen != mTotal) {
-    DispatchError(NS_ERROR_FAILURE, aTerminationEvent);
     FreeFileData();
     return NS_ERROR_FAILURE;
   }
 
-  aSuccessEvent = NS_LITERAL_STRING(LOAD_STR);
-  aTerminationEvent = NS_LITERAL_STRING(LOADEND_STR);
-
   nsresult rv = NS_OK;
   switch (mDataFormat) {
     case FILE_AS_ARRAYBUFFER: {
       AutoJSAPI jsapi;
       if (!jsapi.Init(GetParentObject())) {
         FreeFileData();
         return NS_ERROR_FAILURE;
       }
@@ -536,34 +530,34 @@ FileReader::ClearProgressEventTimer()
   mProgressEventWasDelayed = false;
   mTimerIsActive = false;
   if (mProgressNotifier) {
     mProgressNotifier->Cancel();
   }
 }
 
 void
-FileReader::DispatchError(nsresult rv, nsAString& finalEvent)
+FileReader::DispatchError(nsresult aRv)
 {
   // Set the status attribute, and dispatch the error event
-  switch (rv) {
+  switch (aRv) {
   case NS_ERROR_FILE_NOT_FOUND:
     mError = new DOMError(GetOwner(), NS_LITERAL_STRING("NotFoundError"));
     break;
   case NS_ERROR_FILE_ACCESS_DENIED:
     mError = new DOMError(GetOwner(), NS_LITERAL_STRING("SecurityError"));
     break;
   default:
     mError = new DOMError(GetOwner(), NS_LITERAL_STRING("NotReadableError"));
     break;
   }
 
   // Dispatch error event to signify load failure
   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
-  DispatchProgressEvent(finalEvent);
+  DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
 }
 
 nsresult
 FileReader::DispatchProgressEvent(const nsAString& aType)
 {
   ProgressEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
@@ -650,29 +644,31 @@ nsresult
 FileReader::OnLoadEnd(nsresult aStatus)
 {
   // Cancel the progress event timer
   ClearProgressEventTimer();
 
   // FileReader must be in DONE stage after an operation
   mReadyState = DONE;
 
-  nsAutoString successEvent, termEvent;
-  nsresult rv = DoOnLoadEnd(aStatus, successEvent, termEvent);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv = DoOnLoadEnd(aStatus);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    DispatchError(rv);
+    return NS_OK;
+  }
 
   // Set the status field as appropriate
   if (NS_FAILED(aStatus)) {
-    DispatchError(aStatus, termEvent);
+    DispatchError(aStatus);
     return NS_OK;
   }
 
   // Dispatch event to signify end of a successful operation
-  DispatchProgressEvent(successEvent);
-  DispatchProgressEvent(termEvent);
+  DispatchProgressEvent(NS_LITERAL_STRING(LOAD_STR));
+  DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
 
   return NS_OK;
 }
 
 void
 FileReader::Abort()
 {
   if (mReadyState == EMPTY || mReadyState == DONE) {
--- a/dom/file/FileReader.h
+++ b/dom/file/FileReader.h
@@ -136,24 +136,23 @@ private:
                      nsAString &aResult);
   nsresult GetAsDataURL(Blob *aBlob, const char *aFileData,
                         uint32_t aDataLen, nsAString &aResult);
 
   nsresult OnLoadEnd(nsresult aStatus);
 
   void StartProgressEventTimer();
   void ClearProgressEventTimer();
-  void DispatchError(nsresult rv, nsAString& finalEvent);
+  void DispatchError(nsresult aRv);
   nsresult DispatchProgressEvent(const nsAString& aType);
 
   nsresult DoAsyncWait();
   nsresult DoReadData(uint64_t aCount);
 
-  nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
-                       nsAString& aTerminationEvent);
+  nsresult DoOnLoadEnd(nsresult aStatus);
 
   void FreeFileData()
   {
     free(mFileData);
     mFileData = nullptr;
     mDataLen = 0;
   }