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