Bug 1362194 - Part 3: Make Base64Decode even more tolerant of allocation failures. r=mccr8, a=gchang
☠☠ backed out by e6d59d3fce9c ☠ ☠
authorNathan Froyd <froydnj@mozilla.com>
Fri, 05 May 2017 11:33:36 -0400
changeset 396228 07849fe5dfd8fb01c1d8c9335b3dd6623b065061
parent 396227 cb4ac444390794347fa89c101c8743196bf33824
child 396229 b104650aeda3ed80e1f31ff91117bbf10b9e5aa3
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8, gchang
bugs1362194
milestone54.0
Bug 1362194 - Part 3: Make Base64Decode even more tolerant of allocation failures. r=mccr8, a=gchang The lossy conversion to ASCII here can also fail; we should handle that as well. Rewriting the code to use MakeScopeExit also avoids tangled logic and/or duplicating calls to ensure the destination string is truncated on failure.
xpcom/io/Base64.cpp
--- a/xpcom/io/Base64.cpp
+++ b/xpcom/io/Base64.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Base64.h"
 
+#include "mozilla/ScopeExit.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "nsIInputStream.h"
 #include "nsString.h"
 #include "nsTArray.h"
 
 #include "plbase64.h"
 
 namespace {
@@ -459,29 +460,36 @@ Base64Decode(const nsACString& aBase64, 
 
   aBinary.SetLength(binaryLen);
   return NS_OK;
 }
 
 nsresult
 Base64Decode(const nsAString& aBase64, nsAString& aBinary)
 {
-  NS_LossyConvertUTF16toASCII base64(aBase64);
+  auto truncater = mozilla::MakeScopeExit([&]() { aBinary.Truncate(); });
+
+  // XXX We should really consider decoding directly from the string, rather
+  // than making a separate copy here.
+  nsAutoCString base64;
+  if (!base64.SetCapacity(aBase64.Length(), mozilla::fallible)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  LossyCopyUTF16toASCII(aBase64, base64);
+
   nsAutoCString binary;
 
   nsresult rv = Base64Decode(base64, binary);
-  if (NS_SUCCEEDED(rv)) {
-    if (!CopyASCIItoUTF16(binary, aBinary, mozilla::fallible)) {
-      rv = NS_ERROR_OUT_OF_MEMORY;
-    }
+  NS_ENSURE_STATE(rv, rv);
+
+  if (!CopyASCIItoUTF16(binary, aBinary, mozilla::fallible)) {
+    return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  if (NS_FAILED(rv)) {
-    aBinary.Truncate();
-  }
+  truncater.release();
 
   return rv;
 }
 
 nsresult
 Base64URLDecode(const nsACString& aBase64,
                 Base64URLDecodePaddingPolicy aPaddingPolicy,
                 FallibleTArray<uint8_t>& aBinary)