diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2021-07-01 15:24:46 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-07-05 10:24:54 +0000 |
commit | 8d516e195d64c8bb3c1b14507fcd13975265df57 (patch) | |
tree | aabf70d798d2ad1a2e18c8c741655a8ec1440255 /src/corelib/kernel/qproperty.cpp | |
parent | 14ff68d7a924ce99d5a013a894acc2acab819a92 (diff) |
Fix binding functor addressing in QProperty
We create the callable object at sizeof(QPBP) offset from
the beginning of the memory block. However, evaluateRecursive()
uses sizeof() + alignment when fetching that same callable from
the memory
While on 64-bit platforms this is fine due to
sizeof(QPBP) == QPBP::getSizeEnsuringAlignment(), this is broken for
32-bit systems where there's actually alignment bits that follow the
QPBP struct in memory (and thus we cast a random memory location to
an object)
(Note: QPBP is short for QPropertyBindingPrivate)
To fix this, change the offset for creation and destruction of the
callable to the one that uses alignment. This way, evaluateRecursive()
code becomes correct
Fixes: QTBUG-93890
Change-Id: Ief57051846632fa61df4b79b3f054c25062a9498
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 565864090d4ca38768c2268ffd265d2f4b49d1b0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/corelib/kernel/qproperty.cpp')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index d290f0a16c..965939a1fc 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -268,7 +268,8 @@ QPropertyBindingPrivate::~QPropertyBindingPrivate() if (firstObserver) firstObserver.unlink(); if (vtable->size) - vtable->destroy(reinterpret_cast<std::byte *>(this) + sizeof(QPropertyBindingPrivate)); + vtable->destroy(reinterpret_cast<std::byte *>(this) + + QPropertyBindingPrivate::getSizeEnsuringAlignment()); } void QPropertyBindingPrivate::unlinkAndDeref() @@ -344,7 +345,7 @@ QUntypedPropertyBinding::QUntypedPropertyBinding(QMetaType metaType, const Bindi { std::byte *mem = new std::byte[QPropertyBindingPrivate::getSizeEnsuringAlignment() + vtable->size](); d = new(mem) QPropertyBindingPrivate(metaType, vtable, std::move(location)); - vtable->moveConstruct(mem+sizeof(QPropertyBindingPrivate), function); + vtable->moveConstruct(mem + QPropertyBindingPrivate::getSizeEnsuringAlignment(), function); } QUntypedPropertyBinding::QUntypedPropertyBinding(QUntypedPropertyBinding &&other) |