diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-07-31 14:55:57 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-08-29 18:15:27 +0200 |
commit | 78cf89c07d7fa834a455afa5862823e50171415c (patch) | |
tree | 4cd4fc6347c3df2771f49763231fb2d91b5582d9 /src/corelib/text/qstring.cpp | |
parent | ab5e444c8fd754321ef0a6b084248e431e84a7a8 (diff) |
Use checked string iteration in case conversions
The Unicode table code can only be safely called on valid code-points.
So code that calls it must only pass it valid Unicode data. The string
iterator's Unchecked Unchecked methods only provide this guarantee
when the string being iterated is guaranteed to be valid UTF-16; while
client code should only use QString, QStringView and friends on valid
UTF-16 data, we have no way to be sure they have respected that.
So take the few extra cycles to actually check validity in the course
of iterating strings, when the resulting code-points are to be passed
to the Unicode table look-ups. Add tests that case mapping doesn't
access Unicode tables out of range (it'll trigger the new assertion).
Added some comments to qchar.h that helped me understand surrogates.
Change-Id: Iec2c3106bf1a875bdaa1d622f6cf94d7007e281e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/text/qstring.cpp')
-rw-r--r-- | src/corelib/text/qstring.cpp | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 68b7011f15..068247adb4 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -4755,7 +4755,7 @@ bool QString::isUpper() const QStringIterator it(*this); while (it.hasNext()) { - const char32_t uc = it.nextUnchecked(); + const char32_t uc = it.next(); if (qGetProp(uc)->cases[QUnicodeTables::UpperCase].diff) return false; } @@ -4781,7 +4781,7 @@ bool QString::isLower() const QStringIterator it(*this); while (it.hasNext()) { - const char32_t uc = it.nextUnchecked(); + const char32_t uc = it.next(); if (qGetProp(uc)->cases[QUnicodeTables::LowerCase].diff) return false; } @@ -6143,7 +6143,7 @@ static QString detachAndConvertCase(T &str, QStringIterator it, QUnicodeTables:: QChar *pp = s.begin() + it.index(); // will detach if necessary do { - const auto folded = fullConvertCase(it.nextUnchecked(), which); + const auto folded = fullConvertCase(it.next(), which); if (Q_UNLIKELY(folded.size() > 1)) { if (folded.chars[0] == *pp && folded.size() == 2) { // special case: only second actually changed (e.g. surrogate pairs), @@ -6183,9 +6183,9 @@ static QString convertCase(T &str, QUnicodeTables::Case which) QStringIterator it(p, e); while (it.hasNext()) { - const char32_t uc = it.nextUnchecked(); + const char32_t uc = it.next(); if (qGetProp(uc)->cases[which].diff) { - it.recedeUnchecked(); + it.recede(); return detachAndConvertCase(str, it, which); } } |