How to fix a preg_match bug

This is the second time I try to fix the preg_match bug with a number 50887. The first time I tried it, less than two months ago, my solution was buggy too, and for this reason I have unpublished it.

There are many different scenarios that I didn’t take into account, but almost all of them were related to How to count expected matches of a PHP regular expression. The rest were essentially the same: I thought that the preg_match bug was affecting just the last optional match. Later I found instead that it affects really all the matches at the end, any number of them, be they optional or not. Due to this little misunderstanding I had to rewrite a big portion of the function.

{[ .fix | 1.hilite(=php=) ]}

For the function ando_preg_count_groups(…) see the post How to count expected matches of a PHP regular expression.

Minimal Tests

The following tests are based on $regex = ‘(?J:(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?)’;

.

Test 1a

{[ .test-1a-program | 1.hilite(=php=) ]}

In the next comparison we see the same result, and it really is, because
the count of expected matches equals the count of returned matches.
Array
(
    [0] => Saturday
    [DN] => Sat
    [1] => 
    [2] => 
    [3] => 
    [4] => 
    [5] => Sat
)
Array
(
    [0] => Saturday
    [DN] => Sat
    [1] => 
    [2] => 
    [3] => 
    [4] => 
    [5] => Sat
)
Test 1b

{[ .test-1b-program | 1.hilite(=php=) ]}

In the next comparison we see above that the bug applies to all the matches at the end,
and below that my fix correctly returns all expected matches, including the empty ones.
Array
(
    [0] => Tuesday
    [DN] => Tue
    [1] => 
    [2] => Tue
)
Array
(
    [0] => Tuesday
    [DN] => Tue
    [1] => 
    [2] => Tue
    [3] => 
    [4] => 
    [5] => 
)
Test 1c

{[ .test-1c-program | 1.hilite(=php=) ]}

In the next comparison we see above the bug at its extreme,
and below that my fix works as well as in the other cases.
Array
(
    [0] => 
)
Array
(
    [0] => 
    [DN] => 
    [1] => 
    [2] => 
    [3] => 
    [4] => 
    [5] => 
)

The following tests are based on $regex = ‘(?|Saturday|Sun(day)?)’;.

Test 2a

{[ .test-2a-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sun
)
Array
(
    [0] => Sun
    [1] => 
)
Test 2b

{[ .test-2b-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sunday
    [1] => day
)
Array
(
    [0] => Sunday
    [1] => day
)
Test 2c

{[ .test-2c-program | 1.hilite(=php=) ]}

Array
(
    [0] => Saturday
)
Array
(
    [0] => Saturday
    [1] => 
)

The following tests are based on $regex = ‘(?|(Sat)ur(day)|Sun(day)?)’;.

Test 3a

{[ .test-2a-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sun
)
Array
(
    [0] => Sun
    [1] => 
    [2] => 
)
Test 3b

{[ .test-2b-program | 1.hilite(=php=) ]}

Array
(
    [0] => Sunday
    [1] => day
)
Array
(
    [0] => Sunday
    [1] => day
    [2] => 
)
Test 3c

{[ .test-2c-program | 1.hilite(=php=) ]}

Array
(
    [0] => Saturday
    [1] => Sat
    [2] => day
)
Array
(
    [0] => Saturday
    [1] => Sat
    [2] => day
)

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.