QTest::formatFailMessage(): fix use of std::mbstowcs()
This 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(). Use the re-entrant version and also fix the format string (%* requires int, not size_t). Saturation is ok here, because, while std::mbsrtowcs() will happily return a value > maxMsgLen when dst == nullptr and the string is longer, we will never actually print more than maxMsgLen of it. As a drive-by, port to std and adjust the QNX comments to describe the quirky QNX behavior, if, indeed, still present in the <cwchar> version, better. This author had to go back in the git history to figure out what it wanted to tell him. Amends 2d8028d696a86102a7753f9d59fb41f4170181a8 (mbstowcs) and d040681b6f3d03b349e9b9487fe89a611d03ee3c (%*). Pick-to: 6.8 6.7 6.5 6.2 5.15 Change-Id: I6215713c643647727f73f4e2f2a7ac34204af40d Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
63295f43e7
commit
1579b18dfa
@ -12,6 +12,10 @@
|
||||
#include <QtTest/qtestassert.h>
|
||||
#include <QtTest/qtesteventloop.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <cwchar>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -325,6 +329,18 @@ static const char *rightArgNameForOp(QTest::ComparisonOperation op)
|
||||
return op == QTest::ComparisonOperation::CustomCompare ? "Expected " : "Baseline ";
|
||||
}
|
||||
|
||||
static int approx_wide_len(const char *s)
|
||||
{
|
||||
std::mbstate_t state = {};
|
||||
// QNX might stop at max when dst == nullptr, so pass INT_MAX,
|
||||
// being the largest value this function will return:
|
||||
constexpr size_t max = INT_MAX;
|
||||
auto r = std::mbsrtowcs(nullptr, &s, max, &state);
|
||||
if (r == size_t(-1)) // encoding error, fall back to strlen()
|
||||
r = strlen(s); // `s` was not advanced since `dst == nullptr`
|
||||
return int(std::clamp(r, size_t(0), max));
|
||||
}
|
||||
|
||||
// Overload to format failures for "const char *" - no need to strdup().
|
||||
void formatFailMessage(char *msg, size_t maxMsgLen,
|
||||
const char *failureMsg,
|
||||
@ -332,8 +348,8 @@ void formatFailMessage(char *msg, size_t maxMsgLen,
|
||||
const char *actual, const char *expected,
|
||||
QTest::ComparisonOperation op)
|
||||
{
|
||||
size_t len1 = mbstowcs(nullptr, actual, maxMsgLen); // Last parameter is not ignored on QNX
|
||||
size_t len2 = mbstowcs(nullptr, expected, maxMsgLen); // (result is never larger than this).
|
||||
const auto len1 = approx_wide_len(actual);
|
||||
const auto len2 = approx_wide_len(expected);
|
||||
const int written = qsnprintf(msg, maxMsgLen, "%s\n", failureMsg);
|
||||
msg += written;
|
||||
maxMsgLen -= written;
|
||||
|
Loading…
x
Reference in New Issue
Block a user