IPC: QNativeIpcKey: fix big-endian builds

We weren't using the LSB in big-endian builds because the bitfield was in
the wrong order: it was either using the MSB (in 32-bit builds) or
something in the middle for 64-bit. So use quintptr in the bitfield to
ensure proper sizing and correct the order.

Additionally, we now store the d "pointer" as a quintptr, so as to avoid
storing the actual pointer to QNativeIpcKeyPrivate with the LSB set.

Change-Id: Idd5e1bb52be047d7b4fffffd17506adb77d52805
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Thiago Macieira 2023-03-27 17:35:51 -06:00
parent e2a76797e0
commit 05ebf3e54b

View File

@ -18,7 +18,7 @@ class QNativeIpcKey
{ {
Q_GADGET_EXPORT(Q_CORE_EXPORT) Q_GADGET_EXPORT(Q_CORE_EXPORT)
public: public:
enum class Type : quint16 { enum class Type : quintptr {
// 0 is reserved for the invalid type // 0 is reserved for the invalid type
// keep 1 through 0xff free, except for SystemV // keep 1 through 0xff free, except for SystemV
SystemV = 0x51, // 'Q' SystemV = 0x51, // 'Q'
@ -57,7 +57,7 @@ public:
} }
QNativeIpcKey(QNativeIpcKey &&other) noexcept QNativeIpcKey(QNativeIpcKey &&other) noexcept
: d(other.d), key(std::move(other.key)) : d(std::exchange(other.d, 0)), key(std::move(other.key))
{ {
if (isSlowPath()) if (isSlowPath())
move_internal(std::move(other)); move_internal(std::move(other));
@ -81,7 +81,7 @@ public:
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QNativeIpcKey) QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QNativeIpcKey)
void swap(QNativeIpcKey &other) void swap(QNativeIpcKey &other)
{ {
qt_ptr_swap(d, other.d); std::swap(d, other.d);
key.swap(other.key); key.swap(other.key);
} }
@ -119,17 +119,27 @@ public:
private: private:
struct TypeAndFlags { struct TypeAndFlags {
quint16 isExtended : 1; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
// this is the LSB
quintptr isExtended : 1;
Type type : 15; Type type : 15;
quint16 reserved; #endif
quintptr reserved : sizeof(quintptr) * 8 - 16;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
Type type : 15;
quint16 isExtended : 1;
// this was the LSB
#endif
}; };
// Bit 0: if set, holds a pointer (with the LSB set); if clear, holds the // Bit 0: if set, holds a pointer (with the LSB set); if clear, holds the
// the TypeAndFlags structure. // the TypeAndFlags structure.
union { union {
QNativeIpcKeyPrivate *d = nullptr; quintptr d = 0;
TypeAndFlags typeAndFlags; TypeAndFlags typeAndFlags;
static_assert(sizeof(typeAndFlags) <= sizeof(d)); static_assert(sizeof(typeAndFlags) == sizeof(d));
}; };
QString key; QString key;