Bug 1172055 - Improve size check in nsAttrAndChildArray::GrowBy, r=ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 10 Jul 2015 00:18:30 +0100
changeset 252283 a9e266811633fa2b0e589fd6f09c560e98b99f54
parent 252282 daf75d6af663aef5ea04282f083c6e1df4e31948
child 252284 31fef8afde5a9cc5d96e72318a320e1b52e9ead8
push id62107
push useramarchesini@mozilla.com
push dateFri, 10 Jul 2015 12:19:25 +0000
treeherdermozilla-inbound@a9e266811633 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1172055
milestone42.0a1
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 1172055 - Improve size check in nsAttrAndChildArray::GrowBy, r=ehsan
dom/base/nsAttrAndChildArray.cpp
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -759,56 +759,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*>(realloc(mImpl, size * sizeof(void*)));
+  CheckedUint32 neededSize = size;
+  neededSize *= sizeof(void*);
+  if (!neededSize.isValid()) {
+    return false;
+  }
+
+  Impl* newImpl = static_cast<Impl*>(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);