author | Eric Rahm <erahm@mozilla.com> |
Thu, 03 Sep 2015 13:33:46 -0700 | |
changeset 261050 | 7fd9619376872691295a9ed787c281e77be3481a |
parent 261049 | 4cd826f4b033f0cf1c93bfa5066ea1f14d77c6ef |
child 261051 | 2b1e7c1466c562c917d02f2b8df9c6fa79dbe15a |
push id | 29333 |
push user | philringnalda@gmail.com |
push date | Sun, 06 Sep 2015 03:20:00 +0000 |
treeherder | mozilla-central@56f5ffd44b7f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | froydnj |
bugs | 1199400 |
milestone | 43.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
|
--- a/xpcom/glue/nsDeque.cpp +++ b/xpcom/glue/nsDeque.cpp @@ -6,16 +6,18 @@ #include "nsDeque.h" #include "nsISupportsImpl.h" #include <string.h> #ifdef DEBUG_rickg #include <stdio.h> #endif +#include "mozilla/CheckedInt.h" + /** * 07/02/2001 09:17p 509,104 clangref.pdf from openwatcom's site * Watcom C Language Reference Edition 11.0c * page 118 of 297 * * The % symbol yields the remainder from the division of the first operand * by the second operand. The operands of % must have integral type. * @@ -158,39 +160,51 @@ nsDeque::Erase() * Elements in the deque are resequenced so that elements * in the deque are stored sequentially * * @return whether growing succeeded */ bool nsDeque::GrowCapacity() { - int32_t theNewSize = mCapacity << 2; - NS_ASSERTION(theNewSize > mCapacity, "Overflow"); - if (theNewSize <= mCapacity) { + mozilla::CheckedInt<int32_t> newCapacity = mCapacity; + newCapacity *= 4; + + NS_ASSERTION(newCapacity.isValid(), "Overflow"); + if (!newCapacity.isValid()) { return false; } - void** temp = (void**)malloc(theNewSize * sizeof(void*)); + + // Sanity check the new byte size. + mozilla::CheckedInt<int32_t> newByteSize = newCapacity; + newByteSize *= sizeof(void*); + + NS_ASSERTION(newByteSize.isValid(), "Overflow"); + if (!newByteSize.isValid()) { + return false; + } + + void** temp = (void**)malloc(newByteSize.value()); if (!temp) { return false; } //Here's the interesting part: You can't just move the elements //directly (in situ) from the old buffer to the new one. //Since capacity has changed, the old origin doesn't make //sense anymore. It's better to resequence the elements now. memcpy(temp, mData + mOrigin, sizeof(void*) * (mCapacity - mOrigin)); memcpy(temp + (mCapacity - mOrigin), mData, sizeof(void*) * mOrigin); if (mData != mBuffer) { free(mData); } - mCapacity = theNewSize; + mCapacity = newCapacity.value(); mOrigin = 0; //now realign the origin... mData = temp; return true; } /** * This method adds an item to the end of the deque.