diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-01-13 10:41:48 +0100 |
---|---|---|
committer | Jamey Hicks <jamey.hicks@nokia.com> | 2012-01-13 11:28:20 +0100 |
commit | f2ee3e1cf3978408813a3d61bdd30519281887db (patch) | |
tree | 400852fe585415e2198a333f9d83bd5e097760af /src | |
parent | bddfa69a149970c630750cd9fb7d8bf44babf83f (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.cpp | 17 | ||||
-rw-r--r-- | src/qjson_p.h | 2 | ||||
-rw-r--r-- | src/qjsonarray.cpp | 4 | ||||
-rw-r--r-- | src/qjsonobject.cpp | 6 |
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; |