moonchen commented on code in PR #13441:
URL: https://github.com/apache/trafficserver/pull/13441#discussion_r3738300533
##########
src/tsutil/Regex.cc:
##########
@@ -205,6 +205,13 @@ RegexMatches::operator[](size_t index) const
}
PCRE2_SIZE *ovector =
pcre2_get_ovector_pointer(_MatchData::get(_match_data));
+
+ // A group that did not participate in the match has an unset offset. This
happens for an optional
+ // group that precedes a participating one, so a valid index is not enough
to guarantee an offset.
+ if (PCRE2_UNSET == ovector[2 * index]) {
+ return std::string_view();
+ }
+
return std::string_view(_subject.data() + ovector[2 * index], ovector[2 *
index + 1] - ovector[2 * index]);
Review Comment:
Neither case is reachable.
Unset offsets are set as a pair — pcre2api: *"both values in the offset
pairs corresponding to unused groups are set to PCRE2_UNSET."* Checking the
start is sufficient.
`end < start` requires `\K` inside a lookaround, which PCRE2 has rejected at
compile time since 10.38 (`\K is not allowed in lookarounds`) unless
`PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK` is set; ATS never calls
`pcre2_set_compile_extra_options`. With the option forced on anyway, PCRE2
clamps rather than inverting — `foo(?=bar\K)bar` on `"foobar"` yields `[6,6)`,
not `[6,3)`.
There is a real gap next to this one, though. The index is checked against
the allocated ovector count, but `pcre2_match()` writes only up to the highest
participating group, so an index past the pattern's groups reads the
uninitialized tail of `_buffer` — the UNSET check doesn't catch it. Follow-up:
#13517.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]