diff options
author | Marc Mutz <marc.mutz@qt.io> | 2023-06-27 13:02:45 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2023-06-27 21:33:17 +0200 |
commit | 8a39f7655f4cfbc35c1886b49e2f3a9ada263e39 (patch) | |
tree | 561e2363d4c0174e2fb543f6dd2bb671a06e503a | |
parent | 2b649a7fa0ea192a96ce15326a78b39c0ad05b2b (diff) |
QQmlJs::MemoryPool: fix potential UB (pointer overflow)
A check like (p1 + s op p2) is dangerous, because p1 + s may overflow,
and that would be UB, so the compiler can assume it doesn't happen and
break the check.
Reformulate the expression by subtracting p1 from both sides. Cast the
ptrdiff_t to size_t to avoid -Wsign-compare. This is safe because _end
is always ≥ _ptr.
As a drive-by, remove extra parentheses.
Pick-to: 6.6 6.5 6.2 5.15
Change-Id: If240d685fe48196ab5ceb7ff39736b73c8997e30
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qml/common/qqmljsmemorypool_p.h | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/src/qml/common/qqmljsmemorypool_p.h b/src/qml/common/qqmljsmemorypool_p.h index a2d18f9e7e..6f0f8ed491 100644 --- a/src/qml/common/qqmljsmemorypool_p.h +++ b/src/qml/common/qqmljsmemorypool_p.h @@ -43,13 +43,12 @@ public: free(_blocks); } - qDeleteAll(strings); } inline void *allocate(size_t size) { size = (size + 7) & ~size_t(7); - if (Q_LIKELY(_ptr && (_ptr + size < _end))) { + if (Q_LIKELY(_ptr && size < size_t(_end - _ptr))) { void *addr = _ptr; _ptr += size; return addr; @@ -67,9 +66,8 @@ public: template <typename Tp, typename... Ta> Tp *New(Ta... args) { return new (this->allocate(sizeof(Tp))) Tp(args...); } - QStringView newString(const QString &string) { - strings.append(new QString(string)); - return QStringView(*strings.last()); + QStringView newString(QString string) { + return strings.emplace_back(std::move(string)); } private: @@ -113,7 +111,7 @@ private: int _blockCount = -1; char *_ptr = nullptr; char *_end = nullptr; - QVector<QString*> strings; + QStringList strings; enum { |