Index: src/objects.h |
diff --git a/src/objects.h b/src/objects.h |
index d6670bb573505e02fbd22fb804a91d3fb36e5957..d6432285c0f399d54b5273539f61751641ea4330 100644 |
--- a/src/objects.h |
+++ b/src/objects.h |
@@ -1508,6 +1508,10 @@ class JSObject: public HeapObject { |
#endif |
Object* SlowReverseLookup(Object* value); |
+ // Maximal number of elements (numbered 0 .. kMaxElementCount - 1). |
+ // Also maximal value of JSArray's length property. |
+ static const uint32_t kMaxElementCount = 0xffffffffu; |
+ |
static const uint32_t kMaxGap = 1024; |
static const int kMaxFastElementsLength = 5000; |
static const int kInitialMaxFastElementArray = 100000; |
@@ -1637,6 +1641,13 @@ class FixedArray: public Array { |
// Align data at kPointerSize, even if Array.kHeaderSize isn't aligned. |
static const int kHeaderSize = POINTER_SIZE_ALIGN(Array::kHeaderSize); |
+ // Maximal allowed size, in bytes, of a single FixedArray. |
+ // Prevents overflowing size computations, as well as extreme memory |
+ // consumption. |
+ static const int kMaxSize = 256 * MB; |
+ // Maximally allowed length of a FixedArray. |
+ static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; |
+ |
// Dispatched behavior. |
int FixedArraySize() { return SizeFor(length()); } |
void FixedArrayIterateBody(ObjectVisitor* v); |
@@ -1948,6 +1959,12 @@ class HashTable: public FixedArray { |
// Constant used for denoting a absent entry. |
static const int kNotFound = -1; |
+ // Maximal capacity of HashTable. Based on maximal length of underlying |
+ // FixedArray. Staying below kMaxCapacity also ensures that EntryToIndex |
+ // cannot overflow. |
+ static const int kMaxCapacity = |
+ (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize; |
+ |
// Find entry for key otherwise return -1. |
int FindEntry(Key key); |
@@ -1978,6 +1995,7 @@ class HashTable: public FixedArray { |
// use bit-wise AND with a mask, so the capacity must be positive |
// and non-zero. |
ASSERT(capacity > 0); |
+ ASSERT(capacity <= kMaxCapacity); |
fast_set(this, kCapacityIndex, Smi::FromInt(capacity)); |
} |
@@ -2317,6 +2335,11 @@ class ByteArray: public Array { |
static const int kHeaderSize = Array::kHeaderSize; |
static const int kAlignedSize = Array::kAlignedSize; |
+ // Maximal memory consumption for a single ByteArray. |
+ static const int kMaxSize = 512 * MB; |
+ // Maximal length of a single ByteArray. |
+ static const int kMaxLength = kMaxSize - kHeaderSize; |
+ |
private: |
DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray); |
}; |
@@ -4026,6 +4049,12 @@ class SeqAsciiString: public SeqString { |
static const int kHeaderSize = String::kSize; |
static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); |
+ // Maximal memory usage for a single sequential ASCII string. |
+ static const int kMaxSize = 512 * MB; |
+ // Maximal length of a single sequential ASCII string. |
+ // Q.v. String::kMaxLength which is the maximal size of concatenated strings. |
+ static const int kMaxLength = (kMaxSize - kHeaderSize); |
+ |
// Support for StringInputBuffer. |
inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, |
unsigned* offset, |
@@ -4072,6 +4101,12 @@ class SeqTwoByteString: public SeqString { |
static const int kHeaderSize = String::kSize; |
static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); |
+ // Maximal memory usage for a single sequential two-byte string. |
+ static const int kMaxSize = 512 * MB; |
+ // Maximal length of a single sequential two-byte string. |
+ // Q.v. String::kMaxLength which is the maximal size of concatenated strings. |
+ static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t); |
+ |
// Support for StringInputBuffer. |
inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, |
unsigned* offset_ptr, |