mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 678362 - HashTable should not require callers to bounds-check initial capacity (r=waldo)
--HG-- extra : rebase_source : d0bb0faa097cd04b5be0644f17a37fb96aaffc2d
This commit is contained in:
parent
82d1f93fca
commit
82b532273f
@ -298,7 +298,8 @@ class HashTable : private AllocPolicy
|
||||
|
||||
static const unsigned sMinSizeLog2 = 4;
|
||||
static const unsigned sMinSize = 1 << sMinSizeLog2;
|
||||
static const unsigned sSizeLimit = JS_BIT(24);
|
||||
static const unsigned sMaxInit = JS_BIT(23);
|
||||
static const unsigned sMaxCapacity = JS_BIT(24);
|
||||
static const unsigned sHashBits = tl::BitSize<HashNumber>::result;
|
||||
static const uint8 sMinAlphaFrac = 64; /* (0x100 * .25) taken from jsdhash.h */
|
||||
static const uint8 sMaxAlphaFrac = 192; /* (0x100 * .75) taken from jsdhash.h */
|
||||
@ -308,6 +309,14 @@ class HashTable : private AllocPolicy
|
||||
static const HashNumber sRemovedKey = Entry::sRemovedKey;
|
||||
static const HashNumber sCollisionBit = Entry::sCollisionBit;
|
||||
|
||||
static void staticAsserts()
|
||||
{
|
||||
/* Rely on compiler "constant overflow warnings". */
|
||||
JS_STATIC_ASSERT(((sMaxInit * sInvMaxAlpha) >> 7) < sMaxCapacity);
|
||||
JS_STATIC_ASSERT((sMaxCapacity * sInvMaxAlpha) <= UINT32_MAX);
|
||||
JS_STATIC_ASSERT((sMaxCapacity * sizeof(Entry)) <= UINT32_MAX);
|
||||
}
|
||||
|
||||
static bool isLiveHash(HashNumber hash)
|
||||
{
|
||||
return Entry::isLiveHash(hash);
|
||||
@ -365,7 +374,10 @@ class HashTable : private AllocPolicy
|
||||
* Correct for sMaxAlphaFrac such that the table will not resize
|
||||
* when adding 'length' entries.
|
||||
*/
|
||||
JS_ASSERT(length < (uint32(1) << 23));
|
||||
if (length > sMaxInit) {
|
||||
this->reportAllocOverflow();
|
||||
return false;
|
||||
}
|
||||
uint32 capacity = (length * sInvMaxAlpha) >> 7;
|
||||
|
||||
if (capacity < sMinSize)
|
||||
@ -379,10 +391,7 @@ class HashTable : private AllocPolicy
|
||||
}
|
||||
|
||||
capacity = roundUp;
|
||||
if (capacity >= sSizeLimit) {
|
||||
this->reportAllocOverflow();
|
||||
return false;
|
||||
}
|
||||
JS_ASSERT(capacity <= sMaxCapacity);
|
||||
|
||||
table = createTable(*this, capacity);
|
||||
if (!table)
|
||||
@ -536,7 +545,7 @@ class HashTable : private AllocPolicy
|
||||
uint32 oldCap = tableCapacity;
|
||||
uint32 newLog2 = sHashBits - hashShift + deltaLog2;
|
||||
uint32 newCapacity = JS_BIT(newLog2);
|
||||
if (newCapacity >= sSizeLimit) {
|
||||
if (newCapacity > sMaxCapacity) {
|
||||
this->reportAllocOverflow();
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var r1 = [0, 1, 2, 3];
|
||||
Object.defineProperty(r1, (1 << 23) - 1, {});
|
||||
JSON.stringify({ 0: 0, 1: 1, 2: 2, 3: 3 }, r1)
|
||||
|
||||
var r2 = [0, 1, 2, 3];
|
||||
Object.defineProperty(r2, (1 << 30), {});
|
||||
try
|
||||
{
|
||||
JSON.stringify({ 0: 0, 1: 1, 2: 2, 3: 3 }, r2)
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
assertEq(""+e, "InternalError: allocation size overflow");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
@ -16,6 +16,7 @@ script extension-methods-reject-null-undefined-this.js
|
||||
skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate()
|
||||
script function-properties.js
|
||||
script iterator-in-catch.js
|
||||
script JSON-string-replacer-overflow.js
|
||||
skip-if(!xulRuntime.shell) script legacy-JSON.js # needs parseLegacyJSON
|
||||
fails script nested-delete-name-in-evalcode.js # bug 604301, at a minimum
|
||||
script proxy-strict.js
|
||||
|
Loading…
Reference in New Issue
Block a user