mirror of
https://github.com/php/php-src.git
synced 2024-11-28 20:34:29 +08:00
Merge branch 'PHP-5.6'
* PHP-5.6: Fix #70232: Incorrect bump-along behavior with \K and empty string match Resolved conflicts: ext/pcre/php_pcre.c
This commit is contained in:
commit
1ec40e84d4
@ -44,6 +44,11 @@
|
||||
|
||||
#define PCRE_CACHE_SIZE 4096
|
||||
|
||||
/* not fully functional workaround for libpcre < 8.0, see bug #70232 */
|
||||
#ifndef PCRE_NOTEMPTY_ATSTART
|
||||
# define PCRE_NOTEMPTY_ATSTART PCRE_NOTEMPTY
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PHP_PCRE_NO_ERROR = 0,
|
||||
PHP_PCRE_INTERNAL_ERROR,
|
||||
@ -876,7 +881,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
|
||||
pcre_free((void *) stringlist);
|
||||
}
|
||||
} else if (count == PCRE_ERROR_NOMATCH) {
|
||||
/* If we previously set PCRE_NOTEMPTY after a null match,
|
||||
/* If we previously set PCRE_NOTEMPTY_ATSTART after a null match,
|
||||
this is not necessarily the end. We need to advance
|
||||
the start offset, and continue. Fudge the offset values
|
||||
to achieve this, unless we're already at the end of the string. */
|
||||
@ -893,10 +898,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
|
||||
}
|
||||
|
||||
/* If we have matched an empty string, mimic what Perl's /g options does.
|
||||
This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try
|
||||
This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try
|
||||
the match again at the same point. If this fails (picked up above) we
|
||||
advance to the next character. */
|
||||
g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0;
|
||||
g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0;
|
||||
|
||||
/* Advance to the position right after the last full match */
|
||||
start_offset = offsets[1];
|
||||
@ -1271,7 +1276,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
||||
limit--;
|
||||
}
|
||||
} else if (count == PCRE_ERROR_NOMATCH || UNEXPECTED(limit == 0)) {
|
||||
/* If we previously set PCRE_NOTEMPTY after a null match,
|
||||
/* If we previously set PCRE_NOTEMPTY_ATSTART after a null match,
|
||||
this is not necessarily the end. We need to advance
|
||||
the start offset, and continue. Fudge the offset values
|
||||
to achieve this, unless we're already at the end of the string. */
|
||||
@ -1313,10 +1318,10 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
||||
}
|
||||
|
||||
/* If we have matched an empty string, mimic what Perl's /g options does.
|
||||
This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try
|
||||
This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try
|
||||
the match again at the same point. If this fails (picked up above) we
|
||||
advance to the next character. */
|
||||
g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0;
|
||||
g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0;
|
||||
|
||||
/* Advance to the next piece. */
|
||||
start_offset = offsets[1];
|
||||
@ -1815,7 +1820,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec
|
||||
}
|
||||
}
|
||||
} else if (count == PCRE_ERROR_NOMATCH) {
|
||||
/* If we previously set PCRE_NOTEMPTY after a null match,
|
||||
/* If we previously set PCRE_NOTEMPTY_ATSTART after a null match,
|
||||
this is not necessarily the end. We need to advance
|
||||
the start offset, and continue. Fudge the offset values
|
||||
to achieve this, unless we're already at the end of the string. */
|
||||
@ -1849,10 +1854,10 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec
|
||||
}
|
||||
|
||||
/* If we have matched an empty string, mimic what Perl's /g options does.
|
||||
This turns out to be rather cunning. First we set PCRE_NOTEMPTY and try
|
||||
This turns out to be rather cunning. First we set PCRE_NOTEMPTY_ATSTART and try
|
||||
the match again at the same point. If this fails (picked up above) we
|
||||
advance to the next character. */
|
||||
g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY | PCRE_ANCHORED : 0;
|
||||
g_notempty = (offsets[1] == offsets[0])? PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED : 0;
|
||||
|
||||
/* Advance to the position right after the last full match */
|
||||
start_offset = offsets[1];
|
||||
|
68
ext/pcre/tests/bug70232.phpt
Normal file
68
ext/pcre/tests/bug70232.phpt
Normal file
@ -0,0 +1,68 @@
|
||||
--TEST--
|
||||
Bug #70232 (Incorrect bump-along behavior with \K and empty string match)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (version_compare(explode(' ', PCRE_VERSION)[0], '8.0', 'lt')) {
|
||||
die("skip this test requires libpcre >= 8.0");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$pattern = '~(?: |\G)\d\B\K~';
|
||||
$subject = "123 a123 1234567 b123 123";
|
||||
preg_match_all($pattern, $subject, $matches);
|
||||
var_dump($matches);
|
||||
var_dump(preg_replace($pattern, "*", $subject));
|
||||
var_dump(preg_split($pattern, $subject));
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(10) {
|
||||
[0]=>
|
||||
string(0) ""
|
||||
[1]=>
|
||||
string(0) ""
|
||||
[2]=>
|
||||
string(0) ""
|
||||
[3]=>
|
||||
string(0) ""
|
||||
[4]=>
|
||||
string(0) ""
|
||||
[5]=>
|
||||
string(0) ""
|
||||
[6]=>
|
||||
string(0) ""
|
||||
[7]=>
|
||||
string(0) ""
|
||||
[8]=>
|
||||
string(0) ""
|
||||
[9]=>
|
||||
string(0) ""
|
||||
}
|
||||
}
|
||||
string(35) "1*2*3 a123 1*2*3*4*5*6*7 b123 1*2*3"
|
||||
array(11) {
|
||||
[0]=>
|
||||
string(1) "1"
|
||||
[1]=>
|
||||
string(1) "2"
|
||||
[2]=>
|
||||
string(8) "3 a123 1"
|
||||
[3]=>
|
||||
string(1) "2"
|
||||
[4]=>
|
||||
string(1) "3"
|
||||
[5]=>
|
||||
string(1) "4"
|
||||
[6]=>
|
||||
string(1) "5"
|
||||
[7]=>
|
||||
string(1) "6"
|
||||
[8]=>
|
||||
string(8) "7 b123 1"
|
||||
[9]=>
|
||||
string(1) "2"
|
||||
[10]=>
|
||||
string(1) "3"
|
||||
}
|
Loading…
Reference in New Issue
Block a user