Fix crash in sparse array handling

When re-allocating the sparse array data, make sure to initialize the free list
correctly. Previously this was only done for the first allocation.

Test cases uses an object literal, as that's a reliable way to ensure
a sparse array is created.

Task-number: QTBUG-37892
Change-Id: Ib38cfce50104904af0c980f022c9dbb7461ae5f8
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Simon Hausmann 2014-03-28 14:12:41 +01:00 committed by The Qt Project
parent 910542eb9e
commit 6bbd173a9c
2 changed files with 15 additions and 13 deletions

View File

@ -156,21 +156,22 @@ void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool e
newData->sparse = old->sparse;
old->sparse = 0;
newData->freeList = old->freeList;
return;
}
newData->sparse = new SparseArray;
uint *lastFree = &newData->freeList;
for (uint i = 0; i < toCopy; ++i) {
if (!newData->data[i].isEmpty()) {
SparseArrayNode *n = newData->sparse->insert(i);
n->value = i;
} else {
*lastFree = i;
newData->data[i].tag = Value::Empty_Type;
lastFree = &newData->data[i].uint_32;
} else {
newData->sparse = new SparseArray;
uint *lastFree = &newData->freeList;
for (uint i = 0; i < toCopy; ++i) {
if (!newData->data[i].isEmpty()) {
SparseArrayNode *n = newData->sparse->insert(i);
n->value = i;
} else {
*lastFree = i;
newData->data[i].tag = Value::Empty_Type;
lastFree = &newData->data[i].uint_32;
}
}
}
uint *lastFree = &newData->freeList;
for (uint i = toCopy; i < newData->alloc; ++i) {
*lastFree = i;
newData->data[i].tag = Value::Empty_Type;

View File

@ -1033,6 +1033,7 @@ void tst_QJSEngine::evaluate_data()
QTest::newRow("/a/gim") << QString("/a/gim") << -1 << false << -1;
QTest::newRow("/a/gimp") << QString("/a/gimp") << 1 << true << 1;
QTest::newRow("empty-array-concat") << QString("var a = []; var b = [1]; var c = a.concat(b); ") << 1 << false << -1;
QTest::newRow("object-literal") << QString("var a = {\"0\":\"#\",\"2\":\"#\",\"5\":\"#\",\"8\":\"#\",\"6\":\"#\",\"12\":\"#\",\"13\":\"#\",\"16\":\"#\",\"18\":\"#\",\"39\":\"#\",\"40\":\"#\"}") << 1 << false << -1;
}
void tst_QJSEngine::evaluate()