Copied from upstream: https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/271e3a5a53d9 # HG changeset patch # User Henri Sivonen # Date 1455014759 -7200 # Node ID 271e3a5a53d96871141e89271f611033b512e3e4 # Parent 9719b71d72dd2a3c5ee12ace156af2a63d9595ac Bug 1228103. r=smaug. a=sylvestre diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp --- a/parser/htmlparser/nsExpatDriver.cpp +++ b/parser/htmlparser/nsExpatDriver.cpp @@ -1127,22 +1127,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()) { PR_LOG(GetExpatDriverLog(), PR_LOG_DEBUG, ("Blocked or interrupted parser (probably for loading linked " diff --git a/parser/htmlparser/nsParser.cpp b/parser/htmlparser/nsParser.cpp --- a/parser/htmlparser/nsParser.cpp +++ b/parser/htmlparser/nsParser.cpp @@ -1508,17 +1508,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; diff --git a/parser/htmlparser/nsScanner.cpp b/parser/htmlparser/nsScanner.cpp --- a/parser/htmlparser/nsScanner.cpp +++ b/parser/htmlparser/nsScanner.cpp @@ -379,17 +379,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 * @@ -542,17 +544,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); @@ -597,26 +601,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; } @@ -646,26 +654,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; } @@ -712,37 +724,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 @@ -846,34 +864,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) { @@ -906,34 +928,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) { @@ -1025,26 +1051,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); @@ -1142,29 +1172,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 diff --git a/parser/htmlparser/nsScanner.h b/parser/htmlparser/nsScanner.h --- a/parser/htmlparser/nsScanner.h +++ b/parser/htmlparser/nsScanner.h @@ -204,19 +204,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 diff --git a/parser/htmlparser/nsScannerString.cpp b/parser/htmlparser/nsScannerString.cpp --- 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 ) diff --git a/parser/htmlparser/nsScannerString.h b/parser/htmlparser/nsScannerString.h --- 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 );