From 3e58e15c3d95a7ca0786c837dd9c0d93c93ae562 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 19 Jul 2015 21:58:32 +0200 Subject: QJsonPrivate::q_littleendian: mark as primitive/movable, depending on T Inherit the type-classification from the underlying type. This amends commit 4889269ff0fb37130b332863e82dd7c19564116c, which introduced a QVector, but failed to mark the payload as primitive. Change-Id: I525a0456a550e0694b33b36b4aa71475aeac192b Reviewed-by: Lars Knoll --- src/corelib/json/qjson_p.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/corelib/json') diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 1767b3e9e6..0b3f517990 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -144,6 +144,13 @@ public: return *this; } }; +} // namespace QJsonPrivate + +template +class QTypeInfo > + : public QTypeInfoMerger, T> {}; + +namespace QJsonPrivate { typedef q_littleendian qle_short; typedef q_littleendian qle_ushort; -- cgit v1.2.3 From 1bfc7f680fc3dd839eac553c80d151a2cc7bfa3d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 6 Mar 2016 19:34:06 +0100 Subject: QString, QJson, QHash: Fix UBs involving unaligned loads Found by UBSan: src/corelib/tools/qstring.cpp:587:42: runtime error: load of misaligned address 0x2acbf4b7551b for type 'const long long int', which requires 8 byte alignment src/corelib/json/qjson_p.h:405:30: runtime error: store to misaligned address 0x0000019b1e52 for type 'quint64', which requires 8 byte alignment src/corelib/tools/qhash.cpp:116:27: runtime error: load of misaligned address 0x2b8f9ce80e85 for type 'const qlonglong', which requires 8 byte alignment src/corelib/tools/qhash.cpp:133:26: runtime error: load of misaligned address 0x2b8f9ce80e8d for type 'const ushort', which requires 2 byte alignment Fix by memcpy()ing into a local variable. Wrap this trick in template functions in qsimd_p.h. These are marked as always- inline and use __builtin_memcpy() where available in an attempt to avoid the memcpy() function call overhead in debug builds. While this looks prohibitively expensive, from the pov of the C++ abstract machine, it is 100% equivalent, except for the absence of undefined behavior. In one case, the cast produces a local temporary which is then copied into the function, and in the other case, that local variable comes from return value of qUnalignedLoad(). Consequently, GCC compiles these two versions into identical assembler code (only verfied for ucstrncmp, but there's no reason to believe that it wouldn't hold for the other cases, too). Task-number: QTBUG-51651 Change-Id: Ia50d4a1d7580b6f803e0895c9f3d89c7da37840c Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Allan Sandfeld Jensen --- src/corelib/json/qjson_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/json') diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 0b3f517990..59d0c91785 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -402,7 +402,7 @@ public: // pack with itself, we'll discard the high part anyway chunk = _mm_packus_epi16(chunk, chunk); // unaligned 64-bit store - *(quint64*)&l[i] = _mm_cvtsi128_si64(chunk); + qUnalignedStore(l + i, _mm_cvtsi128_si64(chunk)); i += 8; } # endif -- cgit v1.2.3 From 807240a8831f1b75e945471c129597c4b79a95ea Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 10 Mar 2016 09:49:22 +0100 Subject: QJsonParser: fix UB (misaligned store) in Parser::parseNumber() Found by UBSan: qjsonparser.cpp:741:30: runtime error: store to misaligned address 0x0000019b1e94 for type 'quint64', which requires 8 byte alignment Fix by using the qToLittleEndian() overload that can store to misaligned memory. Change-Id: Ib84bd30b13c68f7fdb8870c9fbbfac15cff0112d Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/json/qjsonparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/json') diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 0d62687388..b8a628fdcc 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -732,7 +732,7 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) } int pos = reserveSpace(sizeof(double)); - *(quint64 *)(data + pos) = qToLittleEndian(ui); + qToLittleEndian(ui, reinterpret_cast(data + pos)); if (current - baseOffset >= Value::MaxSize) { lastError = QJsonParseError::DocumentTooLarge; return false; -- cgit v1.2.3