Sorry, I have accidentally committed without log.

This is a MFB of the fix for #37911 which had been fixed in 5.3 but not in 
5.2, fixes #45748.

On Friday 08 August 2008 11:34:08 Arnaud Le Blanc wrote:
> lbarnaud              Fri Aug  8 09:34:08 2008 UTC
>
>   Added files:                 (Branch: PHP_5_2)
>     /php-src/ext/pcre/tests   bug37911.phpt
>
>   Modified files:
>     /php-src/ext/pcre php_pcre.c
>   Log:
>
>
> http://cvs.php.net/viewvc.cgi/php-src/ext/pcre/php_pcre.c?r1=1.168.2.9.2.25
>&r2=1.168.2.9.2.26&diff_format=u Index: php-src/ext/pcre/php_pcre.c
> diff -u php-src/ext/pcre/php_pcre.c:1.168.2.9.2.25
> php-src/ext/pcre/php_pcre.c:1.168.2.9.2.26 ---
> php-src/ext/pcre/php_pcre.c:1.168.2.9.2.25    Wed Feb 20 22:08:18 2008 +++
> php-src/ext/pcre/php_pcre.c   Fri Aug  8 09:34:08 2008
> @@ -16,7 +16,7 @@
>    
> +----------------------------------------------------------------------+ */
>
> -/* $Id: php_pcre.c,v 1.168.2.9.2.25 2008/02/20 22:08:18 felipe Exp $ */
> +/* $Id: php_pcre.c,v 1.168.2.9.2.26 2008/08/08 09:34:08 lbarnaud Exp $ */
>
>  #include "php.h"
>  #include "php_ini.h"
> @@ -174,6 +174,50 @@
>  }
>  /* }}} */
>
> +/* {{{ static make_subpats_table */
> +static char **make_subpats_table(int num_subpats, pcre_cache_entry *pce
> TSRMLS_DC) +{
> +     pcre_extra *extra = pce->extra;
> +     int name_cnt = 0, name_size, ni = 0;
> +     int rc;
> +     char *name_table;
> +     unsigned short name_idx;
> +     char **subpat_names = (char **)ecalloc(num_subpats, sizeof(char *));
> +
> +     rc = pcre_fullinfo(pce->re, extra, PCRE_INFO_NAMECOUNT, &name_cnt);
> +     if (rc < 0) {
> +             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal 
> pcre_fullinfo()
> error %d", rc); +             efree(subpat_names);
> +             return NULL;
> +     }
> +     if (name_cnt > 0) {
> +             int rc1, rc2;
> +
> +             rc1 = pcre_fullinfo(pce->re, extra, PCRE_INFO_NAMETABLE, 
> &name_table);
> +             rc2 = pcre_fullinfo(pce->re, extra, PCRE_INFO_NAMEENTRYSIZE,
> &name_size); +                rc = rc2 ? rc2 : rc1;
> +             if (rc < 0) {
> +                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal 
> pcre_fullinfo()
> error %d", rc); +                     efree(subpat_names);
> +                     return NULL;
> +             }
> +
> +             while (ni++ < name_cnt) {
> +                     name_idx = 0xff * name_table[0] + name_table[1];
> +                     subpat_names[name_idx] = name_table + 2;
> +                     if (is_numeric_string(subpat_names[name_idx],
> strlen(subpat_names[name_idx]), NULL, NULL, 0) > 0) {
> +                             php_error_docref(NULL TSRMLS_CC, E_WARNING, 
> "Numeric named subpatterns
> are not allowed"); +                          efree(subpat_names);
> +                             return NULL;
> +                     }
> +                     name_table += name_size;
> +             }
> +     }
> +
> +     return subpat_names;
> +}
> +/* }}} */
> +
>  /* {{{ pcre_get_compiled_regex_cache
>   */
>  PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int
> regex_len TSRMLS_DC) @@ -484,7 +528,7 @@
>       int                              g_notempty = 0;        /* If the match 
> should not be empty */
>       const char         **stringlist;                /* Holds list of 
> subpatterns */
>       char                    *match;                         /* The current 
> match */
> -     char               **subpat_names = NULL;/* Array for named subpatterns 
> */
> +     char               **subpat_names;              /* Array for named 
> subpatterns */
>       int                              i, rc;
>       int                              subpats_order;         /* Order of 
> subpattern matches */
>       int                              offset_capture;    /* Capture match 
> offsets: yes/no */
> @@ -539,54 +583,19 @@
>       }
>       num_subpats++;
>       size_offsets = num_subpats * 3;
> -     offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0);
>
>       /*
>        * Build a mapping from subpattern numbers to their names. We will 
> always
>        * allocate the table, even though there may be no named subpatterns.
> This * avoids somewhat more complicated logic in the inner loops.
>        */
> -     subpat_names = (char **)safe_emalloc(num_subpats, sizeof(char *), 0);
> -     memset(subpat_names, 0, sizeof(char *) * num_subpats);
> -     {
> -             int name_cnt = 0, name_size, ni = 0;
> -             char *name_table;
> -             unsigned short name_idx;
> -
> -             rc = pcre_fullinfo(pce->re, extra, PCRE_INFO_NAMECOUNT, 
> &name_cnt);
> -             if (rc < 0) {
> -                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal 
> pcre_fullinfo()
> error %d", rc); -                     efree(offsets);
> -                     efree(subpat_names);
> -                     RETURN_FALSE;
> -             }
> -             if (name_cnt > 0) {
> -                     int rc1, rc2;
> -
> -                     rc1 = pcre_fullinfo(pce->re, extra, 
> PCRE_INFO_NAMETABLE, &name_table);
> -                     rc2 = pcre_fullinfo(pce->re, extra, 
> PCRE_INFO_NAMEENTRYSIZE,
> &name_size); -                        rc = rc2 ? rc2 : rc1;
> -                     if (rc < 0) {
> -                             php_error_docref(NULL TSRMLS_CC, E_WARNING, 
> "Internal pcre_fullinfo()
> error %d", rc); -                             efree(offsets);
> -                             efree(subpat_names);
> -                             RETURN_FALSE;
> -                     }
> -
> -                     while (ni++ < name_cnt) {
> -                             name_idx = 0xff * name_table[0] + name_table[1];
> -                             subpat_names[name_idx] = name_table + 2;
> -                             if (is_numeric_string(subpat_names[name_idx],
> strlen(subpat_names[name_idx]), NULL, NULL, 0) > 0) {
> -                                     php_error_docref(NULL TSRMLS_CC, 
> E_WARNING, "Numeric named
> subpatterns are not allowed"); -                                      
> efree(offsets);
> -                                     efree(subpat_names);
> -                                     RETURN_FALSE;
> -                             }
> -                             name_table += name_size;
> -                     }
> -             }
> +     subpat_names = make_subpats_table(num_subpats, pce TSRMLS_CC);
> +     if (!subpat_names) {
> +             RETURN_FALSE;
>       }
>
> +     offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0);
> +
>       /* Allocate match sets array and initialize the values. */
>       if (global && subpats_order == PREG_PATTERN_ORDER) {
>               match_sets = (zval **)safe_emalloc(num_subpats, sizeof(zval *), 
> 0);
> @@ -794,7 +803,7 @@
>
>  /* {{{ preg_do_repl_func
>   */
> -static int preg_do_repl_func(zval *function, char *subject, int *offsets,
> int count, char **result TSRMLS_DC) +static int preg_do_repl_func(zval
> *function, char *subject, int *offsets, char **subpat_names, int count,
> char **result TSRMLS_DC) {
>       zval            *retval_ptr;            /* Function return value */
>       zval       **args[1];                   /* Argument to pass to function 
> */
> @@ -804,8 +813,12 @@
>
>       MAKE_STD_ZVAL(subpats);
>       array_init(subpats);
> -     for (i = 0; i < count; i++)
> +     for (i = 0; i < count; i++) {
> +             if (subpat_names[i]) {
> +                     add_assoc_stringl(subpats, subpat_names[i], 
> &subject[offsets[i<<1]] ,
> offsets[(i<<1)+1] - offsets[i<<1], 1); +              }
>               add_next_index_stringl(subpats, &subject[offsets[i<<1]],
> offsets[(i<<1)+1] - offsets[i<<1], 1); +      }
>       args[0] = &subpats;
>
>       if (call_user_function_ex(EG(function_table), NULL, function,
> &retval_ptr, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { @@
> -944,6 +957,8 @@
>       int                              exoptions = 0;         /* Execution 
> options */
>       int                              count = 0;                     /* 
> Count of matched subpatterns */
>       int                             *offsets;                       /* 
> Array of subpattern offsets */
> +     char                    **subpat_names;         /* Array for named 
> subpatterns */
> +     int                              num_subpats;           /* Number of 
> captured subpatterns */
>       int                              size_offsets;          /* Size of the 
> offsets array */
>       int                              new_len;                       /* 
> Length of needed storage */
>       int                              alloc_len;                     /* 
> Actual allocated length */
> @@ -987,12 +1002,24 @@
>       }
>
>       /* Calculate the size of the offsets array, and allocate memory for it.
> */ -  rc = pcre_fullinfo(pce->re, extra, PCRE_INFO_CAPTURECOUNT,
> &size_offsets); +     rc = pcre_fullinfo(pce->re, extra,
> PCRE_INFO_CAPTURECOUNT, &num_subpats); if (rc < 0) {
>               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal 
> pcre_fullinfo()
> error %d", rc); return NULL;
>       }
> -     size_offsets = (size_offsets + 1) * 3;
> +     num_subpats++;
> +     size_offsets = num_subpats * 3;
> +
> +     /*
> +      * Build a mapping from subpattern numbers to their names. We will 
> always
> +      * allocate the table, even though there may be no named subpatterns.
> This +         * avoids somewhat more complicated logic in the inner loops.
> +      */
> +     subpat_names = make_subpats_table(num_subpats, pce TSRMLS_CC);
> +     if (!subpat_names) {
> +             return NULL;
> +     }
> +
>       offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0);
>
>       alloc_len = 2 * subject_len + 1;
> @@ -1033,8 +1060,7 @@
>                               new_len += eval_result_len;
>                       } else if (is_callable_replace) {
>                               /* Use custom function to get replacement 
> string and its length. */
> -                             eval_result_len = 
> preg_do_repl_func(replace_val, subject, offsets,
> -                                                                             
>                         count, &eval_result TSRMLS_CC);
> +                             eval_result_len = 
> preg_do_repl_func(replace_val, subject, offsets,
> subpat_names, count, &eval_result TSRMLS_CC); new_len += eval_result_len;
>                       } else { /* do regular substitution */
>                               walk = replace;
> @@ -1149,8 +1175,9 @@
>               /* Advance to the next piece. */
>               start_offset = offsets[1];
>       }
> -
> +
>       efree(offsets);
> +     efree(subpat_names);
>
>       return result;
>  }
>
> http://cvs.php.net/viewvc.cgi/php-src/ext/pcre/tests/bug37911.phpt?view=mar
>kup&rev=1.1 Index: php-src/ext/pcre/tests/bug37911.phpt
> +++ php-src/ext/pcre/tests/bug37911.phpt


-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to