QRegularExpression: do not assume QStringViews are NUL terminated
The convenience API used to look up the index of a named capturing group expects NUL terminated strings. Therefore, we can't just use it together with QStringViews, which may be not. Use the non-convenience API instead. Pick-to: 5.15 Change-Id: I25ca14de49b13ee1764525f8b19f2550c30c1afa Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
acbf9a858b
commit
049d8892ea
|
|
@ -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<PCRE2_SPTR16>(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<const char16_t *>(namedCapturingTable) + namedCapturingTableEntrySize * i;
|
||||
|
||||
if (name == (currentNamedCapturingTableRow + 1)) {
|
||||
const int index = *currentNamedCapturingTableRow;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(?<name>\\d+)c(?<anotherName>\\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<QString>("pattern");
|
||||
|
|
|
|||
Loading…
Reference in New Issue