diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index 0c8215cebb..c6aa26b619 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -823,6 +823,24 @@ struct QRegularExpressionMatchIteratorPrivate : QSharedData const QRegularExpression::MatchOptions matchOptions; }; +/*! + \internal + + Used to centralize the warning about using an invalid QRegularExpression. + In case the pattern is an illegal UTF-16 string, we can't pass print it + (pass it to qUtf16Printable, etc.), so we need to check for that. +*/ +Q_DECL_COLD_FUNCTION +void qtWarnAboutInvalidRegularExpression(const QString &pattern, const char *where) +{ + if (pattern.isValidUtf16()) { + qWarning("%s(): called on an invalid QRegularExpression object " + "(pattern is '%ls')", where, qUtf16Printable(pattern)); + } else { + qWarning("%s(): called on an invalid QRegularExpression object", where); + } +} + /*! \internal */ @@ -1131,7 +1149,7 @@ void QRegularExpressionPrivate::doMatch(QRegularExpressionMatchPrivate *priv, return; if (Q_UNLIKELY(!compiledPattern)) { - qWarning("QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(pattern, "QRegularExpressionPrivate::doMatch"); return; } diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 72c839a478..f1ee16901b 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -1641,6 +1641,10 @@ static int qArgDigitValue(QChar ch) noexcept return -1; } +#if QT_CONFIG(regularexpression) +Q_DECL_COLD_FUNCTION +void qtWarnAboutInvalidRegularExpression(const QString &pattern, const char *where); +#endif /*! \macro QT_RESTRICTED_CAST_FROM_ASCII @@ -4347,7 +4351,7 @@ Q_DECLARE_TYPEINFO(QStringCapture, Q_PRIMITIVE_TYPE); QString &QString::replace(const QRegularExpression &re, const QString &after) { if (!re.isValid()) { - qWarning("QString::replace: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString::replace"); return *this; } @@ -4873,7 +4877,7 @@ static QString extractSections(const QList §ions, qsizetyp QString QString::section(const QRegularExpression &re, qsizetype start, qsizetype end, SectionFlags flags) const { if (!re.isValid()) { - qWarning("QString::section: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString::section"); return QString(); } @@ -7682,7 +7686,7 @@ static ResultList splitString(const String &source, const QRegularExpression &re { ResultList list; if (!re.isValid()) { - qWarning("QString::split: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString::split"); return list; } @@ -10584,7 +10588,7 @@ qsizetype QtPrivate::lastIndexOf(QLatin1String haystack, qsizetype from, QLatin1 qsizetype QtPrivate::indexOf(QStringView haystack, const QRegularExpression &re, qsizetype from, QRegularExpressionMatch *rmatch) { if (!re.isValid()) { - qWarning("QString(View)::indexOf: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString(View)::indexOf"); return -1; } @@ -10602,7 +10606,7 @@ qsizetype QtPrivate::indexOf(QStringView haystack, const QRegularExpression &re, qsizetype QtPrivate::lastIndexOf(QStringView haystack, const QRegularExpression &re, qsizetype from, QRegularExpressionMatch *rmatch) { if (!re.isValid()) { - qWarning("QString(View)::lastIndexOf: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString(View)::lastIndexOf"); return -1; } @@ -10627,7 +10631,7 @@ qsizetype QtPrivate::lastIndexOf(QStringView haystack, const QRegularExpression bool QtPrivate::contains(QStringView haystack, const QRegularExpression &re, QRegularExpressionMatch *rmatch) { if (!re.isValid()) { - qWarning("QString(View)::contains: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString(View)::contains"); return false; } QRegularExpressionMatch m = re.match(haystack); @@ -10640,7 +10644,7 @@ bool QtPrivate::contains(QStringView haystack, const QRegularExpression &re, QRe qsizetype QtPrivate::count(QStringView haystack, const QRegularExpression &re) { if (!re.isValid()) { - qWarning("QString(View)::count: invalid QRegularExpression object"); + qtWarnAboutInvalidRegularExpression(re.pattern(), "QString(View)::count"); return 0; } qsizetype count = 0; diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index 9ded894472..08c787576d 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -712,18 +712,23 @@ void tst_QRegularExpression::validity_data() void tst_QRegularExpression::validity() { + static const QRegularExpression ignoreMessagePattern( + "^" + QRegularExpression::escape("QRegularExpressionPrivate::doMatch(): " + "called on an invalid QRegularExpression object") + ); + QFETCH(QString, pattern); QFETCH(bool, validity); QRegularExpression re(pattern); QCOMPARE(re.isValid(), validity); if (!validity) - QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QRegularExpressionMatch match = re.match("a pattern"); QCOMPARE(match.isValid(), validity); consistencyCheck(match); if (!validity) - QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QRegularExpressionMatchIterator iterator = re.globalMatch("a pattern"); QCOMPARE(iterator.isValid(), validity); } diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index da57694532..c295e96be4 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -1725,14 +1725,18 @@ void tst_QString::indexOf2() #if QT_CONFIG(regularexpression) void tst_QString::indexOfInvalidRegex() { - QTest::ignoreMessage(QtWarningMsg, "QString(View)::indexOf: invalid QRegularExpression object"); + static const QRegularExpression ignoreMessagePattern( + "^QString\\(View\\)::indexOf\\(\\): called on an invalid QRegularExpression object" + ); + + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\")), -1); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::indexOf: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, nullptr), -1); QRegularExpressionMatch match; QVERIFY(!match.hasMatch()); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::indexOf: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, &match), -1); QVERIFY(!match.hasMatch()); } @@ -1851,14 +1855,18 @@ void tst_QString::lastIndexOf() #if QT_CONFIG(regularexpression) void tst_QString::lastIndexOfInvalidRegex() { - QTest::ignoreMessage(QtWarningMsg, "QString(View)::lastIndexOf: invalid QRegularExpression object"); + static const QRegularExpression ignoreMessagePattern( + "^QString\\(View\\)::lastIndexOf\\(\\): called on an invalid QRegularExpression object" + ); + + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::lastIndexOf: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, nullptr), -1); QRegularExpressionMatch match; QVERIFY(!match.hasMatch()); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::lastIndexOf: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, &match), -1); QVERIFY(!match.hasMatch()); } @@ -1866,6 +1874,10 @@ void tst_QString::lastIndexOfInvalidRegex() void tst_QString::count() { + static const QRegularExpression ignoreMessagePattern( + "^QString\\(View\\)::count\\(\\): called on an invalid QRegularExpression object" + ); + QString a; a="ABCDEFGHIEfGEFG"; // 15 chars QCOMPARE(a.count('A'),1); @@ -1881,7 +1893,7 @@ void tst_QString::count() QCOMPARE(a.count(QRegularExpression("")), 16); QCOMPARE(a.count(QRegularExpression("[FG][HI]")), 1); QCOMPARE(a.count(QRegularExpression("[G][HE]")), 2); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::count: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(a.count(QRegularExpression("invalid regex\\")), 0); #endif @@ -1900,7 +1912,7 @@ void tst_QString::count() #if QT_CONFIG(regularexpression) QCOMPARE(nullStr.count(QRegularExpression("")), 1); QCOMPARE(nullStr.count(QRegularExpression("[FG][HI]")), 0); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::count: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(nullStr.count(QRegularExpression("invalid regex\\")), 0); #endif @@ -1914,13 +1926,17 @@ void tst_QString::count() #if QT_CONFIG(regularexpression) QCOMPARE(emptyStr.count(QRegularExpression("")), 1); QCOMPARE(emptyStr.count(QRegularExpression("[FG][HI]")), 0); - QTest::ignoreMessage(QtWarningMsg, "QString(View)::count: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QCOMPARE(emptyStr.count(QRegularExpression("invalid regex\\")), 0); #endif } void tst_QString::contains() { + static const QRegularExpression ignoreMessagePattern( + "^QString\\(View\\)::contains\\(\\): called on an invalid QRegularExpression object" + ); + QString a; a="ABCDEFGHIEfGEFG"; // 15 chars QVERIFY(a.contains('A')); @@ -1987,7 +2003,7 @@ void tst_QString::contains() QVERIFY(!a.contains(QRegularExpression("ZZZ"), 0)); } - QTest::ignoreMessage(QtWarningMsg, "QString(View)::contains: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); QVERIFY(!a.contains(QRegularExpression("invalid regex\\"))); #endif @@ -3226,13 +3242,17 @@ void tst_QString::replace_string_extra() #if QT_CONFIG(regularexpression) void tst_QString::replace_regexp() { + static const QRegularExpression ignoreMessagePattern( + "^QString::replace\\(\\): called on an invalid QRegularExpression object" + ); + QFETCH( QString, string ); QFETCH( QString, regexp ); QFETCH( QString, after ); QRegularExpression regularExpression(regexp); if (!regularExpression.isValid()) - QTest::ignoreMessage(QtWarningMsg, "QString::replace: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); string.replace(regularExpression, after); QTEST(string, "result"); } @@ -3347,6 +3367,10 @@ void tst_QString::remove_regexp_data() void tst_QString::remove_regexp() { + static const QRegularExpression ignoreMessagePattern( + "^QString::replace\\(\\): called on an invalid QRegularExpression object" + ); + QFETCH( QString, string ); QFETCH( QString, regexp ); QTEST(QString(), "after"); // non-empty replacement text tests should go in replace_regexp_data() @@ -3354,7 +3378,7 @@ void tst_QString::remove_regexp() QRegularExpression regularExpression(regexp); // remove() delegates to replace(), which produces this warning: if (!regularExpression.isValid()) - QTest::ignoreMessage(QtWarningMsg, "QString::replace: invalid QRegularExpression object"); + QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern); string.remove(regularExpression); QTEST(string, "result"); }