re_intuit_start(): skip too short variant utf8 pat
authorDavid Mitchell <davem@iabyn.com>
Sun, 3 Dec 2017 16:38:37 +0000 (16:38 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sun, 3 Dec 2017 17:57:37 +0000 (17:57 +0000)
commit2ce94a867b15d96bd49eb8807d39df950f3a1087
tree722fe9fd09dc7138e71d1cfc19e3b59cd6b47d79
parent4f193c3e96af4b9697510e396fb5e944776d38fb
re_intuit_start(): skip too short variant utf8 pat

RT #132187

This function searches in the target string for known fixed substrings
of the pattern, either to quickly reject the match, or to find a minimum
start point at which to run the full regex engine.

If the target string is utf8 and the pattern is non-utf8 but contains
chars in the rang 0x80-0xff, the fixed substring to be searched for will
be upgraded to utf8, which causes its length to grow. This can defeat an
early quick rejection test of: "is the known substring longer than the
target string", because that check is done before the upgrade.

It can also trigger the bug reported in the ticket above: a calculation
of the maximum end-point within the target string to find the substring
goes wrong, because (endpoint - N1) gets limited to the start point (since
N1 is longer than the string length), and so the moral equivalent of
((endpoint - N1) + N2) then disappears off the end of the string.

The net effect of this bug is that a few bytes off the end of the string
may be read, triggering complaints by ASAN etc, or even a SEGV.

It makes no difference to the match (which should fail and does fail),
except that it might match slower in the unlikely event that the bytes off
the end of the string match that tail of the searched-for substring, in
which case the full regex engine has to be run to finally reject it.

This commit:

1) adds a second length(substr) > length(target string) check
 at the point its going to run the FBM substring search;
2) it tidies up the code that moves the endpoint back, skipping
an expensive utf8 hop-back in more cases.
regexec.c
t/re/re_tests