From d351a97e85e5ed8acd7ad1357ef76dc2e0ad639f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 8 Jan 2024 14:47:12 -0300 Subject: QString::arg: don't pass nullptr to memcpy() A null QString / QStringView has a null begin pointer stored as its array beginning (something we hide a little in the QString::data() function, but not in QStringView::data()). We've been passing a null pointer to memcpy() every time someone passed a null QStringView for QString's single-argument arg() call, though not the multi-string arg() version (which is the only one QStringView offers). Commit f5021835dfb4b0bf974794b598cbdf9f0f95898d made this worse by making QStringViews created from null QStrings retain the nullness (as was intended). Fixes: QTBUG-120624 Pick-to: 6.2 6.5 6.6 6.7 Change-Id: I6e2677aad2ab45759db2fffd17a870639b19340b Reviewed-by: Marc Mutz --- src/corelib/text/qstring.cpp | 3 ++- tests/auto/corelib/text/qstring/tst_qstring.cpp | 19 +++++++++++++++++-- .../auto/corelib/text/qstringview/tst_qstringview.cpp | 4 ++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 4c2bef298f..6b06f1581e 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -8405,7 +8405,8 @@ static QString replaceArgEscapes(QStringView s, const ArgEscapeData &d, qsizetyp rc = std::fill_n(rc, pad_chars, fillChar); } - memcpy(rc, use.data(), use.size() * sizeof(QChar)); + if (use.size()) + memcpy(rc, use.data(), use.size() * sizeof(QChar)); rc += use.size(); if (field_width < 0) { // right padded diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index b31c5dedb8..48e64986d1 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -6558,9 +6558,18 @@ void tst_QString::arg() QString s13(u"%1% %x%c%2 %d%2-%"_s); QString s14(u"%1%2%3"_s); + const QString null; + const QString empty(u""_s); const QString foo(u"foo"_s); const QString bar(u"bar"_s); + Q_ASSERT(null.isNull()); + Q_ASSERT(!empty.isNull()); + QCOMPARE(s4.arg(null), "[]"_L1); + QCOMPARE(s4.arg(empty), "[]"_L1); + QCOMPARE(s4.arg(QStringView()), "[]"_L1); + QCOMPARE(s4.arg(QStringView(u"")), "[]"_L1); + QCOMPARE(s4.arg(foo), "[foo]"_L1); QCOMPARE( s5.arg(QLatin1String("foo")), QLatin1String("[foo]") ); QCOMPARE( s6.arg(u"foo"), QLatin1String("[foo]") ); @@ -6653,6 +6662,14 @@ void tst_QString::arg() QCOMPARE(QString(u"%%%"_s).arg(0), "%%%"_L1); QCOMPARE(QString(u"%%%1%%%2"_s).arg(foo).arg(bar), "%%foo%%bar"_L1); + QCOMPARE(u"%1"_s.arg(null, 3), " "_L1); + QCOMPARE(u"%1"_s.arg(empty, 3), " "_L1); + QCOMPARE(u"%1"_s.arg(QStringView(), 3), " "_L1); + QCOMPARE(u"%1"_s.arg(QStringView(u""), 3), " "_L1); + QCOMPARE(u"%1%1"_s.arg(null), ""_L1); + QCOMPARE(u"%2%1"_s.arg(empty), "%2"_L1); + QCOMPARE(u"%2%1"_s.arg(QStringView()), "%2"_L1); + QCOMPARE(u"%2%1"_s.arg(QStringView(u"")), "%2"_L1); QCOMPARE(u"%1"_s.arg(u"hello"_s, -10), "hello "_L1); QCOMPARE(u"%1"_s.arg("hello"_L1, -5), "hello"_L1); QCOMPARE(u"%1"_s.arg(u"hello", -2), "hello"_L1); @@ -6662,8 +6679,6 @@ void tst_QString::arg() QCOMPARE(u"%1"_s.arg(u"hello"_s, 10), " hello"_L1); QCOMPARE(u"%1%1"_s.arg(u"hello"_s), "hellohello"_L1); QCOMPARE(u"%2%1"_s.arg(u"hello"_s), "%2hello"_L1); - QCOMPARE(u"%1%1"_s.arg(QString()), QLatin1String("")); - QCOMPARE(u"%2%1"_s.arg(u""_s), "%2"_L1); QCOMPARE( QString(u"%2 %L1"_s).arg(12345.6789).arg(12345.6789), QLatin1String("12345.7 12.345,7") ); diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index e0564ac671..5adb8d5213 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -469,6 +469,10 @@ void tst_QStringView::at() const void tst_QStringView::arg() const { + // nullness checks + QCOMPARE(QStringView().arg(QStringView()), ""); + QCOMPARE(QStringView("%1").arg(QStringView()), ""); + #define CHECK1(pattern, arg1, expected) \ do { \ auto p = QStringView(u"" pattern); \ -- cgit v1.2.3