From b8dbde10a065c3ba95b794b6d53ff62e8ca22ee7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 30 Jan 2017 19:02:23 +0100 Subject: Fix data corruption when reading byte arrays from QSettings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS, the code that read the plist is using QByteArray::fromRawCFData. When we return the data directly we need to detach the QByteArray so that it does not point CFData's data that will get deallocated just after the call. Task-number: QTBUG-58531 Change-Id: If829a304b986c99c8fc2aeeb992f2d539a4eef3a Reviewed-by: Thiago Macieira Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qsettings_mac.cpp | 4 +++- tests/auto/corelib/io/qsettings/qsettings.qrc | 1 + tests/auto/corelib/io/qsettings/resourcefile6.plist | 10 ++++++++++ tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 11 +++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/auto/corelib/io/qsettings/resourcefile6.plist diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp index b79abfb874..0e3520441e 100644 --- a/src/corelib/io/qsettings_mac.cpp +++ b/src/corelib/io/qsettings_mac.cpp @@ -269,8 +269,10 @@ static QVariant qtValue(CFPropertyListRef cfvalue) // Fast-path for QByteArray, so that we don't have to go // though the expensive and lossy conversion via UTF-8. - if (!byteArray.startsWith('@')) + if (!byteArray.startsWith('@')) { + byteArray.detach(); return byteArray; + } const QString str = QString::fromUtf8(byteArray.constData(), byteArray.size()); return QSettingsPrivate::stringToVariant(str); diff --git a/tests/auto/corelib/io/qsettings/qsettings.qrc b/tests/auto/corelib/io/qsettings/qsettings.qrc index c0be7e013f..c664a6f68c 100644 --- a/tests/auto/corelib/io/qsettings/qsettings.qrc +++ b/tests/auto/corelib/io/qsettings/qsettings.qrc @@ -5,6 +5,7 @@ resourcefile3.ini resourcefile4.ini resourcefile5.ini + resourcefile6.plist bom.ini diff --git a/tests/auto/corelib/io/qsettings/resourcefile6.plist b/tests/auto/corelib/io/qsettings/resourcefile6.plist new file mode 100644 index 0000000000..6f994accac --- /dev/null +++ b/tests/auto/corelib/io/qsettings/resourcefile6.plist @@ -0,0 +1,10 @@ + + + + + passwordData + + RBxVAAsDVsO/ + + + diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index f94349fd02..199ab442c4 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -178,6 +178,7 @@ private slots: void testByteArray_data(); void testByteArray(); + void testByteArrayNativeFormat(); void iniCodec(); void bom(); void embeddedZeroByte_data(); @@ -670,6 +671,16 @@ void tst_QSettings::testByteArray() } } +void tst_QSettings::testByteArrayNativeFormat() +{ +#ifndef Q_OS_MACOS + QSKIP("This test is specific to macOS plist reading."); +#else + QSettings settings(":/resourcefile6.plist", QSettings::NativeFormat); + QCOMPARE(settings.value("passwordData"), QVariant(QByteArray::fromBase64("RBxVAAsDVsO/"))); +#endif +} + void tst_QSettings::iniCodec() { { -- cgit v1.2.3