diff options
-rw-r--r-- | src/corelib/text/qregularexpression.cpp | 16 | ||||
-rw-r--r-- | tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp | 25 |
2 files changed, 37 insertions, 4 deletions
diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index a311c0878f..a4bb19d0b2 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -1174,7 +1174,19 @@ void QRegularExpressionPrivate::doMatch(QRegularExpressionMatchPrivate *priv, pcre2_jit_stack_assign_16(matchContext, &qtPcreCallback, nullptr); pcre2_match_data_16 *matchData = pcre2_match_data_create_from_pattern_16(compiledPattern, nullptr); - const char16_t * const subjectUtf16 = priv->subject.utf16(); + // PCRE does not accept a null pointer as subject string, even if + // its length is zero. We however allow it in input: a QStringView + // subject may have data == nullptr. In this case, to keep PCRE + // happy, pass a pointer to a dummy character. + constexpr char16_t dummySubject = 0; + const char16_t * const subjectUtf16 = [&]() + { + const auto subjectUtf16 = priv->subject.utf16(); + if (subjectUtf16) + return subjectUtf16; + Q_ASSERT(subjectLength == 0); + return &dummySubject; + }(); int result; @@ -1610,7 +1622,7 @@ QRegularExpressionMatch QRegularExpression::match(const QString &subject, d.data()->compilePattern(); auto priv = new QRegularExpressionMatchPrivate(*this, subject, - qToStringViewIgnoringNull(subject), + QStringView(subject), matchType, matchOptions); d->doMatch(priv, offset); diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index f2fe382521..48d4de0aa4 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -252,8 +252,11 @@ void consistencyCheck(const QRegularExpressionMatch &match) QVERIFY((endPos - startPos) == length); QVERIFY(captured == capturedView); } else { - QVERIFY(startPos == -1); - QVERIFY(endPos == -1); + // A null capture can either mean no capture at all, + // or capture of length 0 over a null subject. + QVERIFY(startPos == endPos); + QVERIFY(((startPos == -1) && (endPos == -1)) // no capture + || ((startPos == 0) && (endPos == 0))); // null subject QVERIFY((endPos - startPos) == length); QVERIFY(capturedView.isNull()); } @@ -860,6 +863,24 @@ void tst_QRegularExpression::normalMatch_data() << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) << m; + m.clear(); + m.isValid = true; m.hasMatch = true; + m.captured << QString(); + QTest::newRow("empty-in-null-string") << QRegularExpression("") + << QString() + << qsizetype(0) + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + + m.clear(); + m.isValid = true; m.hasMatch = true; + m.captured << QString(""); + QTest::newRow("empty-in-empty-string") << QRegularExpression("") + << QString("") + << qsizetype(0) + << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption) + << m; + // non existing names for capturing groups m.clear(); m.isValid = true; m.hasMatch = true; |