diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index c52a80e676..a0b35f8142 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -1040,9 +1040,24 @@ int QRegularExpressionPrivate::captureIndexForName(QStringView name) const if (!compiledPattern) return -1; - int index = pcre2_substring_number_from_name_16(compiledPattern, reinterpret_cast(name.utf16())); - if (index >= 0) - return index; + // See the other usages of pcre2_pattern_info_16 for more details about this + PCRE2_SPTR16 *namedCapturingTable; + unsigned int namedCapturingTableEntryCount; + unsigned int namedCapturingTableEntrySize; + + pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NAMETABLE, &namedCapturingTable); + pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NAMECOUNT, &namedCapturingTableEntryCount); + pcre2_pattern_info_16(compiledPattern, PCRE2_INFO_NAMEENTRYSIZE, &namedCapturingTableEntrySize); + + for (unsigned int i = 0; i < namedCapturingTableEntryCount; ++i) { + const auto currentNamedCapturingTableRow = + reinterpret_cast(namedCapturingTable) + namedCapturingTableEntrySize * i; + + if (name == (currentNamedCapturingTableRow + 1)) { + const int index = *currentNamedCapturingTableRow; + return index; + } + } return -1; } diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index ab93373d44..dbe77be1f5 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -69,6 +69,7 @@ private slots: void captureCount(); void captureNames_data(); void captureNames(); + void captureNamesNul(); void pcreJitStackUsage_data(); void pcreJitStackUsage(); void regularExpressionMatch_data(); @@ -1620,6 +1621,36 @@ void tst_QRegularExpression::captureNames() } +void tst_QRegularExpression::captureNamesNul() +{ + QRegularExpression re("a(\\d+)b(?\\d+)c(?\\d+)d(\\d+)e$"); + QVERIFY(re.isValid()); + + QCOMPARE(re.captureCount(), 4); + + QStringList namedCaptureGroups = re.namedCaptureGroups(); + QCOMPARE(namedCaptureGroups[0], QString()); + QCOMPARE(namedCaptureGroups[1], QString()); + QCOMPARE(namedCaptureGroups[2], "name"); + QCOMPARE(namedCaptureGroups[3], "anotherName"); + QCOMPARE(namedCaptureGroups[4], QString()); + + QRegularExpressionMatch m = re.match("a12b456c789d0e"); + QVERIFY(m.hasMatch()); + + QString captureName("name"); + QCOMPARE(m.captured(captureName), "456"); + QCOMPARE(m.captured(QStringView(captureName)), "456"); + QCOMPARE(m.captured(qToStringViewIgnoringNull(captureName)), "456"); + QCOMPARE(m.captured(u"name"), "456"); + + captureName = "anotherName"; + QCOMPARE(m.captured(captureName), "789"); + QCOMPARE(m.captured(QStringView(captureName)), "789"); + QCOMPARE(m.captured(qToStringViewIgnoringNull(captureName)), "789"); + QCOMPARE(m.captured(u"anotherName"), "789"); +} + void tst_QRegularExpression::pcreJitStackUsage_data() { QTest::addColumn("pattern");