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=markup&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