Bug 1291082 - ContentCacheInParent::GetUnionTextRects() shouldn't use mTextRectArray when it's empty. r=m_kato, a=ritu
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 02 Aug 2016 12:02:14 +0900
changeset 350961 3efa36accd3f965657b982cd24bac1b2929281d4
parent 350960 5d2cabc2cc9f0741942b83a462ba11a0bfedd837
child 350962 590db93819a56ed477aff263e452ee4991de6b04
push id1303
push userryanvm@gmail.com
push dateMon, 05 Dec 2016 22:59:59 +0000
treeherdermozilla-release@3c35b7472b97 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato, ritu
bugs1291082
milestone50.1.0
Bug 1291082 - ContentCacheInParent::GetUnionTextRects() shouldn't use mTextRectArray when it's empty. r=m_kato, a=ritu This must be able to reproduce with some IMEs which creates 0 length composition string. In such case, mTextRectArray isn't available, but mTextRectArray.GetUnionRectAsFarAsPossible() always assumes that it's valid and has at least one rect. Therefore, it can meet this crash. Therefore, this patch makes that ContentCacheInParent::GetUnionTextRects() not use mTextRectArray when it's not valid nor doesn't have rects. MozReview-Commit-ID: 2yLMo4lxI3Z
widget/ContentCache.cpp
widget/ContentCache.h
--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -824,17 +824,17 @@ ContentCacheInParent::GetUnionTextRects(
   // in most cases.
 
   if (!aOffset && aOffset != mSelection.mAnchor &&
       aOffset != mSelection.mFocus && !mTextRectArray.InRange(aOffset)) {
     // The first character rect isn't cached.
     return false;
   }
 
-  if ((aRoundToExistingOffset && mTextRectArray.IsValid()) ||
+  if ((aRoundToExistingOffset && mTextRectArray.HasRects()) ||
       mTextRectArray.IsOverlappingWith(aOffset, aLength)) {
     aUnionTextRect =
       mTextRectArray.GetUnionRectAsFarAsPossible(aOffset, aLength,
                                                  aRoundToExistingOffset);
   } else {
     aUnionTextRect.SetEmpty();
   }
 
@@ -1167,16 +1167,18 @@ ContentCache::TextRectArray::GetUnionRec
 }
 
 LayoutDeviceIntRect
 ContentCache::TextRectArray::GetUnionRectAsFarAsPossible(
                                uint32_t aOffset,
                                uint32_t aLength,
                                bool aRoundToExistingOffset) const
 {
+  MOZ_ASSERT(HasRects());
+
   LayoutDeviceIntRect rect;
   if (!aRoundToExistingOffset && !IsOverlappingWith(aOffset, aLength)) {
     return rect;
   }
   uint32_t startOffset = std::max(aOffset, mStart);
   if (aRoundToExistingOffset && startOffset >= EndOffset()) {
     startOffset = EndOffset() - 1;
   }
--- a/widget/ContentCache.h
+++ b/widget/ContentCache.h
@@ -177,16 +177,20 @@ protected:
     {
       if (mStart == UINT32_MAX) {
         return false;
       }
       CheckedInt<uint32_t> endOffset =
         CheckedInt<uint32_t>(mStart) + mRects.Length();
       return endOffset.isValid();
     }
+    bool HasRects() const
+    {
+      return IsValid() && !mRects.IsEmpty();
+    }
     uint32_t StartOffset() const
     {
       NS_ASSERTION(IsValid(),
                    "The caller should check if the caret is valid");
       return mStart;
     }
     uint32_t EndOffset() const
     {