summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qsettings.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2022-02-24 15:43:23 +0100
committerIvan Solovev <ivan.solovev@qt.io>2022-03-02 11:13:33 +0100
commit6e9a3d420935ab67372edb8ef7bb7ca0b65517ac (patch)
treec2940efc3095a1842398af6fdedf9ba81a7446b0 /src/corelib/io/qsettings.cpp
parentdfe66019748920f5af0e143b18304a64b6f8ee6c (diff)
QSettings: support reading UTF-8 keys in INI files
[ChangeLog][QtCore][QSettings] The INI file reader now supports keys encoded with UTF-8, as well as the %-encoded format. Writing the keys back to the INI file is still done using %-encoded format. This change does not touch the way the *values* are handled - they are both read and written in UTF-8. Drive-by: remove misleading comments from the reading algorithm. Task-number: QTBUG-99401 Change-Id: I6a83cbf24d919a499540403688615f93cb195e93 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/io/qsettings.cpp')
-rw-r--r--src/corelib/io/qsettings.cpp32
1 files changed, 18 insertions, 14 deletions
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 34f07096eb..fc31eca5de 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -545,11 +545,13 @@ void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result)
bool QSettingsPrivate::iniUnescapedKey(const QByteArray &key, int from, int to, QString &result)
{
+ const QString decoded = QString::fromUtf8(QByteArrayView(key).sliced(from, to - from));
+ const qsizetype size = decoded.size();
+ result.reserve(result.length() + size);
+ qsizetype i = 0;
bool lowercaseOnly = true;
- int i = from;
- result.reserve(result.length() + (to - from));
- while (i < to) {
- char16_t ch = (uchar)key.at(i);
+ while (i < size) {
+ char16_t ch = decoded.at(i).unicode();
if (ch == '\\') {
result += QLatin1Char('/');
@@ -557,10 +559,11 @@ bool QSettingsPrivate::iniUnescapedKey(const QByteArray &key, int from, int to,
continue;
}
- if (ch != '%' || i == to - 1) {
- if (uint(ch - 'A') <= 'Z' - 'A') // only for ASCII
+ if (ch != '%' || i == size - 1) {
+ QChar qch(ch);
+ if (qch.isUpper())
lowercaseOnly = false;
- result += ch;
+ result += qch;
++i;
continue;
}
@@ -568,24 +571,22 @@ bool QSettingsPrivate::iniUnescapedKey(const QByteArray &key, int from, int to,
int numDigits = 2;
int firstDigitPos = i + 1;
- ch = key.at(i + 1);
+ ch = decoded.at(i + 1).unicode();
if (ch == 'U') {
++firstDigitPos;
numDigits = 4;
}
- if (firstDigitPos + numDigits > to) {
+ if (firstDigitPos + numDigits > size) {
result += QLatin1Char('%');
- // ### missing U
++i;
continue;
}
bool ok;
- ch = key.mid(firstDigitPos, numDigits).toUShort(&ok, 16);
+ ch = QStringView(decoded).sliced(firstDigitPos, numDigits).toUShort(&ok, 16);
if (!ok) {
result += QLatin1Char('%');
- // ### missing U
++i;
continue;
}
@@ -2427,9 +2428,12 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
such as "General/someKey", the key will be located in the
"%General" section, \e not in the "General" section.
- \li In line with most implementations today, QSettings will
- assume the INI file is utf-8 encoded. This means that keys and values
+ \li In line with most implementations today, QSettings will assume that
+ \e values in the INI file are utf-8 encoded. This means that \e values
will be decoded as utf-8 encoded entries and written back as utf-8.
+ To retain backward compatibility with older Qt versions, \e keys in the
+ INI file are written in %-encoded format, but can be read in both
+ %-encoded and utf-8 formats.
\endlist