Skip to content

Commit

Permalink
QTest: fix bug dereferencing nullptr in toString<std::nullptr_t>()
Browse files Browse the repository at this point in the history
Amends commit 0756cc1.

The generic instantiation of this function had a std::nullptr_t *
parameter, but callers had special code to pass a nullptr there because
we never needed a value of a nullptr (it's always a null pointer). For
example, in compare_ptr_helper():

        auto lhsFormatter = Internal::pointerToString<QObject>;
        auto rhsFormatter = Internal::genericToString<std::nullptr_t>;
        return compare_helper(t1 == nullptr, "Compared QObject pointers are not the same",
                              const_cast<const QObject *>(t1), nullptr,
                              lhsFormatter, rhsFormatter, actual, expected, file, line);

But in debug mode, some compilers did emit a load from this memory
location, causing a crash. So we just specialize this function to avoid
such.

We had a test for this... except it was never reached because the
earlier QCOMPARE() had already failed. For the test, this amends
commit ae02188.

Fixes: QTBUG-133330
Pick-to: 6.9 6.8
Change-Id: I2cd3bb475788431c6a0dfffd28e730e8b613e033
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
  • Loading branch information
thiagomacieira committed Jan 30, 2025
1 parent 91d86e4 commit e19b633
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/testlib/qtestcase.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ namespace QTest
return toString(static_cast<const char *>(arg));
}

template <> inline const char *genericToString<std::nullptr_t>(const void *)
{
return QTest::toString(nullptr);
}

template <typename T> const char *pointerToString(const void *arg)
{
using QTest::toString;
Expand Down
8 changes: 4 additions & 4 deletions tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,10 @@ void tst_Cmptest::compareQObjects()
object1.setObjectName(QStringLiteral("object1"));
QObject object2;
object2.setObjectName(QStringLiteral("object2"));
QCOMPARE(&object1, &object1);
QCOMPARE(&object1, &object2);
QCOMPARE(&object1, nullptr);
QCOMPARE(nullptr, &object2);
[&] { QCOMPARE(&object1, &object1); }();
[&] { QCOMPARE(&object1, &object2); }();
[&] { QCOMPARE(&object1, nullptr); }();
[&] { QCOMPARE(nullptr, &object2); }();
}

void tst_Cmptest::compare_stringLiterals()
Expand Down
10 changes: 10 additions & 0 deletions tests/auto/testlib/selftests/expected_cmptest.lightxml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
<Description><![CDATA[Compared QObject pointers are not the same
Actual (&object1): QObject/"object1"
Expected (&object2): QObject/"object2"]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
<Description><![CDATA[Compared QObject pointers are not the same
Actual (&object1): QObject/"object1"
Expected (nullptr) : "nullptr"]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
<Description><![CDATA[Compared QObject pointers are not the same
Actual (nullptr) : "nullptr"
Expected (&object2): QObject/"object2"]]></Description>
</Incident>
<Duration msecs="0"/>
Expand Down
24 changes: 24 additions & 0 deletions tests/auto/testlib/selftests/expected_cmptest.tap
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,30 @@ not ok 22 - compareQObjects()
file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
line: 0
...
not ok 22 - compareQObjects()
---
type: QCOMPARE
message: Compared QObject pointers are not the same
wanted: "nullptr" (nullptr)
found: QObject/"object1" (&object1)
expected: "nullptr" (nullptr)
actual: QObject/"object1" (&object1)
at: tst_Cmptest::compareQObjects() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:0)
file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
line: 0
...
not ok 22 - compareQObjects()
---
type: QCOMPARE
message: Compared QObject pointers are not the same
wanted: QObject/"object2" (&object2)
found: "nullptr" (nullptr)
expected: QObject/"object2" (&object2)
actual: "nullptr" (nullptr)
at: tst_Cmptest::compareQObjects() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:0)
file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
line: 0
...
ok 23 - compareQStringLists(empty lists)
ok 24 - compareQStringLists(equal lists)
not ok 25 - compareQStringLists(last item different)
Expand Down
4 changes: 4 additions & 0 deletions tests/auto/testlib/selftests/expected_cmptest.teamcity
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
##teamcity[testStarted name='compareQObjects()' flowId='tst_Cmptest']
##teamcity[testFailed name='compareQObjects()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QObject pointers are not the same|n Actual (&object1): QObject/"object1"|n Expected (&object2): QObject/"object2"' flowId='tst_Cmptest']
##teamcity[testFinished name='compareQObjects()' flowId='tst_Cmptest']
##teamcity[testFailed name='compareQObjects()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QObject pointers are not the same|n Actual (&object1): QObject/"object1"|n Expected (nullptr) : "nullptr"' flowId='tst_Cmptest']
##teamcity[testFinished name='compareQObjects()' flowId='tst_Cmptest']
##teamcity[testFailed name='compareQObjects()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QObject pointers are not the same|n Actual (nullptr) : "nullptr"|n Expected (&object2): QObject/"object2"' flowId='tst_Cmptest']
##teamcity[testFinished name='compareQObjects()' flowId='tst_Cmptest']
##teamcity[testStarted name='compareQStringLists(empty lists)' flowId='tst_Cmptest']
##teamcity[testFinished name='compareQStringLists(empty lists)' flowId='tst_Cmptest']
##teamcity[testStarted name='compareQStringLists(equal lists)' flowId='tst_Cmptest']
Expand Down
8 changes: 8 additions & 0 deletions tests/auto/testlib/selftests/expected_cmptest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ FAIL! : tst_Cmptest::compareQObjects() Compared QObject pointers are not the sa
Actual (&object1): QObject/"object1"
Expected (&object2): QObject/"object2"
Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
FAIL! : tst_Cmptest::compareQObjects() Compared QObject pointers are not the same
Actual (&object1): QObject/"object1"
Expected (nullptr) : "nullptr"
Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
FAIL! : tst_Cmptest::compareQObjects() Compared QObject pointers are not the same
Actual (nullptr) : "nullptr"
Expected (&object2): QObject/"object2"
Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
PASS : tst_Cmptest::compareQStringLists(empty lists)
PASS : tst_Cmptest::compareQStringLists(equal lists)
FAIL! : tst_Cmptest::compareQStringLists(last item different) Compared lists differ at index 2.
Expand Down
10 changes: 10 additions & 0 deletions tests/auto/testlib/selftests/expected_cmptest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
<Description><![CDATA[Compared QObject pointers are not the same
Actual (&object1): QObject/"object1"
Expected (&object2): QObject/"object2"]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
<Description><![CDATA[Compared QObject pointers are not the same
Actual (&object1): QObject/"object1"
Expected (nullptr) : "nullptr"]]></Description>
</Incident>
<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
<Description><![CDATA[Compared QObject pointers are not the same
Actual (nullptr) : "nullptr"
Expected (&object2): QObject/"object2"]]></Description>
</Incident>
<Duration msecs="0"/>
Expand Down

0 comments on commit e19b633

Please sign in to comment.