diff options
author | Marc Mutz <[email protected]> | 2024-07-22 21:55:19 +0200 |
---|---|---|
committer | Marc Mutz <[email protected]> | 2024-07-31 19:02:24 +0200 |
commit | aa8a4be9e9eae82b6c6b8875371114dbfb3ec06a (patch) | |
tree | 98fd3fc90d973cafdb590f79aeb02890f2db27e3 | |
parent | bc34fe0e351d682584387dbfe5adee06ff59895c (diff) |
QPROPERTY_TEST_COMPARISON_HELPER: fix mbstowcs and snprintf usage
The mbstowcs() function is not re-entrant, and while we can probably
rule out that our test macros are being executed concurrently, we
can't rule out that other parts of the test concurrently execute
std::mbstowcs().
To fix, de-inline the code so we can re-use the existing
formatFailMessage() in qtestresult.cpp, which has already been fixed
before.
Amends 930e59b798d9e3d08e17440980d33a08fb411cbe.
Pick-to: 6.8 6.7 6.5 6.2
Change-Id: I61144af13a41ea0b4fba17bd232e660ef33dbd20
Reviewed-by: Ivan Solovev <[email protected]>
-rw-r--r-- | src/testlib/qpropertytesthelper_p.h | 22 | ||||
-rw-r--r-- | src/testlib/qtestcase.h | 5 | ||||
-rw-r--r-- | src/testlib/qtestresult.cpp | 11 |
3 files changed, 25 insertions, 13 deletions
diff --git a/src/testlib/qpropertytesthelper_p.h b/src/testlib/qpropertytesthelper_p.h index 226de8e3fba..67314ec1a08 100644 --- a/src/testlib/qpropertytesthelper_p.h +++ b/src/testlib/qpropertytesthelper_p.h @@ -44,19 +44,15 @@ namespace QTestPrivate { */ #define QPROPERTY_TEST_COMPARISON_HELPER(actual, expected, comparator, represent) \ do { \ - const size_t maxMsgLen = 1024; \ - char msg[maxMsgLen]; \ - auto actualStr = represent(actual); \ - auto expectedStr = represent(expected); \ - const size_t len1 = mbstowcs(nullptr, #actual, maxMsgLen); \ - const size_t len2 = mbstowcs(nullptr, #expected, maxMsgLen); \ - qsnprintf(msg, maxMsgLen, "\n%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s\n", \ - "Comparison failed!", #actual, qMax(len1, len2) - len1 + 1, ":", \ - actualStr ? actualStr : "<null>", #expected, qMax(len1, len2) - len2 + 1, ":", \ - expectedStr ? expectedStr : "<null>"); \ - delete[] actualStr; \ - delete[] expectedStr; \ - QVERIFY2(comparator(actual, expected), msg); \ + char qprop_tst_cmp_hlp_buf[1024]; \ + const auto qprop_tst_cmp_hlp_act = std::unique_ptr<char[]>(represent(actual)); \ + const auto qprop_tst_cmp_hlp_exp = std::unique_ptr<char[]>(represent(expected)); \ + QVERIFY2(comparator(actual, expected), \ + QTest::Internal::formatPropertyTestHelperFailure(qprop_tst_cmp_hlp_buf, \ + sizeof qprop_tst_cmp_hlp_buf, \ + qprop_tst_cmp_hlp_act.get(), \ + qprop_tst_cmp_hlp_exp.get(), \ + #actual, #expected)); \ } while (false) /*! diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 44371c00a19..2c2c3263ff6 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -316,6 +316,11 @@ namespace QTest Q_TESTLIB_EXPORT void maybeThrowOnSkip(); Q_TESTLIB_EXPORT QString formatTryTimeoutDebugMessage(q_no_char8_t::QUtf8StringView expr, int timeout, int actual); + Q_TESTLIB_EXPORT + const char *formatPropertyTestHelperFailure(char *msg, size_t maxMsgLen, + const char *actual, const char *expected, + const char *actualExpr, + const char *expectedExpr); template <ComparisonOperation> struct Compare; template <> struct Compare<ComparisonOperation::Equal> diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 4feb0ac7044..6714d38ddf8 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -367,6 +367,17 @@ void formatFailMessage(char *msg, size_t maxMsgLen, } } +const char * +QTest::Internal::formatPropertyTestHelperFailure(char *msg, size_t maxMsgLen, + const char *actual, const char *expected, + const char *actualExpr, const char *expectedExpr) +{ + formatFailMessage(msg, maxMsgLen, "\nComparison failed!", // ### why leading \n? + actual, expected, actualExpr, expectedExpr, + QTest::ComparisonOperation::CustomCompare); + return msg; +} + // Format failures using the toString() template template <class Actual, class Expected> void formatFailMessage(char *msg, size_t maxMsgLen, |