bug 607160 - check text length computations. r=roc a=blocking2.0
authorJonathan Kew <jfkthame@gmail.com>
Thu, 25 Nov 2010 15:36:53 +0000
changeset 58221 eb8d110a117aa494b073edeb50ba7383cfb218c9
parent 58220 8545045acca27b494f7eb353a8270a31d6e5092c
child 58222 6038dc8945d82f1b67b931faf2a32f1b5e415260
push id17207
push userjkew@mozilla.com
push dateThu, 25 Nov 2010 15:38:33 +0000
treeherdermozilla-central@eb8d110a117a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, blocking2.0
bugs607160
milestone2.0b8pre
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 607160 - check text length computations. r=roc a=blocking2.0
layout/generic/nsTextFrameThebes.cpp
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -861,16 +861,17 @@ private:
   gfxTextRun*                   mCurrentFramesAllSameTextRun;
   gfxContext*                   mContext;
   nsIFrame*                     mLineContainer;
   nsTextFrame*                  mLastFrame;
   // The common ancestor of the current frame and the previous leaf frame
   // on the line, or null if there was no previous leaf frame.
   nsIFrame*                     mCommonAncestorWithLastFrame;
   // mMaxTextLength is an upper bound on the size of the text in all mapped frames
+  // The value PR_UINT32_MAX represents overflow; text will be discarded
   PRUint32                      mMaxTextLength;
   PRPackedBool                  mDoubleByteText;
   PRPackedBool                  mBidiEnabled;
   PRPackedBool                  mStartOfLine;
   PRPackedBool                  mSkipIncompleteTextRuns;
   PRPackedBool                  mCanStopOnThisLine;
   PRUint8                       mNextRunContextInfo;
   PRUint8                       mCurrentRunContextInfo;
@@ -1289,18 +1290,21 @@ void BuildTextRunsScanner::FlushFrames(P
       if (textRun->GetFlags() & nsTextFrameUtils::TEXT_TRAILING_WHITESPACE) {
         mNextRunContextInfo |= nsTextFrameUtils::INCOMING_WHITESPACE;
       }
       if (textRun->GetFlags() & gfxTextRunWordCache::TEXT_TRAILING_ARABICCHAR) {
         mNextRunContextInfo |= nsTextFrameUtils::INCOMING_ARABICCHAR;
       }
     } else {
       nsAutoTArray<PRUint8,BIG_TEXT_NODE_SIZE> buffer;
-      if (!buffer.AppendElements(mMaxTextLength*(mDoubleByteText ? 2 : 1)))
+      PRUint32 bufferSize = mMaxTextLength*(mDoubleByteText ? 2 : 1);
+      if (bufferSize < mMaxTextLength || bufferSize == PR_UINT32_MAX ||
+          !buffer.AppendElements(bufferSize)) {
         return;
+      }
       textRun = BuildTextRunForFrames(buffer.Elements());
     }
   }
 
   if (aFlushLineBreaks) {
     FlushLineBreaks(aSuppressTrailingBreak ? nsnull : textRun);
   }
 
@@ -1334,18 +1338,24 @@ void BuildTextRunsScanner::FlushLineBrea
     gTextRuns->RemoveFromCache(deleteTextRun);
     delete deleteTextRun;
   }
   mTextRunsToDelete.Clear();
 }
 
 void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame)
 {
-  NS_ASSERTION(mMaxTextLength <= mMaxTextLength + aFrame->GetContentLength(), "integer overflow");
-  mMaxTextLength += aFrame->GetContentLength();
+  if (mMaxTextLength != PR_UINT32_MAX) {
+    NS_ASSERTION(mMaxTextLength < PR_UINT32_MAX - aFrame->GetContentLength(), "integer overflow");
+    if (mMaxTextLength >= PR_UINT32_MAX - aFrame->GetContentLength()) {
+      mMaxTextLength = PR_UINT32_MAX;
+    } else {
+      mMaxTextLength += aFrame->GetContentLength();
+    }
+  }
   mDoubleByteText |= aFrame->GetContent()->GetText()->Is2b();
   mLastFrame = aFrame;
   mCommonAncestorWithLastFrame = aFrame->GetParent();
 
   MappedFlow* mappedFlow = &mMappedFlows[mMappedFlows.Length() - 1];
   NS_ASSERTION(mappedFlow->mStartFrame == aFrame ||
                mappedFlow->GetContentEnd() == aFrame->GetContentOffset(),
                "Overlapping or discontiguous frames => BAD");