QCborArray: allow large but in-range keys
The 0x10000 limit should not apply if the key is a valid index in the array. Change-Id: I5e52dc5b093c43a3b678fffd16b6a2a5a69acd61 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
800f60657d
commit
3531f578d3
@ -2215,6 +2215,21 @@ const QCborValue QCborValue::operator[](qint64 key) const
|
|||||||
return QCborValue();
|
return QCborValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool shouldArrayRemainArray(qint64 key, QCborValue::Type t, QCborContainerPrivate *container)
|
||||||
|
{
|
||||||
|
constexpr qint64 LargeKey = 0x10000;
|
||||||
|
if (t != QCborValue::Array)
|
||||||
|
return false;
|
||||||
|
if (key < 0)
|
||||||
|
return false; // negative keys can't be an array index
|
||||||
|
if (key < LargeKey)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Only convert to map if key is greater than array size + 1
|
||||||
|
qsizetype currentSize = container ? container->elements.size() : 0;
|
||||||
|
return key <= currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
@ -2369,7 +2384,7 @@ QCborValueRef QCborValue::operator[](QLatin1String key)
|
|||||||
*/
|
*/
|
||||||
QCborValueRef QCborValue::operator[](qint64 key)
|
QCborValueRef QCborValue::operator[](qint64 key)
|
||||||
{
|
{
|
||||||
if (isArray() && key >= 0 && key < 0x10000) {
|
if (shouldArrayRemainArray(key, t, container)) {
|
||||||
container = maybeGrow(container, key);
|
container = maybeGrow(container, key);
|
||||||
return { container, qsizetype(key) };
|
return { container, qsizetype(key) };
|
||||||
}
|
}
|
||||||
@ -2898,7 +2913,7 @@ QCborValueRef QCborValueRef::operator[](QLatin1String key)
|
|||||||
QCborValueRef QCborValueRef::operator[](qint64 key)
|
QCborValueRef QCborValueRef::operator[](qint64 key)
|
||||||
{
|
{
|
||||||
auto &e = d->elements[i];
|
auto &e = d->elements[i];
|
||||||
if (e.type == QCborValue::Array && key >= 0 && key < 0x10000) {
|
if (shouldArrayRemainArray(key, e.type, e.container)) {
|
||||||
e.container = maybeGrow(e.container, key);
|
e.container = maybeGrow(e.container, key);
|
||||||
e.flags |= QtCbor::Element::IsContainer;
|
e.flags |= QtCbor::Element::IsContainer;
|
||||||
return { e.container, qsizetype(key) };
|
return { e.container, qsizetype(key) };
|
||||||
|
@ -74,6 +74,7 @@ private slots:
|
|||||||
void arrayPrepend();
|
void arrayPrepend();
|
||||||
void arrayValueRef_data() { basics_data(); }
|
void arrayValueRef_data() { basics_data(); }
|
||||||
void arrayValueRef();
|
void arrayValueRef();
|
||||||
|
void arrayValueRefLargeKey();
|
||||||
void arrayInsertRemove_data() { basics_data(); }
|
void arrayInsertRemove_data() { basics_data(); }
|
||||||
void arrayInsertRemove();
|
void arrayInsertRemove();
|
||||||
void arrayInsertTagged_data() { basics_data(); }
|
void arrayInsertTagged_data() { basics_data(); }
|
||||||
@ -1320,6 +1321,30 @@ void tst_QCborValue::arrayValueRef()
|
|||||||
iteratorCheck(a.constBegin());
|
iteratorCheck(a.constBegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QCborValue::arrayValueRefLargeKey()
|
||||||
|
{
|
||||||
|
// make sure the access via QCborValue & QCborValueRef don't convert this
|
||||||
|
// array to a map
|
||||||
|
constexpr qsizetype LargeKey = 0x10000;
|
||||||
|
QCborArray a;
|
||||||
|
a[LargeKey + 1] = 123;
|
||||||
|
|
||||||
|
QCborValue v(a);
|
||||||
|
QCOMPARE(qAsConst(v)[LargeKey], QCborValue());
|
||||||
|
QCOMPARE(qAsConst(v)[LargeKey + 1], 123);
|
||||||
|
QCOMPARE(v[LargeKey], QCborValue());
|
||||||
|
QCOMPARE(v[LargeKey + 1], 123);
|
||||||
|
QCOMPARE(v.type(), QCborValue::Array);
|
||||||
|
|
||||||
|
QCborArray outer = { QCborValue(a) };
|
||||||
|
QCborValueRef ref = outer[0];
|
||||||
|
QCOMPARE(qAsConst(ref)[LargeKey], QCborValue());
|
||||||
|
QCOMPARE(qAsConst(ref)[LargeKey + 1], 123);
|
||||||
|
QCOMPARE(ref[LargeKey], QCborValue());
|
||||||
|
QCOMPARE(ref[LargeKey + 1], 123);
|
||||||
|
QCOMPARE(ref.type(), QCborValue::Array);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QCborValue::mapValueRef()
|
void tst_QCborValue::mapValueRef()
|
||||||
{
|
{
|
||||||
QFETCH(QCborValue, v);
|
QFETCH(QCborValue, v);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user