diff options
author | Karl Williamson <khw@cpan.org> | 2018-11-15 10:56:31 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2018-11-17 10:02:11 -0700 |
commit | 1d8aafa0548097ffe407cad078f79b4d56fd7dca (patch) | |
tree | 5d9739d91a092f3ca1b7346a7069b340c72a0a4d | |
parent | 012b274eec07a4c9eeea66cdccf68990e896323d (diff) | |
download | perl-1d8aafa0548097ffe407cad078f79b4d56fd7dca.tar.gz |
regexec.c: Fix logic error
The function S_find_next_masked() could return a pointer to something
that wasn't wanted, returning prematurely due to a logic error I made.
This erroneous code is in 5.28.0, but I couldn't figure out any actual
bugs this caused, due to the circumstances it is called under.
The bug is I should have used 'xor' instead of complement and 'and'.
Thus trying to find 0x2f, with a mask of all F's also found 2e.
-rw-r--r-- | regexec.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -749,7 +749,7 @@ S_find_next_masked(U8 * s, const U8 * send, const U8 byte, const U8 mask) + PERL_WORDSIZE * PERL_IS_SUBWORD_ADDR(s) - (PTR2nat(s) & PERL_WORD_BOUNDARY_MASK)) { - PERL_UINTMAX_T word_complemented, mask_word; + PERL_UINTMAX_T word, mask_word; while (PTR2nat(s) & PERL_WORD_BOUNDARY_MASK) { if (((*s) & mask) == byte) { @@ -758,15 +758,17 @@ S_find_next_masked(U8 * s, const U8 * send, const U8 byte, const U8 mask) s++; } - word_complemented = ~ (PERL_COUNT_MULTIPLIER * byte); - mask_word = PERL_COUNT_MULTIPLIER * mask; + word = PERL_COUNT_MULTIPLIER * byte; + mask_word = PERL_COUNT_MULTIPLIER * mask; do { PERL_UINTMAX_T masked = (* (PERL_UINTMAX_T *) s) & mask_word; - /* If 'masked' contains 'byte' within it, anding with the - * complement will leave those 8 bits 0 */ - masked &= word_complemented; + /* If 'masked' contains bytes with the bit pattern of 'byte' within + * it, xoring with 'word' will leave each of the 8 bits in such + * bytes be 0, and no byte containing any other bit pattern will be + * 0. */ + masked ^= word; /* This causes the most significant bit to be set to 1 for any * bytes in the word that aren't completely 0 */ |