Bug 1172055 - Improve size check in nsAttrAndChildArray::GrowBy. r=ehsan, a=mahe
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 10 Jul 2015 00:18:30 +0100
changeset 222379 71aa93494a06
parent 222378 b272be44ac17
child 222380 5e80c7eefb66
push id240
push userryanvm@gmail.com
push dateTue, 01 Sep 2015 02:40:06 +0000
treeherdermozilla-b2g34_v2_1s@71aa93494a06 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, mahe
bugs1172055
milestone34.0
Bug 1172055 - Improve size check in nsAttrAndChildArray::GrowBy. r=ehsan, a=mahe
content/base/src/nsAttrAndChildArray.cpp
--- a/content/base/src/nsAttrAndChildArray.cpp
+++ b/content/base/src/nsAttrAndChildArray.cpp
@@ -758,56 +758,86 @@ nsAttrAndChildArray::MakeMappedUnique(ns
 
   return NS_OK;
 }
 
 
 bool
 nsAttrAndChildArray::GrowBy(uint32_t aGrowSize)
 {
-  uint32_t size = mImpl ? mImpl->mBufferSize + NS_IMPL_EXTRA_SIZE : 0;
-  uint32_t minSize = size + aGrowSize;
+  CheckedUint32 size = 0;
+  if (mImpl) {
+    size += mImpl->mBufferSize;
+    size += NS_IMPL_EXTRA_SIZE;
+    if (!size.isValid()) {
+      return false;
+    }
+  }
 
-  if (minSize <= ATTRCHILD_ARRAY_LINEAR_THRESHOLD) {
+  CheckedUint32 minSize = size.value();
+  minSize += aGrowSize;
+  if (!minSize.isValid()) {
+    return false;
+  }
+
+  if (minSize.value() <= ATTRCHILD_ARRAY_LINEAR_THRESHOLD) {
     do {
       size += ATTRCHILD_ARRAY_GROWSIZE;
-    } while (size < minSize);
+      if (!size.isValid()) {
+        return false;
+      }
+    } while (size.value() < minSize.value());
   }
   else {
-    size = 1u << mozilla::CeilingLog2(minSize);
+    size = 1u << mozilla::CeilingLog2(minSize.value());
   }
 
   bool needToInitialize = !mImpl;
-  Impl* newImpl = static_cast<Impl*>(moz_realloc(mImpl, size * sizeof(void*)));
+  CheckedUint32 neededSize = size;
+  neededSize *= sizeof(void*);
+  if (!neededSize.isValid()) {
+    return false;
+  }
+
+  Impl* newImpl = static_cast<Impl*>(moz_realloc(mImpl, neededSize.value()));
   NS_ENSURE_TRUE(newImpl, false);
 
   mImpl = newImpl;
 
   // Set initial counts if we didn't have a buffer before
   if (needToInitialize) {
     mImpl->mMappedAttrs = nullptr;
     SetAttrSlotAndChildCount(0, 0);
   }
 
-  mImpl->mBufferSize = size - NS_IMPL_EXTRA_SIZE;
+  mImpl->mBufferSize = size.value() - NS_IMPL_EXTRA_SIZE;
 
   return true;
 }
 
 bool
 nsAttrAndChildArray::AddAttrSlot()
 {
   uint32_t slotCount = AttrSlotCount();
   uint32_t childCount = ChildCount();
 
+  CheckedUint32 size = slotCount;
+  size += 1;
+  size *= ATTRSIZE;
+  size += childCount;
+  if (!size.isValid()) {
+    return false;
+  }
+
   // Grow buffer if needed
-  if (!(mImpl && mImpl->mBufferSize >= (slotCount + 1) * ATTRSIZE + childCount) &&
+  if (!(mImpl && mImpl->mBufferSize >= size.value()) &&
       !GrowBy(ATTRSIZE)) {
     return false;
   }
+
   void** offset = mImpl->mBuffer + slotCount * ATTRSIZE;
 
   if (childCount > 0) {
     memmove(&ATTRS(mImpl)[slotCount + 1], &ATTRS(mImpl)[slotCount],
             childCount * sizeof(nsIContent*));
   }
 
   SetAttrSlotCount(slotCount + 1);