summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qsettings.cpp
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2016-10-03 18:41:30 +0200
committerTor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>2016-10-05 11:57:41 +0000
commit764f5bf48cc87f4c72550b853ab93b815454cd48 (patch)
treeed8b076c842572290624e049993333dd17a11c72 /src/corelib/io/qsettings.cpp
parent483aff406a8cd9bb824cbd39a0a20619fe9b1fa2 (diff)
Apple OS: Handle QSetting strings with embedded zero-bytes
Saving strings with embedded zero-bytes (\0) as CFStrings would sometimes fail, and only write the part of the string leading up to the first zero-byte, instead of all the way to the final zero-terminator. This bug was revealed by the code-path that falls back to storing e.g. QTime as strings, via the helper method QSettingsPrivate::variantToString(). We now use the same approach as on platforms such as Windows and WinRT, where the string produced by variantToString() is checked for null-bytes, and if so, stored using a binary representation instead of as a string. For our case that means we fall back to CFData when detecting the null-byte. To separate strings from regular byte arrays, new logic has been added to variantToString() that wraps the null-byte strings in @String(). That way we can implement a fast-path when converting back from CFData, that doesn't go via the slow and lossy conversion via UTF8, and the resulting QVariant will be of type QVariant::ByteArray. The reason for using UTF-8 as the binary representation of the string is that in the case of storing a QByteArray("@foo") we need to still be able to convert it back to the same byte array, which doesn't work if the on-disk format is UTF-16. Task-number: QTBUG-56124 Change-Id: Iab2f71cf96cf3225de48dc5e71870d74b6dde1e8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io/qsettings.cpp')
-rw-r--r--src/corelib/io/qsettings.cpp6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index fcdc1e362b..47108d057b 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -416,7 +416,9 @@ QString QSettingsPrivate::variantToString(const QVariant &v)
case QVariant::Double:
case QVariant::KeySequence: {
result = v.toString();
- if (result.startsWith(QLatin1Char('@')))
+ if (result.contains(QChar::Null))
+ result = QLatin1String("@String(") + result + QLatin1Char(')');
+ else if (result.startsWith(QLatin1Char('@')))
result.prepend(QLatin1Char('@'));
break;
}
@@ -476,6 +478,8 @@ QVariant QSettingsPrivate::stringToVariant(const QString &s)
if (s.endsWith(QLatin1Char(')'))) {
if (s.startsWith(QLatin1String("@ByteArray("))) {
return QVariant(s.midRef(11, s.size() - 12).toLatin1());
+ } else if (s.startsWith(QLatin1String("@String("))) {
+ return QVariant(s.midRef(8, s.size() - 9).toString());
} else if (s.startsWith(QLatin1String("@Variant("))
|| s.startsWith(QLatin1String("@DateTime("))) {
#ifndef QT_NO_DATASTREAM