From: Jonathan Kew <jfkthame@gmail.com>
Date: Sat, 1 Jan 2011 15:50:48 +0000
Subject: bug 607160 - check text length computations. r=roc approval1.9.1.17=clegnitto

---
 layout/generic/nsTextFrameThebes.cpp |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp
index 690b689..924e2ca 100644
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -816,6 +816,7 @@ private:
   // 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;
@@ -1232,8 +1233,11 @@ void BuildTextRunsScanner::FlushFrames(PRBool aFlushLineBreaks, PRBool aSuppress
       }
     } 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());
     }
   }
@@ -1277,8 +1281,14 @@ void BuildTextRunsScanner::FlushLineBreaks(gfxTextRun* aTrailingTextRun)
 
 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->GetFragment()->Is2b();
   mLastFrame = aFrame;
   mCommonAncestorWithLastFrame = aFrame->GetParent();
