summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qstringiterator_p.h
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2020-08-12 14:24:10 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2020-12-11 16:08:01 +0100
commit7715b186c79a968950fd1c8e0993641f2f58b3be (patch)
treecb9bd9bf6d0afef7e0a5556e3ef3ccd0109eaae1 /src/corelib/text/qstringiterator_p.h
parent379799b10de6203be3eb382aa2a66d443e75534c (diff)
Assert validity in QStringIterator's unchecked methods
These methods should never be used on strings not known to be valid UTF-16. Their optimizations will produce undefined behavior otherwise. Change-Id: I03a95140dcbdd1f7189eea1be69289ce227331a5 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/text/qstringiterator_p.h')
-rw-r--r--src/corelib/text/qstringiterator_p.h24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/corelib/text/qstringiterator_p.h b/src/corelib/text/qstringiterator_p.h
index 0ee5eb0e53..e7e4166c6f 100644
--- a/src/corelib/text/qstringiterator_p.h
+++ b/src/corelib/text/qstringiterator_p.h
@@ -120,16 +120,20 @@ public:
{
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
+ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
+ Q_ASSERT(pos < e && pos->isLowSurrogate());
++pos;
+ }
}
inline char32_t peekNextUnchecked() const
{
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
- if (Q_UNLIKELY(pos->isHighSurrogate()))
+ if (Q_UNLIKELY(pos->isHighSurrogate())) {
+ Q_ASSERT(pos + 1 < e && pos[1].isLowSurrogate());
return QChar::surrogateToUcs4(pos[0], pos[1]);
+ }
return pos->unicode();
}
@@ -155,8 +159,10 @@ public:
Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
const QChar cur = *pos++;
- if (Q_UNLIKELY(cur.isHighSurrogate()))
+ if (Q_UNLIKELY(cur.isHighSurrogate())) {
+ Q_ASSERT(pos < e && pos->isLowSurrogate());
return QChar::surrogateToUcs4(cur, *pos++);
+ }
return cur.unicode();
}
@@ -196,16 +202,20 @@ public:
{
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
+ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
+ Q_ASSERT(pos > i && pos[-1].isHighSurrogate());
--pos;
+ }
}
inline char32_t peekPreviousUnchecked() const
{
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
+ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
+ Q_ASSERT(pos > i + 1 && pos[-2].isHighSurrogate());
return QChar::surrogateToUcs4(pos[-2], pos[-1]);
+ }
return pos[-1].unicode();
}
@@ -230,8 +240,10 @@ public:
Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
const QChar cur = *--pos;
- if (Q_UNLIKELY(cur.isLowSurrogate()))
+ if (Q_UNLIKELY(cur.isLowSurrogate())) {
+ Q_ASSERT(pos > i && pos[-1].isHighSurrogate());
return QChar::surrogateToUcs4(*--pos, cur);
+ }
return cur.unicode();
}