Bug 1309834. r=wchen.
MozReview-Commit-ID: FO7bXlx6lv
This commit is contained in:
@@ -50,12 +50,12 @@ struct jArray {
|
||||
L length;
|
||||
static jArray<T,L> newJArray(L const len) {
|
||||
MOZ_ASSERT(len >= 0, "Negative length.");
|
||||
jArray<T,L> newArray = { new T[len], len };
|
||||
jArray<T,L> newArray = { new T[size_t(len)], len };
|
||||
return newArray;
|
||||
}
|
||||
static jArray<T,L> newFallibleJArray(L const len) {
|
||||
MOZ_ASSERT(len >= 0, "Negative length.");
|
||||
T* a = new (mozilla::fallible) T[len];
|
||||
T* a = new (mozilla::fallible) T[size_t(len)];
|
||||
jArray<T,L> newArray = { a, a ? len : 0 };
|
||||
return newArray;
|
||||
}
|
||||
|
||||
@@ -36,43 +36,43 @@ class nsHtml5ArrayCopy {
|
||||
static inline void
|
||||
arraycopy(char16_t* source, int32_t sourceOffset, char16_t* target, int32_t targetOffset, int32_t length)
|
||||
{
|
||||
memcpy(&(target[targetOffset]), &(source[sourceOffset]), length * sizeof(char16_t));
|
||||
memcpy(&(target[targetOffset]), &(source[sourceOffset]), size_t(length) * sizeof(char16_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
arraycopy(char16_t* source, char16_t* target, int32_t length)
|
||||
{
|
||||
memcpy(target, source, length * sizeof(char16_t));
|
||||
memcpy(target, source, size_t(length) * sizeof(char16_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
arraycopy(int32_t* source, int32_t* target, int32_t length)
|
||||
{
|
||||
memcpy(target, source, length * sizeof(int32_t));
|
||||
memcpy(target, source, size_t(length) * sizeof(int32_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
arraycopy(nsString** source, nsString** target, int32_t length)
|
||||
{
|
||||
memcpy(target, source, length * sizeof(nsString*));
|
||||
memcpy(target, source, size_t(length) * sizeof(nsString*));
|
||||
}
|
||||
|
||||
static inline void
|
||||
arraycopy(nsHtml5AttributeName** source, nsHtml5AttributeName** target, int32_t length)
|
||||
{
|
||||
memcpy(target, source, length * sizeof(nsHtml5AttributeName*));
|
||||
memcpy(target, source, size_t(length) * sizeof(nsHtml5AttributeName*));
|
||||
}
|
||||
|
||||
static inline void
|
||||
arraycopy(nsHtml5StackNode** source, nsHtml5StackNode** target, int32_t length)
|
||||
{
|
||||
memcpy(target, source, length * sizeof(nsHtml5StackNode*));
|
||||
memcpy(target, source, size_t(length) * sizeof(nsHtml5StackNode*));
|
||||
}
|
||||
|
||||
static inline void
|
||||
arraycopy(nsHtml5StackNode** arr, int32_t sourceOffset, int32_t targetOffset, int32_t length)
|
||||
{
|
||||
memmove(&(arr[targetOffset]), &(arr[sourceOffset]), length * sizeof(nsHtml5StackNode*));
|
||||
memmove(&(arr[targetOffset]), &(arr[sourceOffset]), size_t(length) * sizeof(nsHtml5StackNode*));
|
||||
}
|
||||
};
|
||||
#endif // nsHtml5ArrayCopy_h
|
||||
|
||||
@@ -4,39 +4,56 @@
|
||||
|
||||
#include "mozilla/Likely.h"
|
||||
|
||||
// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
|
||||
// is 2^30. Note that this is counting char16_t units. The underlying
|
||||
// bytes will be twice that, but they fit even in 32-bit size_t even
|
||||
// if a contiguous chunk of memory of that size is pretty unlikely to
|
||||
// be available on a 32-bit system.
|
||||
#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
|
||||
|
||||
bool
|
||||
nsHtml5Tokenizer::EnsureBufferSpace(int32_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(aLength >= 0, "Negative length.");
|
||||
MOZ_RELEASE_ASSERT(aLength >= 0, "Negative length.");
|
||||
if (aLength > MAX_POWER_OF_TWO_IN_INT32) {
|
||||
// Can't happen when loading from network.
|
||||
return false;
|
||||
}
|
||||
CheckedInt<int32_t> worstCase(strBufLen);
|
||||
worstCase += aLength;
|
||||
worstCase += charRefBufLen;
|
||||
// Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
|
||||
// Adding to the general worst case instead of only the
|
||||
// TreeBuilder-exposed worst case to avoid re-introducing a bug when
|
||||
// unifying the tokenizer and tree builder buffers in the future.
|
||||
size_t worstCase = size_t(strBufLen) +
|
||||
size_t(aLength) +
|
||||
size_t(charRefBufLen) +
|
||||
size_t(2);
|
||||
if (worstCase > INT32_MAX) {
|
||||
// Since we index into the buffer using int32_t due to the Java heritage
|
||||
// of the code, let's treat this as OOM.
|
||||
worstCase += 2;
|
||||
if (!worstCase.isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
|
||||
// so that the call below becomes unnecessary.
|
||||
tokenHandler->EnsureBufferSpace(worstCase);
|
||||
if (!tokenHandler->EnsureBufferSpace(worstCase.value())) {
|
||||
return false;
|
||||
}
|
||||
if (!strBuf) {
|
||||
if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
|
||||
// Add one to round to the next power of two to avoid immediate
|
||||
// reallocation once there are a few characters in the buffer.
|
||||
strBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase + 1));
|
||||
worstCase += 1;
|
||||
}
|
||||
strBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
|
||||
if (!strBuf) {
|
||||
return false;
|
||||
}
|
||||
} else if (worstCase > size_t(strBuf.length)) {
|
||||
jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase));
|
||||
} else if (worstCase.value() > strBuf.length) {
|
||||
jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
|
||||
if (!newBuf) {
|
||||
return false;
|
||||
}
|
||||
memcpy(newBuf,strBuf, sizeof(char16_t) * strBufLen);
|
||||
memcpy(newBuf, strBuf, sizeof(char16_t) * size_t(strBufLen));
|
||||
strBuf = newBuf;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -961,30 +961,42 @@ nsHtml5TreeBuilder::accumulateCharacters(const char16_t* aBuf, int32_t aStart, i
|
||||
charBufferLen += aLength;
|
||||
}
|
||||
|
||||
// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
|
||||
// is 2^30. Note that this is counting char16_t units. The underlying
|
||||
// bytes will be twice that, but they fit even in 32-bit size_t even
|
||||
// if a contiguous chunk of memory of that size is pretty unlikely to
|
||||
// be available on a 32-bit system.
|
||||
#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
|
||||
|
||||
bool
|
||||
nsHtml5TreeBuilder::EnsureBufferSpace(size_t aLength)
|
||||
nsHtml5TreeBuilder::EnsureBufferSpace(int32_t aLength)
|
||||
{
|
||||
// TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
|
||||
// so that this method becomes unnecessary.
|
||||
size_t worstCase = size_t(charBufferLen) + aLength;
|
||||
if (worstCase > INT32_MAX) {
|
||||
// Since we index into the buffer using int32_t due to the Java heritage
|
||||
// of the code, let's treat this as OOM.
|
||||
CheckedInt<int32_t> worstCase(charBufferLen);
|
||||
worstCase += aLength;
|
||||
if (!worstCase.isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
|
||||
return false;
|
||||
}
|
||||
if (!charBuffer) {
|
||||
if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
|
||||
// Add one to round to the next power of two to avoid immediate
|
||||
// reallocation once there are a few characters in the buffer.
|
||||
charBuffer = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase + 1));
|
||||
worstCase += 1;
|
||||
}
|
||||
charBuffer = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
|
||||
if (!charBuffer) {
|
||||
return false;
|
||||
}
|
||||
} else if (worstCase > size_t(charBuffer.length)) {
|
||||
jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase));
|
||||
} else if (worstCase.value() > charBuffer.length) {
|
||||
jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
|
||||
if (!newBuf) {
|
||||
return false;
|
||||
}
|
||||
memcpy(newBuf, charBuffer, sizeof(char16_t) * charBufferLen);
|
||||
memcpy(newBuf, charBuffer, sizeof(char16_t) * size_t(charBufferLen));
|
||||
charBuffer = newBuf;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
* next call to this method.
|
||||
* @return true if successful; false if out of memory
|
||||
*/
|
||||
bool EnsureBufferSpace(size_t aLength);
|
||||
bool EnsureBufferSpace(int32_t aLength);
|
||||
|
||||
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user