summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-01-13 10:41:48 +0100
committerJamey Hicks <jamey.hicks@nokia.com>2012-01-13 11:28:20 +0100
commitf2ee3e1cf3978408813a3d61bdd30519281887db (patch)
tree400852fe585415e2198a333f9d83bd5e097760af /src
parentbddfa69a149970c630750cd9fb7d8bf44babf83f (diff)
Fix a corruption in the binary data
When replacing an existing Value in an object or array, we wrote that Value to the place where the old value lived. This caused the data to get corrupted in case the new value was larger than the old one. Change-Id: I0358c30124ae28c16a34a554fc7b24f279850428 Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jamey Hicks <jamey.hicks@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qjson.cpp17
-rw-r--r--src/qjson_p.h2
-rw-r--r--src/qjsonarray.cpp4
-rw-r--r--src/qjsonobject.cpp6
4 files changed, 18 insertions, 11 deletions
diff --git a/src/qjson.cpp b/src/qjson.cpp
index 41d0144..d36f5e2 100644
--- a/src/qjson.cpp
+++ b/src/qjson.cpp
@@ -141,19 +141,26 @@ void Data::validate()
}
-int Base::reserveSpace(uint dataSize, int posInTable, uint numItems)
+int Base::reserveSpace(uint dataSize, int posInTable, uint numItems, bool replace)
{
Q_ASSERT(posInTable >= 0 && posInTable <= (int)length);
offset off = tableOffset;
// move table to new position
- memmove((char *)(table() + posInTable + numItems) + dataSize, table() + posInTable, (length - posInTable)*sizeof(offset));
- memmove((char *)(table()) + dataSize, table(), posInTable*sizeof(offset));
+ if (replace) {
+ memmove((char *)(table()) + dataSize, table(), length*sizeof(offset));
+ } else {
+ memmove((char *)(table() + posInTable + numItems) + dataSize, table() + posInTable, (length - posInTable)*sizeof(offset));
+ memmove((char *)(table()) + dataSize, table(), posInTable*sizeof(offset));
+ }
tableOffset += dataSize;
for (int i = 0; i < (int)numItems; ++i)
table()[posInTable + i] = off;
- length += numItems;
- size += dataSize + numItems * sizeof(offset);
+ size += dataSize;
+ if (!replace) {
+ length += numItems;
+ size += numItems * sizeof(offset);
+ }
return off;
}
diff --git a/src/qjson_p.h b/src/qjson_p.h
index 96d135e..d96eb6a 100644
--- a/src/qjson_p.h
+++ b/src/qjson_p.h
@@ -413,7 +413,7 @@ struct Base
inline offset *table() const { return (offset *) (((char *) this) + tableOffset); }
- int reserveSpace(uint dataSize, int posInTable, uint numItems);
+ int reserveSpace(uint dataSize, int posInTable, uint numItems, bool replace);
void removeItems(int pos, int numItems);
};
diff --git a/src/qjsonarray.cpp b/src/qjsonarray.cpp
index 5385ca2..70c6d3c 100644
--- a/src/qjsonarray.cpp
+++ b/src/qjsonarray.cpp
@@ -201,7 +201,7 @@ void QJsonArray::insert(int i, const QJsonValue &value)
if (!a->length)
a->tableOffset = sizeof(Private::Array);
- int valueOffset = a->reserveSpace(valueSize, i, 1);
+ int valueOffset = a->reserveSpace(valueSize, i, 1, false);
Private::Value &v = (*a)[i];
v.type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
v.latinOrIntValue = compressed;
@@ -223,7 +223,7 @@ void QJsonArray::replace(int i, const QJsonValue &value)
if (!a->length)
a->tableOffset = sizeof(Private::Array);
- int valueOffset = a->reserveSpace(valueSize, i, 0);
+ int valueOffset = a->reserveSpace(valueSize, i, 1, true);
Private::Value &v = (*a)[i];
v.type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
v.latinOrIntValue = compressed;
diff --git a/src/qjsonobject.cpp b/src/qjsonobject.cpp
index a953d8e..d855eee 100644
--- a/src/qjsonobject.cpp
+++ b/src/qjsonobject.cpp
@@ -191,14 +191,14 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &
int pos = o->indexOf(key);
- int newIndex = 1;
+ bool replace = false;
if (pos >= 0) {
++d->compactionCounter;
- newIndex = 0;
+ replace = true;
} else {
pos = o->length;
}
- o->reserveSpace(requiredSize, pos, newIndex);
+ o->reserveSpace(requiredSize, pos, 1, replace);
Private::Entry *e = o->entryAt(pos);
e->value.type = value.t;