QCborValue: fix incorrect to{Array,Map} when the value is empty

When QCborValue referred to an empty array or map, toArray() and toMap()
would respectively return the default value instead of the empty object,
as expected.

Pick-to: 6.2 6.3
Change-Id: I5e52dc5b093c43a3b678fffd16b60456d0037ad7
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
bb10
Thiago Macieira 2021-11-09 15:24:45 -08:00
parent 1e62f08998
commit de6ced6692
2 changed files with 91 additions and 2 deletions

View File

@ -2108,7 +2108,8 @@ QCborArray QCborValue::toArray(const QCborArray &defaultValue) const
Q_ASSERT(n == -1 || container == nullptr);
if (n < 0)
dd = container;
return dd ? QCborArray(*dd) : defaultValue;
// return QCborArray(*dd); but that's UB if dd is nullptr
return dd ? QCborArray(*dd) : QCborArray();
}
/*!
@ -2150,7 +2151,8 @@ QCborMap QCborValue::toMap(const QCborMap &defaultValue) const
Q_ASSERT(n == -1 || container == nullptr);
if (n < 0)
dd = container;
return dd ? QCborMap(*dd) : defaultValue;
// return QCborMap(*dd); but that's UB if dd is nullptr
return dd ? QCborMap(*dd) : QCborMap();
}
/*!

View File

@ -79,6 +79,7 @@ private slots:
void arrayStringElements();
void arraySelfAssign_data() { basics_data(); }
void arraySelfAssign();
void arrayNested();
void mapDefaultInitialization();
void mapEmptyInitializerList();
@ -97,6 +98,7 @@ private slots:
void mapSelfAssign();
void mapComplexKeys_data() { basics_data(); }
void mapComplexKeys();
void mapNested();
void sorting();
@ -1581,6 +1583,91 @@ void tst_QCborValue::mapComplexKeys()
QVERIFY(!m.contains(tagged));
}
void tst_QCborValue::arrayNested()
{
const QCborArray wrongArray = { false, nullptr, QCborValue() };
{
QCborArray a1 = { 42, 47 };
QCborArray a2 = { QCborValue(a1) };
QCOMPARE(a2.size(), 1);
const QCborValue &first = qAsConst(a2).first();
QVERIFY(first.isArray());
QCOMPARE(first.toArray(wrongArray).size(), 2);
QCOMPARE(first.toArray(wrongArray).first(), 42);
QCOMPARE(first.toArray(wrongArray).last(), 47);
}
{
QCborArray a1 = { 42, 47 };
QCborArray a2 = { QCborValue(a1) };
QCOMPARE(a2.size(), 1);
QCborValueRef first = a2.first();
QVERIFY(first.isArray());
QCOMPARE(first.toArray(wrongArray).size(), 2);
QCOMPARE(first.toArray(wrongArray).first(), 42);
QCOMPARE(first.toArray(wrongArray).last(), 47);
}
{
QCborArray a1;
a1 = { QCborValue(a1) }; // insert it into itself
QCOMPARE(a1.size(), 1);
const QCborValue &first = qAsConst(a1).first();
QVERIFY(first.isArray());
QCOMPARE(first, QCborArray());
QCOMPARE(first.toArray(wrongArray), QCborArray());
}
{
QCborArray a1;
a1 = { QCborValue(a1) }; // insert it into itself
QCborValueRef first = a1.first();
QVERIFY(first.isArray());
QCOMPARE(first, QCborArray());
QCOMPARE(first.toArray(wrongArray), QCborArray());
}
{
QCborArray a1;
a1.append(a1); // insert into itself
QCOMPARE(a1.size(), 1);
const QCborValue &first = qAsConst(a1).first();
QVERIFY(first.isArray());
QCOMPARE(first, QCborArray());
QCOMPARE(first.toArray(), QCborArray());
}
{
QCborArray a1;
a1.append(a1); // insert into itself
QCborValueRef first = a1.first();
QVERIFY(first.isArray());
QCOMPARE(first, QCborArray());
QCOMPARE(first.toArray(), QCborArray());
}
}
void tst_QCborValue::mapNested()
{
const QCborMap wrongMap = { { -1, false }, {-2, nullptr }, { -3, QCborValue() } };
{
QCborMap m1 = { {1, 42}, {2, 47} };
QCborMap m2 = { { QString(), m1 } };
QCOMPARE(m2.size(), 1);
const QCborValue &first = m2.constBegin().value();
QVERIFY(first.isMap());
QCOMPARE(first.toMap(wrongMap).size(), 2);
QCOMPARE(first.toMap(wrongMap).begin().key(), 1);
QCOMPARE(first.toMap(wrongMap).begin().value(), 42);
}
{
QCborMap m1;
m1 = { { QString(), QCborValue(m1) } }; // insert it into itself
QCOMPARE(m1.size(), 1);
const QCborValue &first = m1.constBegin().value();
QVERIFY(first.isMap());
QCOMPARE(first, QCborMap());
QCOMPARE(first.toMap(wrongMap), QCborMap());
}
}
void tst_QCborValue::sorting()
{
QCborValue vundef, vnull(nullptr);