macOS: Don't mangle QByteArray settings with @ prefix by decoding as UTF-8

QSettings encodes QVariants as @Type(data) strings. If that data contains
a null-byte, we write the string as UTF-8 encoded CFData. When reading it
back we look for a @ prefix, and then pass it as UTF-8 through stringToVariant.

The problem arises then the user writes raw QByteArrays with a @ prefix.
We can detect this situation by checking the result of stringToVariant,
and if it's just a simple conversion of the string into a QVariant, we
know that stringToVariant hit its fallback path due to not finding any
embedded variants.

If that's the case, we return the raw bytes as a QByteArray.

Pick-to: 6.2 6.1 5.15 5.12
Change-Id: I4ac5c35d0a6890ebea983b9aca0a3a36b0143de2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Tor Arne Vestbø 2021-07-12 13:29:17 +02:00
parent c0b7d834b0
commit 3eac6079d9
2 changed files with 13 additions and 1 deletions

View File

@ -247,7 +247,15 @@ static QVariant qtValue(CFPropertyListRef cfvalue)
}
const QString str = QString::fromUtf8(byteArray.constData(), byteArray.size());
return QSettingsPrivate::stringToVariant(str);
QVariant variant = QSettingsPrivate::stringToVariant(str);
if (variant == QVariant(str)) {
// We did not find an encoded variant in the string,
// so return the raw byte array instead.
byteArray.detach();
return byteArray;
}
return variant;
} else if (typeId == CFDictionaryGetTypeID()) {
CFDictionaryRef cfdict = static_cast<CFDictionaryRef>(cfvalue);
CFTypeID arrayTypeId = CFArrayGetTypeID();

View File

@ -711,6 +711,10 @@ void tst_QSettings::embeddedZeroByte_data()
QTest::newRow("@bytearray\\0") << QVariant(bytes);
QTest::newRow("@string\\0") << QVariant(QString::fromLatin1(bytes.data(), bytes.size()));
bytes = QByteArray("@\xdd\x7d", 3);
QTest::newRow("@-prefixed data") << QVariant(bytes);
QTest::newRow("@-prefixed data as string") << QVariant(QString::fromLatin1(bytes.data(), bytes.size()));
}
void tst_QSettings::embeddedZeroByte()