summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <[email protected]>2024-07-22 21:55:19 +0200
committerMarc Mutz <[email protected]>2024-07-31 19:02:24 +0200
commitaa8a4be9e9eae82b6c6b8875371114dbfb3ec06a (patch)
tree98fd3fc90d973cafdb590f79aeb02890f2db27e3
parentbc34fe0e351d682584387dbfe5adee06ff59895c (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.h22
-rw-r--r--src/testlib/qtestcase.h5
-rw-r--r--src/testlib/qtestresult.cpp11
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,