This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regexec.c: Remove some read beyond buffer ends
authorKarl Williamson <public@khwilliamson.com>
Wed, 19 Dec 2012 17:28:29 +0000 (10:28 -0700)
committerKarl Williamson <public@khwilliamson.com>
Wed, 19 Dec 2012 18:04:10 +0000 (11:04 -0700)
commit9a902117f5d8a3ebc669e3a90eeb7cee78286a33
tree7b6d2b1da596c055654638c8b45d5f5d86c2b78a
parentbfd14e5219e2beca5044738e1e721818ee9d28c6
regexec.c: Remove some read beyond buffer ends

It turns out that this paradigm used in several places in regexec.c is
wrong:

while (s + (len = UTF8SKIP(s)) <= PL_regeol) {
    ...
    s += len;
}

The reason it is wrong is that PL_regeol points to one past the end, and
this will inevitably end up reading the character at PL_regeol, which is
hence out-of-bounds.  I don't know how many times I've looked at this
code and missed this, but valgrind found it after I tried Dave
Mitchell's hack to remove the trailing NUL for testing purposes.

The way to make sure that there isn't malformed UTF-8 pointing us to
read too far would be:

while (s < PL_regeol && s + (len = UTF8SKIP(s)) <= PL_regeol) {}

This commit converts the one place that uses this safe thing to the
others:

while (s < PL_regeol) {}

In many places (but not all) in this file, we assume that the input is
well formed.  If we're going to be paranoid, it seems to me we should do
it consistently.  So I've converted this one relevant instance of
paranoia to not be, to be in line with the rest of the code.
regexec.c