@@ -987,7 +987,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, size_t sub
987
987
* match_sets = NULL ; /* An array of sets of matches for each
988
988
subpattern after a global match */
989
989
uint32_t options ; /* Execution options */
990
- int count = 0 ; /* Count of matched subpatterns */
990
+ int count ; /* Count of matched subpatterns */
991
991
PCRE2_SIZE * offsets ; /* Array of subpattern offsets */
992
992
uint32_t num_subpats ; /* Number of captured subpatterns */
993
993
int matched ; /* Has anything matched */
@@ -1510,7 +1510,7 @@ PHPAPI zend_string *php_pcre_replace(zend_string *regex,
1510
1510
PHPAPI zend_string * php_pcre_replace_impl (pcre_cache_entry * pce , zend_string * subject_str , char * subject , size_t subject_len , zend_string * replace_str , size_t limit , size_t * replace_count )
1511
1511
{
1512
1512
uint32_t options ; /* Execution options */
1513
- int count = 0 ; /* Count of matched subpatterns */
1513
+ int count ; /* Count of matched subpatterns */
1514
1514
PCRE2_SIZE * offsets ; /* Array of subpattern offsets */
1515
1515
char * * subpat_names ; /* Array for named subpatterns */
1516
1516
uint32_t num_subpats ; /* Number of captured subpatterns */
@@ -1685,9 +1685,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
1685
1685
result_len += (walkbuf - (ZSTR_VAL (result ) + result_len ));
1686
1686
}
1687
1687
1688
- if (limit ) {
1689
- limit -- ;
1690
- }
1688
+ limit -- ;
1691
1689
1692
1690
/* Advance to the next piece. */
1693
1691
start_offset = offsets [1 ];
@@ -1760,7 +1758,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
1760
1758
static zend_string * php_pcre_replace_func_impl (pcre_cache_entry * pce , zend_string * subject_str , char * subject , size_t subject_len , zend_fcall_info * fci , zend_fcall_info_cache * fcc , size_t limit , size_t * replace_count )
1761
1759
{
1762
1760
uint32_t options ; /* Execution options */
1763
- int count = 0 ; /* Count of matched subpatterns */
1761
+ int count ; /* Count of matched subpatterns */
1764
1762
PCRE2_SIZE * offsets ; /* Array of subpattern offsets */
1765
1763
char * * subpat_names ; /* Array for named subpatterns */
1766
1764
uint32_t num_subpats ; /* Number of captured subpatterns */
@@ -1770,9 +1768,8 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
1770
1768
char * match , /* The current match */
1771
1769
* piece ; /* The current piece of subject */
1772
1770
size_t result_len ; /* Length of result */
1773
- PCRE2_SPTR mark = NULL ; /* Target for MARK name */
1774
1771
zend_string * result ; /* Result of replacement */
1775
- zend_string * eval_result = NULL ; /* Result of custom function */
1772
+ zend_string * eval_result ; /* Result of custom function */
1776
1773
pcre2_match_data * match_data ;
1777
1774
zend_bool old_mdata_used ;
1778
1775
@@ -1834,8 +1831,6 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
1834
1831
1835
1832
piece = subject + start_offset ;
1836
1833
1837
- mark = pcre2_get_mark (match_data );
1838
-
1839
1834
if (count >= 0 && limit ) {
1840
1835
/* Check for too many substrings condition. */
1841
1836
if (UNEXPECTED (count == 0 )) {
@@ -1864,7 +1859,9 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
1864
1859
new_len = result_len + offsets [0 ] - start_offset ; /* part before the match */
1865
1860
1866
1861
/* Use custom function to get replacement string and its length. */
1867
- eval_result = preg_do_repl_func (fci , fcc , subject , offsets , subpat_names , count , mark );
1862
+ eval_result = preg_do_repl_func (fci , fcc , subject , offsets , subpat_names , count ,
1863
+ pcre2_get_mark (match_data ));
1864
+
1868
1865
ZEND_ASSERT (eval_result );
1869
1866
new_len = zend_safe_address_guarded (1 , ZSTR_LEN (eval_result ), new_len );
1870
1867
if (new_len >= alloc_len ) {
@@ -1887,9 +1884,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
1887
1884
result_len += ZSTR_LEN (eval_result );
1888
1885
zend_string_release_ex (eval_result , 0 );
1889
1886
1890
- if (limit ) {
1891
- limit -- ;
1892
- }
1887
+ limit -- ;
1893
1888
1894
1889
/* Advance to the next piece. */
1895
1890
start_offset = offsets [1 ];
@@ -2435,7 +2430,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str,
2435
2430
{
2436
2431
PCRE2_SIZE * offsets ; /* Array of subpattern offsets */
2437
2432
uint32_t options ; /* Execution options */
2438
- int count = 0 ; /* Count of matched subpatterns */
2433
+ int count ; /* Count of matched subpatterns */
2439
2434
PCRE2_SIZE start_offset ; /* Where the new search starts */
2440
2435
PCRE2_SIZE next_offset ; /* End of the last delimiter match + 1 */
2441
2436
char * last_match ; /* Location of last match */
@@ -2763,7 +2758,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
2763
2758
{
2764
2759
zval * entry ; /* An entry in the input array */
2765
2760
uint32_t num_subpats ; /* Number of captured subpatterns */
2766
- int count = 0 ; /* Count of matched subpatterns */
2761
+ int count ; /* Count of matched subpatterns */
2767
2762
uint32_t options ; /* Execution options */
2768
2763
zend_string * string_key ;
2769
2764
zend_ulong num_key ;
@@ -2794,7 +2789,8 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
2794
2789
2795
2790
/* Go through the input array */
2796
2791
ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P (input ), num_key , string_key , entry ) {
2797
- zend_string * subject_str = zval_get_string (entry );
2792
+ zend_string * tmp_subject_str ;
2793
+ zend_string * subject_str = zval_get_tmp_string (entry , & tmp_subject_str );
2798
2794
2799
2795
/* Perform the match */
2800
2796
#ifdef HAVE_PCRE_JIT_SUPPORT
@@ -2807,27 +2803,39 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
2807
2803
options , match_data , mctx );
2808
2804
2809
2805
/* If the entry fits our requirements */
2810
- if (( count >= 0 && ! invert ) || ( count == PCRE2_ERROR_NOMATCH && invert ) ) {
2806
+ if (count >= 0 ) {
2811
2807
/* Check for too many substrings condition. */
2812
2808
if (UNEXPECTED (count == 0 )) {
2813
2809
php_error_docref (NULL , E_NOTICE , "Matched, but too many substrings" );
2814
- count = num_subpats ;
2815
2810
}
2816
- Z_TRY_ADDREF_P (entry );
2811
+ if (!invert ) {
2812
+ Z_TRY_ADDREF_P (entry );
2817
2813
2818
- /* Add to return array */
2819
- if (string_key ) {
2820
- zend_hash_update (Z_ARRVAL_P (return_value ), string_key , entry );
2821
- } else {
2822
- zend_hash_index_update (Z_ARRVAL_P (return_value ), num_key , entry );
2814
+ /* Add to return array */
2815
+ if (string_key ) {
2816
+ zend_hash_update (Z_ARRVAL_P (return_value ), string_key , entry );
2817
+ } else {
2818
+ zend_hash_index_update (Z_ARRVAL_P (return_value ), num_key , entry );
2819
+ }
2823
2820
}
2824
- } else if (count < 0 && count != PCRE2_ERROR_NOMATCH ) {
2821
+ } else if (count == PCRE2_ERROR_NOMATCH ) {
2822
+ if (invert ) {
2823
+ Z_TRY_ADDREF_P (entry );
2824
+
2825
+ /* Add to return array */
2826
+ if (string_key ) {
2827
+ zend_hash_update (Z_ARRVAL_P (return_value ), string_key , entry );
2828
+ } else {
2829
+ zend_hash_index_update (Z_ARRVAL_P (return_value ), num_key , entry );
2830
+ }
2831
+ }
2832
+ } else {
2825
2833
pcre_handle_exec_error (count );
2826
- zend_string_release_ex ( subject_str , 0 );
2834
+ zend_tmp_string_release ( tmp_subject_str );
2827
2835
break ;
2828
2836
}
2829
2837
2830
- zend_string_release_ex ( subject_str , 0 );
2838
+ zend_tmp_string_release ( tmp_subject_str );
2831
2839
} ZEND_HASH_FOREACH_END ();
2832
2840
if (match_data != mdata ) {
2833
2841
pcre2_match_data_free (match_data );
0 commit comments