Bug 1228103. r=smaug.
authorHenri Sivonen <hsivonen@hsivonen.fi>
Tue, 09 Feb 2016 12:45:59 +0200
changeset 283526 b5ef9e8af8425f2cb3223a2114924f808d5bfbfe
parent 283525 1e661e47254accb6c9ff404aa043d3a715467707
child 283527 0fa3eddf8063895c3a45164a4416471c0eb5a026
push id71590
push userhsivonen@mozilla.com
push dateTue, 09 Feb 2016 10:46:40 +0000
treeherdermozilla-inbound@0fa3eddf8063 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1228103
milestone47.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 1228103. r=smaug.
parser/htmlparser/nsExpatDriver.cpp
parser/htmlparser/nsParser.cpp
parser/htmlparser/nsScanner.cpp
parser/htmlparser/nsScanner.h
parser/htmlparser/nsScannerString.cpp
parser/htmlparser/nsScannerString.h
--- a/parser/htmlparser/nsExpatDriver.cpp
+++ b/parser/htmlparser/nsExpatDriver.cpp
@@ -1123,22 +1123,28 @@ nsExpatDriver::ConsumeToken(nsScanner& a
       XML_Size lastLineLength = XML_GetCurrentColumnNumber(mExpatParser);
 
       if (lastLineLength <= consumed) {
         // The length of the last line was less than what expat consumed, so
         // there was at least one line break in the consumed data. Store the
         // last line until the point where we stopped parsing.
         nsScannerIterator startLastLine = currentExpatPosition;
         startLastLine.advance(-((ptrdiff_t)lastLineLength));
-        CopyUnicodeTo(startLastLine, currentExpatPosition, mLastLine);
+        if (!CopyUnicodeTo(startLastLine, currentExpatPosition, mLastLine)) {
+          return (mInternalState = NS_ERROR_OUT_OF_MEMORY);
+        }
       }
       else {
         // There was no line break in the consumed data, append the consumed
         // data.
-        AppendUnicodeTo(oldExpatPosition, currentExpatPosition, mLastLine);
+        if (!AppendUnicodeTo(oldExpatPosition,
+                             currentExpatPosition,
+                             mLastLine)) {
+          return (mInternalState = NS_ERROR_OUT_OF_MEMORY);
+        }
       }
     }
 
     mExpatBuffered += length - consumed;
 
     if (BlockedOrInterrupted()) {
       MOZ_LOG(GetExpatDriverLog(), LogLevel::Debug,
              ("Blocked or interrupted parser (probably for loading linked "
--- a/parser/htmlparser/nsParser.cpp
+++ b/parser/htmlparser/nsParser.cpp
@@ -1507,17 +1507,19 @@ nsParser::ResumeParse(bool allowIteratio
                 DidBuildModel(mStreamStatus);
                 return NS_OK;
               }
             } else {
               CParserContext* theContext = PopContext();
               if (theContext) {
                 theIterationIsOk = allowIteration && theContextIsStringBased;
                 if (theContext->mCopyUnused) {
-                  theContext->mScanner->CopyUnusedData(mUnusedInput);
+                  if (!theContext->mScanner->CopyUnusedData(mUnusedInput)) {
+                    mInternalState = NS_ERROR_OUT_OF_MEMORY;
+                  }
                 }
 
                 delete theContext;
               }
 
               result = mInternalState;
               aIsFinalChunk = mParserContext &&
                               mParserContext->mStreamListenerState == eOnStop;
--- a/parser/htmlparser/nsScanner.cpp
+++ b/parser/htmlparser/nsScanner.cpp
@@ -384,17 +384,19 @@ nsresult nsScanner::Peek(nsAString& aStr
   if (mCountRemaining < uint32_t(aNumChars + aOffset)) {
     end = mEndPosition;
   }
   else {
     end = start;
     end.advance(aNumChars);
   }
 
-  CopyUnicodeTo(start, end, aStr);
+  if (!CopyUnicodeTo(start, end, aStr)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
 
   return NS_OK;
 }
 
 
 /**
  *  Skip whitespace on scanner input stream
  *  
@@ -548,17 +550,19 @@ nsresult nsScanner::ReadTagIdentifier(ns
 
     if (!found) {
       ++current;
     }
   }
 
   // Don't bother appending nothing.
   if (current != mCurrentPosition) {
-    AppendUnicodeTo(mCurrentPosition, current, aString);
+    if (!AppendUnicodeTo(mCurrentPosition, current, aString)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
   }
 
   SetPosition(current);  
   if (current == end) {
     result = kEOF;
   }
 
   //DoErrTest(aString);
@@ -603,26 +607,30 @@ nsresult nsScanner::ReadEntityIdentifier
         default:
           found = ('a'<=theChar && theChar<='z') ||
                   ('A'<=theChar && theChar<='Z') ||
                   ('0'<=theChar && theChar<='9');
           break;
       }
 
       if(!found) {
-        AppendUnicodeTo(mCurrentPosition, current, aString);
+        if (!AppendUnicodeTo(mCurrentPosition, current, aString)) {
+          return NS_ERROR_OUT_OF_MEMORY;
+        }
         break;
       }
     }
     ++current;
   }
   
   SetPosition(current);
   if (current == end) {
-    AppendUnicodeTo(origin, current, aString);
+    if (!AppendUnicodeTo(origin, current, aString)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
     return kEOF;
   }
 
   //DoErrTest(aString);
 
   return result;
 }
 
@@ -652,26 +660,30 @@ nsresult nsScanner::ReadNumber(nsString&
   while(current != end) {
     theChar=*current;
     if(theChar) {
       done = (theChar < '0' || theChar > '9') && 
              ((aBase == 16)? (theChar < 'A' || theChar > 'F') &&
                              (theChar < 'a' || theChar > 'f')
                              :true);
       if(done) {
-        AppendUnicodeTo(origin, current, aString);
+        if (!AppendUnicodeTo(origin, current, aString)) {
+          return NS_ERROR_OUT_OF_MEMORY;
+        }
         break;
       }
     }
     ++current;
   }
 
   SetPosition(current);
   if (current == end) {
-    AppendUnicodeTo(origin, current, aString);
+    if (!AppendUnicodeTo(origin, current, aString)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
     return kEOF;
   }
 
   //DoErrTest(aString);
 
   return result;
 }
 
@@ -718,37 +730,43 @@ nsresult nsScanner::ReadWhitespace(nsSca
           char16_t thePrevChar = theChar;
           theChar = (++current != end) ? *current : '\0';
           if ((thePrevChar == '\r' && theChar == '\n') ||
               (thePrevChar == '\n' && theChar == '\r')) {
             theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
             haveCR = true;
           } else if (thePrevChar == '\r') {
             // Lone CR becomes CRLF; callers should know to remove extra CRs
-            AppendUnicodeTo(origin, current, aString);
+            if (!AppendUnicodeTo(origin, current, aString)) {
+              return NS_ERROR_OUT_OF_MEMORY;
+            }
             aString.writable().Append(char16_t('\n'));
             origin = current;
             haveCR = true;
           }
         }
         break;
       case ' ' :
       case '\t':
         theChar = (++current != end) ? *current : '\0';
         break;
       default:
         done = true;
-        AppendUnicodeTo(origin, current, aString);
+        if (!AppendUnicodeTo(origin, current, aString)) {
+          return NS_ERROR_OUT_OF_MEMORY;
+        }
         break;
     }
   }
 
   SetPosition(current);
   if (current == end) {
-    AppendUnicodeTo(origin, current, aString);
+    if (!AppendUnicodeTo(origin, current, aString)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
     result = kEOF;
   }
 
   aHaveCR = haveCR;
   return result;
 }
 
 //XXXbz callers of this have to manage their lone '\r' themselves if they want
@@ -853,34 +871,38 @@ nsresult nsScanner::ReadUntil(nsAString&
     if(!(theChar & aEndCondition.mFilter)) {
       // They were. Do a thorough check.
 
       setcurrent = setstart;
       while (*setcurrent) {
         if (*setcurrent == theChar) {
           if(addTerminal)
             ++current;
-          AppendUnicodeTo(origin, current, aString);
+          if (!AppendUnicodeTo(origin, current, aString)) {
+            return NS_ERROR_OUT_OF_MEMORY;
+          }
           SetPosition(current);
 
           //DoErrTest(aString);
 
           return NS_OK;
         }
         ++setcurrent;
       }
     }
     
     ++current;
   }
 
   // If we are here, we didn't find any terminator in the string and
   // current = mEndPosition
   SetPosition(current);
-  AppendUnicodeTo(origin, current, aString);
+  if (!AppendUnicodeTo(origin, current, aString)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
   return kEOF;
 }
 
 nsresult nsScanner::ReadUntil(nsScannerSharedSubstring& aString,
                               const nsReadEndCondition& aEndCondition,
                               bool addTerminal)
 {  
   if (!mSlidingBuffer) {
@@ -913,34 +935,38 @@ nsresult nsScanner::ReadUntil(nsScannerS
     if(!(theChar & aEndCondition.mFilter)) {
       // They were. Do a thorough check.
 
       setcurrent = setstart;
       while (*setcurrent) {
         if (*setcurrent == theChar) {
           if(addTerminal)
             ++current;
-          AppendUnicodeTo(origin, current, aString);
+          if (!AppendUnicodeTo(origin, current, aString)) {
+            return NS_ERROR_OUT_OF_MEMORY;
+          }
           SetPosition(current);
 
           //DoErrTest(aString);
 
           return NS_OK;
         }
         ++setcurrent;
       }
     }
     
     ++current;
   }
 
   // If we are here, we didn't find any terminator in the string and
   // current = mEndPosition
   SetPosition(current);
-  AppendUnicodeTo(origin, current, aString);
+  if (!AppendUnicodeTo(origin, current, aString)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
   return kEOF;
 }
 
 nsresult nsScanner::ReadUntil(nsScannerIterator& aStart, 
                               nsScannerIterator& aEnd,
                               const nsReadEndCondition &aEndCondition,
                               bool addTerminal)
 {
@@ -1032,26 +1058,30 @@ nsresult nsScanner::ReadUntil(nsAString&
     if (theChar == '\0') {
       ReplaceCharacter(current, sInvalid);
       theChar = sInvalid;
     }
 
     if (aTerminalChar == theChar) {
       if(addTerminal)
         ++current;
-      AppendUnicodeTo(origin, current, aString);
+      if (!AppendUnicodeTo(origin, current, aString)) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
       SetPosition(current);
       return NS_OK;
     }
     ++current;
   }
 
   // If we are here, we didn't find any terminator in the string and
   // current = mEndPosition
-  AppendUnicodeTo(origin, current, aString);
+  if (!AppendUnicodeTo(origin, current, aString)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
   SetPosition(current);
   return kEOF;
 
 }
 
 void nsScanner::BindSubstring(nsScannerSubstring& aSubstring, const nsScannerIterator& aStart, const nsScannerIterator& aEnd)
 {
   aSubstring.Rebind(*mSlidingBuffer, aStart, aEnd);
@@ -1149,29 +1179,29 @@ bool nsScanner::AppendToBuffer(nsScanner
 }
 
 /**
  *  call this to copy bytes out of the scanner that have not yet been consumed
  *  by the tokenization process.
  *  
  *  @update  gess 5/12/98
  *  @param   aCopyBuffer is where the scanner buffer will be copied to
- *  @return  nada
+ *  @return  true if OK or false on OOM
  */
-void nsScanner::CopyUnusedData(nsString& aCopyBuffer) {
+bool nsScanner::CopyUnusedData(nsString& aCopyBuffer) {
   if (!mSlidingBuffer) {
     aCopyBuffer.Truncate();
-    return;
+    return true;
   }
 
   nsScannerIterator start, end;
   start = mCurrentPosition;
   end = mEndPosition;
 
-  CopyUnicodeTo(start, end, aCopyBuffer);
+  return CopyUnicodeTo(start, end, aCopyBuffer);
 }
 
 /**
  *  Retrieve the name of the file that the scanner is reading from.
  *  In some cases, it's just a given name, because the scanner isn't
  *  really reading from a file.
  *  
  *  @update  gess 5/12/98
--- a/parser/htmlparser/nsScanner.h
+++ b/parser/htmlparser/nsScanner.h
@@ -202,19 +202,19 @@ class nsScanner {
                       nsIRequest *aRequest);
 
       /**
        *  Call this to copy bytes out of the scanner that have not yet been consumed
        *  by the tokenization process.
        *  
        *  @update  gess 5/12/98
        *  @param   aCopyBuffer is where the scanner buffer will be copied to
-       *  @return  nada
+       *  @return  true if OK or false on OOM
        */
-      void CopyUnusedData(nsString& aCopyBuffer);
+      bool CopyUnusedData(nsString& aCopyBuffer);
 
       /**
        *  Retrieve the name of the file that the scanner is reading from.
        *  In some cases, it's just a given name, because the scanner isn't
        *  really reading from a file.
        *  
        *  @update  gess 5/12/98
        *  @return  
--- a/parser/htmlparser/nsScannerString.cpp
+++ b/parser/htmlparser/nsScannerString.cpp
@@ -461,61 +461,63 @@ copy_multifragment_string( nsScannerIter
         sink_traits::write(result, source_traits::read(first), distance);
         NS_ASSERTION(distance > 0, "|copy_multifragment_string| will never terminate");
         source_traits::advance(first, distance);
       }
 
     return result;
   }
 
-void
+bool
 CopyUnicodeTo( const nsScannerIterator& aSrcStart,
                const nsScannerIterator& aSrcEnd,
                nsAString& aDest )
   {
     nsAString::iterator writer;
     if (!aDest.SetLength(Distance(aSrcStart, aSrcEnd), mozilla::fallible)) {
       aDest.Truncate();
-      return; // out of memory
+      return false; // out of memory
     }
     aDest.BeginWriting(writer);
     nsScannerIterator fromBegin(aSrcStart);
     
     copy_multifragment_string(fromBegin, aSrcEnd, writer);
+    return true;
   }
 
-void
+bool
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsScannerSharedSubstring& aDest )
   {
     // Check whether we can just create a dependent string.
     if (aDest.str().IsEmpty()) {
       // We can just make |aDest| point to the buffer.
       // This will take care of copying if the buffer spans fragments.
       aDest.Rebind(aSrcStart, aSrcEnd);
-    } else {
-      // The dest string is not empty, so it can't be a dependent substring.
-      AppendUnicodeTo(aSrcStart, aSrcEnd, aDest.writable());
+      return true;
     }
+    // The dest string is not empty, so it can't be a dependent substring.
+    return AppendUnicodeTo(aSrcStart, aSrcEnd, aDest.writable());
   }
 
-void
+bool
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsAString& aDest )
   {
     nsAString::iterator writer;
     uint32_t oldLength = aDest.Length();
     if (!aDest.SetLength(oldLength + Distance(aSrcStart, aSrcEnd), mozilla::fallible))
-      return; // out of memory
+      return false; // out of memory
     aDest.BeginWriting(writer).advance(oldLength);
     nsScannerIterator fromBegin(aSrcStart);
     
     copy_multifragment_string(fromBegin, aSrcEnd, writer);
+    return true;
   }
 
 bool
 FindCharInReadable( char16_t aChar,
                     nsScannerIterator& aSearchStart,
                     const nsScannerIterator& aSearchEnd )
   {
     while ( aSearchStart != aSearchEnd )
--- a/parser/htmlparser/nsScannerString.h
+++ b/parser/htmlparser/nsScannerString.h
@@ -539,43 +539,43 @@ nsScannerBufferList::Position::operator=
 inline
 size_t
 Distance( const nsScannerIterator& aStart, const nsScannerIterator& aEnd )
   {
     typedef nsScannerBufferList::Position Position;
     return Position::Distance(Position(aStart), Position(aEnd));
   }
 
-void
+bool
 CopyUnicodeTo( const nsScannerIterator& aSrcStart,
                const nsScannerIterator& aSrcEnd,
                nsAString& aDest );
 
 inline
-void
+bool
 CopyUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
   {
     nsScannerIterator begin, end;
-    CopyUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
+    return CopyUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
   }
 
-void
+bool
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsAString& aDest );
 
 inline
-void
+bool
 AppendUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
   {
     nsScannerIterator begin, end;
-    AppendUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
+    return AppendUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
   }
 
-void
+bool
 AppendUnicodeTo( const nsScannerIterator& aSrcStart,
                  const nsScannerIterator& aSrcEnd,
                  nsScannerSharedSubstring& aDest );
 
 bool
 FindCharInReadable( char16_t aChar,
                     nsScannerIterator& aStart,
                     const nsScannerIterator& aEnd );