Bug 328755 - Assigning a zero-length string should not alloc a buffer. r=bsmedberg
authorJames Kitchener <jkitch.bug@gmail.com>
Mon, 03 Feb 2014 22:57:56 +1030
changeset 169364 6f1e6f7d3041bc1da91f1814497a71366a9bdbc3
parent 169363 c0e256be477547426276d2a9d078e7a4c6c1729b
child 169365 b95d0fb140264ad21beb8bcf91f590ab1122bc02
push id26245
push userryanvm@gmail.com
push dateTue, 18 Feb 2014 20:18:17 +0000
treeherdermozilla-central@9019cc90719c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs328755
milestone30.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 328755 - Assigning a zero-length string should not alloc a buffer. r=bsmedberg
xpcom/io/Base64.cpp
xpcom/io/nsEscape.cpp
xpcom/string/public/nsCharTraits.h
xpcom/string/src/nsSubstring.cpp
xpcom/string/src/nsTSubstring.cpp
--- a/xpcom/io/Base64.cpp
+++ b/xpcom/io/Base64.cpp
@@ -204,17 +204,20 @@ EncodeInputStream(nsIInputStream *aInput
     if (!read)
       break;
   }
 
   // Finish encoding if anything is left
   if (state.charsOnStack)
     Encode(state.c, state.charsOnStack, state.buffer);
 
-  *aDest.EndWriting() = '\0';
+  if (aDest.Length())
+    // May belong to an nsCString with an unallocated buffer, so only null
+    // terminate if there is a need to.
+    *aDest.EndWriting() = '\0';
 
   return NS_OK;
 }
 
 } // namespace (anonymous)
 
 namespace mozilla {
 
--- a/xpcom/io/nsEscape.cpp
+++ b/xpcom/io/nsEscape.cpp
@@ -148,16 +148,23 @@ int32_t nsUnescapeCount(char * str)
     char *dst = str;
     static const char hexChars[] = "0123456789ABCDEFabcdef";
 
     char c1[] = " ";
     char c2[] = " ";
     char* const pc1 = c1;
     char* const pc2 = c2;
 
+    if (!*src) {
+      // A null string was passed in.  Nothing to escape.
+      // Returns early as the string might not actually be mutable with
+      // length 0.
+      return 0;
+    }
+
     while (*src)
     {
         c1[0] = *(src+1);
         if (*(src+1) == '\0') 
             c2[0] = '\0';
         else
             c2[0] = *(src+2);
 
--- a/xpcom/string/public/nsCharTraits.h
+++ b/xpcom/string/public/nsCharTraits.h
@@ -95,17 +95,17 @@ template <class CharT> struct nsCharTrai
 
 template <>
 struct nsCharTraits<char16_t>
   {
     typedef char16_t char_type;
     typedef uint16_t  unsigned_char_type;
     typedef char      incompatible_char_type;
 
-    static char_type *sEmptyBuffer;
+    static char_type* const sEmptyBuffer;
 
     static
     void
     assign( char_type& lhs, char_type rhs )
       {
         lhs = rhs;
       }
 
@@ -321,17 +321,17 @@ struct nsCharTraits<char16_t>
 
 template <>
 struct nsCharTraits<char>
   {
     typedef char           char_type;
     typedef unsigned char  unsigned_char_type;
     typedef char16_t      incompatible_char_type;
 
-    static char_type *sEmptyBuffer;
+    static char_type* const sEmptyBuffer;
 
     static
     void
     assign( char_type& lhs, char_type rhs )
       {
         lhs = rhs;
       }
 
--- a/xpcom/string/src/nsSubstring.cpp
+++ b/xpcom/string/src/nsSubstring.cpp
@@ -35,20 +35,22 @@
 #include <pthread.h>
 #include <unistd.h>
 #endif
 
 using mozilla::Atomic;
 
 // ---------------------------------------------------------------------------
 
-static char16_t gNullChar = 0;
+static const char16_t gNullChar = 0;
 
-char*      nsCharTraits<char>     ::sEmptyBuffer = (char*) &gNullChar;
-char16_t* nsCharTraits<char16_t>::sEmptyBuffer =         &gNullChar;
+char* const nsCharTraits<char>::sEmptyBuffer =
+  (char*) const_cast<char16_t*>(&gNullChar);
+char16_t* const nsCharTraits<char16_t>::sEmptyBuffer =
+  const_cast<char16_t*>(&gNullChar);
 
 // ---------------------------------------------------------------------------
 
 #ifdef ENABLE_STRING_STATS
 class nsStringStats
   {
     public:
       nsStringStats()
--- a/xpcom/string/src/nsTSubstring.cpp
+++ b/xpcom/string/src/nsTSubstring.cpp
@@ -299,17 +299,17 @@ nsTSubstring_CharT::Assign( const char_t
   {
     if (!Assign(data, length, fallible_t()))
       NS_ABORT_OOM(length);
   }
 
 bool
 nsTSubstring_CharT::Assign( const char_type* data, size_type length, const fallible_t& )
   {
-    if (!data)
+    if (!data || length == 0)
       {
         Truncate();
         return true;
       }
 
     if (length == size_type(-1))
       length = char_traits::length(data);