From f4e1c43872601372e3f6f8ece8b1f07cac541501 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 6 Aug 2022 08:54:17 +0200 Subject: qputenv: defend against non-NUL-terminated QByteArray values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old code assumed that a QByteArray's data() is always NUL-terminated. Due to the conflation of owners and non-owners in QByteArray (but also in case we ever get efficient substringing), this is not always the case, e.g. QByteArray::fromRawData() does not ensure NUL-termination. From QString::utf16(), we learn that the condition to check for is QArrayData::isMutable(). After working around the fact that QByteArray::data_ptr() doesn't exist for const QBAs and that empty QBAs always refer to QByteArray::empty_, which is !isMutable(), we can detect this situation and re-allocate without introducing new API. This is the fix for Qt ≤ 6.4. For Qt 6.5, we'll port the function to QByteArrayView. Manual conflict resolutions: - tracked changes into qglobal.cpp (was: qenvionmentvariables.cpp) - QCOMPARE_EQ → QCOMPARE - ported from QArrayDataPointer::isMutable() to Qt 5's IS_RAW_DATA Fixes: QTBUG-105302 Change-Id: I3416535ab09d601e0e87b2767f2c024ba1217e64 Reviewed-by: Sona Kurazyan Reviewed-by: Mårten Nordheim (cherry picked from commit 15422d191fb03eb9cafe68b24484d59c1270244c) Reviewed-by: Qt CI Bot --- src/corelib/global/qglobal.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/corelib/global') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index a4cc506089..206548d897 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3723,6 +3723,15 @@ bool qEnvironmentVariableIsSet(const char *varName) noexcept */ bool qputenv(const char *varName, const QByteArray& value) { + // protect against non-NUL-terminated QByteArrays: + #define IS_RAW_DATA(d) ((d)->offset != sizeof(QByteArrayData)) // copied from qbytearray.cpp + if (IS_RAW_DATA(const_cast(value).data_ptr())) { + QByteArray copy(value); + copy.detach(); // ensures NUL termination + return qputenv(varName, copy); + } + #undef IS_RAW_DATA + const auto locker = qt_scoped_lock(environmentMutex); #if defined(Q_CC_MSVC) return _putenv_s(varName, value.constData()) == 0; -- cgit v1.2.3