Re: cvs: php-src(PHP_5_2) /ext/pcre php_pcre.c /ext/pcre/tests bug37911.phpt
| From: | Arnaud Le Blanc | Date: | Fri, 08 Aug 2008 09:37:55 +0000 |
| Subject: | Re: cvs: php-src(PHP_5_2) /ext/pcre php_pcre.c /ext/pcre/tests bug37911.phpt | ||
| References: | 1 | Groups: | php.cvs |
| Request: | Send a blank email to php-cvs+get-52125@lists.php.net to get a copy of this message | ||
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=marW:—
> Ü
è8ƒ3µ¿ŸP
>kup&rev=1.1 Index: php-src/ext/pcre/tests/bug37911.phpt
> +++ php-src/ext/pcre/tests/bug37911.phpt