diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-08-12 14:24:10 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-12-11 16:08:01 +0100 |
commit | 7715b186c79a968950fd1c8e0993641f2f58b3be (patch) | |
tree | cb9bd9bf6d0afef7e0a5556e3ef3ccd0109eaae1 /src/corelib/text/qstringiterator_p.h | |
parent | 379799b10de6203be3eb382aa2a66d443e75534c (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.h | 24 |
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(); } |