зеркало из https://github.com/mozilla/pjs.git
Bug 615147. r=dbaron a=blocking2.0:final
This commit is contained in:
Родитель
6359a7cbf9
Коммит
3f6003cc53
|
@ -201,6 +201,9 @@ nsStringBuffer*
|
|||
nsStringBuffer::Alloc(size_t size)
|
||||
{
|
||||
NS_ASSERTION(size != 0, "zero capacity allocation not allowed");
|
||||
NS_ASSERTION(sizeof(nsStringBuffer) + size <= size_t(PRUint32(-1)) &&
|
||||
sizeof(nsStringBuffer) + size > size,
|
||||
"mStorageSize will truncate");
|
||||
|
||||
nsStringBuffer *hdr =
|
||||
(nsStringBuffer *) malloc(sizeof(nsStringBuffer) + size);
|
||||
|
@ -221,12 +224,15 @@ nsStringBuffer::Realloc(nsStringBuffer* hdr, size_t size)
|
|||
STRING_STAT_INCREMENT(Realloc);
|
||||
|
||||
NS_ASSERTION(size != 0, "zero capacity allocation not allowed");
|
||||
NS_ASSERTION(sizeof(nsStringBuffer) + size <= size_t(PRUint32(-1)) &&
|
||||
sizeof(nsStringBuffer) + size > size,
|
||||
"mStorageSize will truncate");
|
||||
|
||||
// no point in trying to save ourselves if we hit this assertion
|
||||
NS_ASSERTION(!hdr->IsReadonly(), "|Realloc| attempted on readonly string");
|
||||
|
||||
// Treat this as a release and addref for refcounting purposes, since we
|
||||
// just asserted that the refcound is 1. If we don't do that, refcount
|
||||
// just asserted that the refcount is 1. If we don't do that, refcount
|
||||
// logging will claim we've leaked all sorts of stuff.
|
||||
NS_LOG_RELEASE(hdr, 0, "nsStringBuffer");
|
||||
|
||||
|
|
|
@ -79,10 +79,13 @@ nsTSubstring_CharT::MutatePrep( size_type capacity, char_type** oldData, PRUint3
|
|||
|
||||
size_type curCapacity = Capacity();
|
||||
|
||||
// If |capacity > size_type(-1)/2|, then our doubling algorithm may not be
|
||||
// If |capacity > kMaxCapacity|, then our doubling algorithm may not be
|
||||
// able to allocate it. Just bail out in cases like that. We don't want
|
||||
// to be allocating 2GB+ strings anyway.
|
||||
if (capacity > size_type(-1)/2) {
|
||||
PR_STATIC_ASSERT((sizeof(nsStringBuffer) & 0x1) == 0);
|
||||
const size_type kMaxCapacity =
|
||||
(size_type(-1)/2 - sizeof(nsStringBuffer)) / sizeof(char_type) - 2;
|
||||
if (capacity > kMaxCapacity) {
|
||||
// Also assert for |capacity| equal to |size_type(-1)|, since we used to
|
||||
// use that value to flag immutability.
|
||||
NS_ASSERTION(capacity != size_type(-1), "Bogus capacity");
|
||||
|
@ -100,15 +103,13 @@ nsTSubstring_CharT::MutatePrep( size_type capacity, char_type** oldData, PRUint3
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (curCapacity > 0)
|
||||
{
|
||||
// use doubling algorithm when forced to increase available
|
||||
// capacity.
|
||||
PRUint32 temp = curCapacity;
|
||||
while (temp < capacity)
|
||||
temp <<= 1;
|
||||
capacity = temp;
|
||||
}
|
||||
// Use doubling algorithm when forced to increase available capacity.
|
||||
size_type temp = curCapacity;
|
||||
while (temp < capacity)
|
||||
temp <<= 1;
|
||||
NS_ASSERTION(NS_MIN(temp, kMaxCapacity) >= capacity,
|
||||
"should have hit the early return at the top");
|
||||
capacity = NS_MIN(temp, kMaxCapacity);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -1069,6 +1069,92 @@ static PRBool test_strip_chars()
|
|||
NS_LITERAL_STRING(" foo"), 1);
|
||||
}
|
||||
|
||||
static PRBool test_huge_capacity()
|
||||
{
|
||||
nsString a, b, c, d, e, f, g, h, i, j, k, l, m, n;
|
||||
nsCString n1;
|
||||
PRBool fail = PR_FALSE;
|
||||
#undef ok
|
||||
#define ok(x) { fail |= !(x); }
|
||||
|
||||
ok(a.SetCapacity(1));
|
||||
ok(!a.SetCapacity(nsString::size_type(-1)/2));
|
||||
ok(a.SetCapacity(0)); // free the allocated memory
|
||||
|
||||
ok(b.SetCapacity(1));
|
||||
ok(!b.SetCapacity(nsString::size_type(-1)/2 - 1));
|
||||
ok(b.SetCapacity(0));
|
||||
|
||||
ok(c.SetCapacity(1));
|
||||
ok(!c.SetCapacity(nsString::size_type(-1)/2));
|
||||
ok(c.SetCapacity(0));
|
||||
|
||||
ok(!d.SetCapacity(nsString::size_type(-1)/2 - 1));
|
||||
ok(!d.SetCapacity(nsString::size_type(-1)/2));
|
||||
ok(d.SetCapacity(0));
|
||||
|
||||
ok(!e.SetCapacity(nsString::size_type(-1)/4));
|
||||
ok(!e.SetCapacity(nsString::size_type(-1)/4 + 1));
|
||||
ok(e.SetCapacity(0));
|
||||
|
||||
ok(!f.SetCapacity(nsString::size_type(-1)/2));
|
||||
ok(f.SetCapacity(0));
|
||||
|
||||
ok(!g.SetCapacity(nsString::size_type(-1)/4 + 1000));
|
||||
ok(!g.SetCapacity(nsString::size_type(-1)/4 + 1001));
|
||||
ok(g.SetCapacity(0));
|
||||
|
||||
ok(!h.SetCapacity(nsString::size_type(-1)/4+1));
|
||||
ok(!h.SetCapacity(nsString::size_type(-1)/2));
|
||||
ok(h.SetCapacity(0));
|
||||
|
||||
ok(i.SetCapacity(1));
|
||||
ok(i.SetCapacity(nsString::size_type(-1)/4 - 1000));
|
||||
ok(!i.SetCapacity(nsString::size_type(-1)/4 + 1));
|
||||
ok(i.SetCapacity(0));
|
||||
|
||||
ok(j.SetCapacity(nsString::size_type(-1)/4 - 1000));
|
||||
ok(!j.SetCapacity(nsString::size_type(-1)/4 + 1));
|
||||
ok(j.SetCapacity(0));
|
||||
|
||||
ok(k.SetCapacity(nsString::size_type(-1)/8 - 1000));
|
||||
ok(k.SetCapacity(nsString::size_type(-1)/4 - 1001));
|
||||
ok(k.SetCapacity(nsString::size_type(-1)/4 - 998));
|
||||
ok(!k.SetCapacity(nsString::size_type(-1)/4 + 1));
|
||||
ok(k.SetCapacity(0));
|
||||
|
||||
ok(l.SetCapacity(nsString::size_type(-1)/8));
|
||||
ok(l.SetCapacity(nsString::size_type(-1)/8 + 1));
|
||||
ok(l.SetCapacity(nsString::size_type(-1)/8 + 2));
|
||||
ok(l.SetCapacity(0));
|
||||
|
||||
ok(m.SetCapacity(nsString::size_type(-1)/8 + 1000));
|
||||
ok(m.SetCapacity(nsString::size_type(-1)/8 + 1001));
|
||||
ok(m.SetCapacity(0));
|
||||
|
||||
ok(n.SetCapacity(nsString::size_type(-1)/8+1));
|
||||
ok(!n.SetCapacity(nsString::size_type(-1)/4));
|
||||
ok(n.SetCapacity(0));
|
||||
|
||||
ok(n.SetCapacity(0));
|
||||
ok(n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 2));
|
||||
ok(n.SetCapacity(0));
|
||||
ok(!n.SetCapacity((nsString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 2 - 1));
|
||||
ok(n.SetCapacity(0));
|
||||
ok(n1.SetCapacity(0));
|
||||
ok(n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 2));
|
||||
ok(n1.SetCapacity(0));
|
||||
ok(!n1.SetCapacity((nsCString::size_type(-1)/2 - sizeof(nsStringBuffer)) / 1 - 1));
|
||||
ok(n1.SetCapacity(0));
|
||||
|
||||
// Ignore the result if the address space is less than 64-bit because
|
||||
// some of the allocations above will exhaust the address space.
|
||||
if (sizeof(void*) >= 8) {
|
||||
return !fail;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//----
|
||||
|
||||
typedef PRBool (*TestFunc)();
|
||||
|
@ -1119,6 +1205,7 @@ tests[] =
|
|||
{ "test_string_tointeger", test_string_tointeger },
|
||||
{ "test_parse_string", test_parse_string },
|
||||
{ "test_strip_chars", test_strip_chars },
|
||||
{ "test_huge_capacity", test_huge_capacity },
|
||||
{ nsnull, nsnull }
|
||||
};
|
||||
|
||||
|
@ -1132,6 +1219,8 @@ int main(int argc, char **argv)
|
|||
if (argc > 1)
|
||||
count = atoi(argv[1]);
|
||||
|
||||
NS_LogInit();
|
||||
|
||||
while (count--)
|
||||
{
|
||||
for (const Test* t = tests; t->name != nsnull; ++t)
|
||||
|
|
Загрузка…
Ссылка в новой задаче