Bug 1333899 - Part 1: Add a fallible NS_UnescapeURL. r=froydnj
☠☠ backed out by b593e365b72d ☠ ☠
authorEric Rahm <erahm@mozilla.com>
Tue, 21 Feb 2017 17:56:34 -0800
changeset 344136 5739a7f790f2e171af618eec42ecfeaf9d681433
parent 344135 988dd3817ad4b72dacd30b36eebbcfdd9a47719c
child 344137 f82fd05e7699aed68ad105fa9ecdd3fa7b7f689d
push id87278
push usererahm@mozilla.com
push dateWed, 22 Feb 2017 01:56:49 +0000
treeherdermozilla-inbound@fbb7cc8d04b9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1333899
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1333899 - Part 1: Add a fallible NS_UnescapeURL. r=froydnj This adds a fallible version of |NS_UnescapeURL| that can be used to gracefully handle allocation failures when the string needs to be unescaped. MozReview-Commit-ID: 1eXPzeB2yrI
xpcom/io/nsEscape.cpp
xpcom/io/nsEscape.h
--- a/xpcom/io/nsEscape.cpp
+++ b/xpcom/io/nsEscape.cpp
@@ -570,36 +570,53 @@ NS_EscapeURL(const nsAFlatString& aStr, 
 }
 
 #define ISHEX(c) memchr(hexCharsUpperLower, c, sizeof(hexCharsUpperLower)-1)
 
 bool
 NS_UnescapeURL(const char* aStr, int32_t aLen, uint32_t aFlags,
                nsACString& aResult)
 {
+  bool didAppend = false;
+  nsresult rv = NS_UnescapeURL(aStr, aLen, aFlags, aResult, didAppend,
+                               mozilla::fallible);
+  if (rv == NS_ERROR_OUT_OF_MEMORY) {
+    ::NS_ABORT_OOM(aLen * sizeof(nsACString::char_type));
+  }
+
+  return didAppend;
+}
+
+nsresult
+NS_UnescapeURL(const char* aStr, int32_t aLen, uint32_t aFlags,
+               nsACString& aResult, bool& aDidAppend,
+               const mozilla::fallible_t&)
+{
   if (!aStr) {
     NS_NOTREACHED("null pointer");
-    return false;
+    return NS_ERROR_INVALID_ARG;
   }
 
   MOZ_ASSERT(aResult.IsEmpty(),
              "Passing a non-empty string as an out parameter!");
 
   if (aLen < 0) {
     aLen = strlen(aStr);
   }
 
   bool ignoreNonAscii = !!(aFlags & esc_OnlyASCII);
   bool ignoreAscii = !!(aFlags & esc_OnlyNonASCII);
   bool writing = !!(aFlags & esc_AlwaysCopy);
   bool skipControl = !!(aFlags & esc_SkipControl);
   bool skipInvalidHostChar = !!(aFlags & esc_Host);
 
   if (writing) {
-    aResult.SetCapacity(aLen);
+    if (!aResult.SetCapacity(aLen, mozilla::fallible)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
   }
 
   const char* last = aStr;
   const char* p = aStr;
 
   for (int i = 0; i < aLen; ++i, ++p) {
     if (*p == HEX_ESCAPE && i < aLen - 2) {
       unsigned char c1 = *((unsigned char*)p + 1);
@@ -607,27 +624,36 @@ NS_UnescapeURL(const char* aStr, int32_t
       unsigned char u = (UNHEX(c1) << 4) + UNHEX(c2);
       if (ISHEX(c1) && ISHEX(c2) &&
           (!skipInvalidHostChar || dontNeedEscape(u, aFlags) || c1 >= '8') &&
           ((c1 < '8' && !ignoreAscii) || (c1 >= '8' && !ignoreNonAscii)) &&
           !(skipControl &&
             (c1 < '2' || (c1 == '7' && (c2 == 'f' || c2 == 'F'))))) {
         if (!writing) {
           writing = true;
-          aResult.SetCapacity(aLen);
+          if (!aResult.SetCapacity(aLen, mozilla::fallible)) {
+            return NS_ERROR_OUT_OF_MEMORY;
+          }
         }
         if (p > last) {
-          aResult.Append(last, p - last);
+          if (!aResult.Append(last, p - last, mozilla::fallible)) {
+            return NS_ERROR_OUT_OF_MEMORY;
+          }
           last = p;
         }
-        aResult.Append(u);
+        if (!aResult.Append(u, mozilla::fallible)) {
+          return NS_ERROR_OUT_OF_MEMORY;
+        }
         i += 2;
         p += 2;
         last += 3;
       }
     }
   }
   if (writing && last < aStr + aLen) {
-    aResult.Append(last, aStr + aLen - last);
+    if (!aResult.Append(last, aStr + aLen - last, mozilla::fallible)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
   }
 
-  return writing;
+  aDidAppend = writing;
+  return NS_OK;
 }
--- a/xpcom/io/nsEscape.h
+++ b/xpcom/io/nsEscape.h
@@ -137,16 +137,26 @@ bool NS_EscapeURL(const char* aStr,
  * @return true if aResult was written to (i.e. at least one character was
  *              unescaped or esc_AlwaysCopy was requested), false otherwise.
  */
 bool NS_UnescapeURL(const char* aStr,
                     int32_t aLen,
                     uint32_t aFlags,
                     nsACString& aResult);
 
+/**
+ * Fallible version of |NS_UnescapeURL|.
+ */
+nsresult NS_UnescapeURL(const char* aStr,
+                        int32_t aLen,
+                        uint32_t aFlags,
+                        nsACString& aResult,
+                        bool& aAppended,
+                        const mozilla::fallible_t&);
+
 /** returns resultant string length **/
 inline int32_t
 NS_UnescapeURL(char* aStr)
 {
   return nsUnescapeCount(aStr);
 }
 
 /**
@@ -172,16 +182,17 @@ NS_EscapeURL(const nsCSubstring& aStr, u
 inline const nsCSubstring&
 NS_UnescapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult)
 {
   if (NS_UnescapeURL(aStr.Data(), aStr.Length(), aFlags, aResult)) {
     return aResult;
   }
   return aStr;
 }
+
 const nsSubstring&
 NS_EscapeURL(const nsSubstring& aStr, uint32_t aFlags, nsSubstring& aResult);
 
 /**
  * Percent-escapes all characters in aStr that occurs in aForbidden.
  * @param aStr the input URL string
  * @param aForbidden the characters that should be escaped if found in aStr
  * @note that aForbidden MUST be sorted (low to high)