Bug #73948 [Opn->Ana]: Preg_match_all should return NULLs on trailing optional capture groups.

From: Date: Tue, 17 Jan 2017 13:28:23 +0000
Subject: Bug #73948 [Opn->Ana]: Preg_match_all should return NULLs on trailing optional capture groups.
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-206710@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73948&edit=1

 ID:                 73948
 Updated by:         cmb@php.net
 Reported by:        tomasyorke at hotmail dot com
 Summary:            Preg_match_all should return NULLs on trailing
                     optional capture groups.
-Status:             Open
+Status:             Analyzed
 Type:               Bug
 Package:            PCRE related
 Operating System:   Windows 7
 PHP Version:        7.0.14
 Block user comment: N
 Private report:     N

 New Comment:

For PREG_PATTERN_ORDER unmatched subpatterns are already added[1];
something like that would also have to be done for PREG_SET_ORDER.

However, that would cause BC issues, and adding another flag isn't
appealing to me. I also think that NULL and unset are close enough
to stick with the current behavior for now; checking isset()
would suffice.

[1] <https://github.com/php/php-src/blob/PHP-7.1.0/ext/pcre/php_pcre.c#L862-L871>


Previous Comments:
------------------------------------------------------------------------
[2017-01-16 15:50:23] requinix@php.net

Actually I can. Yay for Linux on Windows!

~/php/master/bin# ./php
<?php var_dump(preg_match('/(a)?(b)?(c)?/', 'b', $matches), $matches);
int(1)
array(3) {
  [0]=>
  string(1) "b"
  [1]=>
  NULL
  [2]=>
  string(1) "b"
}

[1] is clearly NULL but there is no [3] for the unmatched (c)? group.

------------------------------------------------------------------------
[2017-01-16 14:57:13] requinix@php.net

Hmm, yes, I misunderstood this report: 61780 is about turning empty strings from unmatched
subpatterns into NULLs while this is about *adding* trailing unmatched subpatterns.
I don't see anything in the 61780 changes that clearly indicate this is also fixed, but some
parts look like they might do it accidentally. Can anyone check? (It'd be nice if 3v4l could do
master too...)

------------------------------------------------------------------------
[2017-01-16 14:40:41] nikic@php.net

Not sure if it's quite a duplicate. IIRC we now use null instead of "" if unmatched,
but we still don't fill up null values at the end.

------------------------------------------------------------------------
[2017-01-16 14:38:08] requinix@php.net

Duplicate of bug #61780, fixed in master. (unmatched groups will be NULL)

------------------------------------------------------------------------
[2017-01-16 14:24:55] tomasyorke at hotmail dot com

Description:
------------
Using preg_match_all with the PREG_SET_ORDER flag and an optional capture group might return either
an empty string or a missing element. 

This depends on whether there is a matched capture group after the non-matched capture group.

From an interface perspective, this means that I have to check for two representations to test
whether an optional capture group was matched.

The test script demonstrates such a case.

When considering a fix, the first priority should be that whatever the representation is (NULL, an
empty string or a missing element.),  it should be consistent, no matter if there is a matched
capture group after or not.

If this cannot be fixed due to backwards compatibility Issues. Could we add a PREG_KEEP_NONMATCHES
or PREG_SET_ORDER_2 flag?


Test script:
---------------
<?php

preg_match_all("#(a)?(b)(c)?#","b",$matches,PREG_SET_ORDER);

var_dump($matches);

Expected result:
----------------
array(1) {
  [0] => array(3) {
    [0] => string(1) "b" [1] => string(0) "" [2] => string(1)
"b" [3] => string(0) ""
  }
}

Actual result:
--------------
array(1) {
  [0] => array(3) {
    [0] => string(1) "b" [1] => string(0) "" [2] => string(1)
"b"
  }
}


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=73948&edit=1


Thread (19 messages)

« previous php.bugs (#206710) next »