From d3a39771c1320bfc030423db394a5a06a434614c Mon Sep 17 00:00:00 2001 From: Andrei Zmievski Date: Fri, 15 Oct 1999 16:57:54 +0000 Subject: [PATCH] (_php_replace_in_subject) (PHP preg_replace): Fixed a bug that happened when regex was an array and replacement was a single non-string value. Also changed conversions to use convert_to_string_ex(). (PHP preg_grep): use convert_to_string_ex() for proper conversion --- ext/pcre/php_pcre.c | 108 +++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 66 deletions(-) diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 1e6522427b..02b0fc52de 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -768,56 +768,47 @@ char *_php_pcre_replace(char *regex, char *subject, char *replace) /* }}} */ -static char *_php_replace_in_subject(zval *regex, zval *replace, zval *subject) +static char *_php_replace_in_subject(zval *regex, zval *replace, zval **subject) { - zval **regex_entry_ptr, - *regex_entry, - **replace_entry_ptr, - *replace_entry = NULL; + zval **regex_entry, + **replace_entry = NULL; char *replace_value = NULL, *subject_value, *result; /* Make sure we're dealing with strings. */ - convert_to_string(subject); + convert_to_string_ex(subject); /* If regex is an array */ if (regex->type == IS_ARRAY) { /* Duplicating subject string for repeated replacement */ - subject_value = estrdup(subject->value.str.val); + subject_value = estrdup((*subject)->value.str.val); zend_hash_internal_pointer_reset(regex->value.ht); if (replace->type == IS_ARRAY) { zend_hash_internal_pointer_reset(replace->value.ht); - MAKE_STD_ZVAL(replace_entry); } else /* Set replacement value to the passed one */ replace_value = replace->value.str.val; - MAKE_STD_ZVAL(regex_entry); - /* For each entry in the regex array, get the entry */ - while (zend_hash_get_current_data(regex->value.ht, (void **)®ex_entry_ptr) == SUCCESS) { - *regex_entry = **regex_entry_ptr; - zval_copy_ctor(regex_entry); - + while (zend_hash_get_current_data(regex->value.ht, + (void **)®ex_entry) == SUCCESS) { /* Make sure we're dealing with strings. */ - convert_to_string(regex_entry); + convert_to_string_ex(regex_entry); /* If replace is an array */ if (replace->type == IS_ARRAY) { /* Get current entry */ - if (zend_hash_get_current_data(replace->value.ht, (void **)&replace_entry_ptr) == SUCCESS) { - *replace_entry = **replace_entry_ptr; - zval_copy_ctor(replace_entry); - + if (zend_hash_get_current_data(replace->value.ht, + (void **)&replace_entry) == SUCCESS) { /* Make sure we're dealing with strings. */ - convert_to_string(replace_entry); + convert_to_string_ex(replace_entry); /* Set replacement value to the one we got from array */ - replace_value = replace_entry->value.str.val; + replace_value = (*replace_entry)->value.str.val; zend_hash_move_forward(replace->value.ht); } @@ -828,31 +819,21 @@ static char *_php_replace_in_subject(zval *regex, zval *replace, zval *subject) /* Do the actual replacement and put the result back into subject_value for further replacements. */ - if ((result = _php_pcre_replace(regex_entry->value.str.val, + if ((result = _php_pcre_replace((*regex_entry)->value.str.val, subject_value, replace_value)) != NULL) { efree(subject_value); subject_value = result; } - if (replace->type == IS_ARRAY) - zval_dtor(replace_entry); - zval_dtor(regex_entry); zend_hash_move_forward(regex->value.ht); } - if (replace->type == IS_ARRAY) - efree(replace_entry); - efree(regex_entry); return subject_value; - } - else { - /* Make sure we're dealing with strings and do the replacement */ - convert_to_string(regex); - convert_to_string(replace); + } else { result = _php_pcre_replace(regex->value.str.val, - subject->value.str.val, - replace->value.str.val); + (*subject)->value.str.val, + replace->value.str.val); return result; } } @@ -865,8 +846,7 @@ PHP_FUNCTION(preg_replace) zval **regex, **replace, **subject, - **subject_entry_ptr, - *subject_entry; + **subject_entry; char *result; char *string_key; ulong num_key; @@ -876,19 +856,26 @@ PHP_FUNCTION(preg_replace) WRONG_PARAM_COUNT; } + SEPARATE_ZVAL(regex); + SEPARATE_ZVAL(replace); + SEPARATE_ZVAL(subject); + + /* Make sure we're dealing with strings and do the replacement */ + if ((*regex)->type != IS_ARRAY) { + convert_to_string_ex(regex); + convert_to_string_ex(replace); + } else if ((*replace)->type != IS_ARRAY) + convert_to_string_ex(replace); + /* if subject is an array */ if ((*subject)->type == IS_ARRAY) { array_init(return_value); zend_hash_internal_pointer_reset((*subject)->value.ht); - MAKE_STD_ZVAL(subject_entry); - /* For each subject entry, convert it to string, then perform replacement and add the result to the return_value array. */ - while (zend_hash_get_current_data((*subject)->value.ht, (void **)&subject_entry_ptr) == SUCCESS) { - *subject_entry = **subject_entry_ptr; - zval_copy_ctor(subject_entry); - + while (zend_hash_get_current_data((*subject)->value.ht, + (void **)&subject_entry) == SUCCESS) { if ((result = _php_replace_in_subject(*regex, *replace, subject_entry)) != NULL) { /* Add to return array */ @@ -905,15 +892,11 @@ PHP_FUNCTION(preg_replace) } } - zval_dtor(subject_entry); - zend_hash_move_forward((*subject)->value.ht); } - - efree(subject_entry); } else { /* if subject is not an array */ - if ((result = _php_replace_in_subject(*regex, *replace, *subject)) != NULL) { + if ((result = _php_replace_in_subject(*regex, *replace, subject)) != NULL) { RETVAL_STRING(result, 1); efree(result); } @@ -1114,8 +1097,7 @@ PHP_FUNCTION(preg_grep) { zval **regex, /* Regular expression */ **input, /* Input array */ - *entry, /* A copy of the entry in the input array */ - **entry_ptr; /* An entry in the input array */ + **entry; /* An entry in the input array */ pcre *re = NULL; /* Compiled regular expression */ pcre_extra *extra = NULL; /* Holds results of studying */ int preg_options = 0; /* Custom preg options */ @@ -1135,6 +1117,8 @@ PHP_FUNCTION(preg_grep) zend_error(E_WARNING, "Secong argument to preg_grep() should be an array"); return; } + + SEPARATE_ZVAL(input); /* Make sure regex is a string */ convert_to_string_ex(regex); @@ -1151,21 +1135,15 @@ PHP_FUNCTION(preg_grep) /* Initialize return array */ array_init(return_value); - /* Allocate entry storage */ - entry = (zval *)emalloc(sizeof(zval)); - /* Go through the input array */ zend_hash_internal_pointer_reset((*input)->value.ht); - while(zend_hash_get_current_data((*input)->value.ht, (void **)&entry_ptr) == SUCCESS) { + while(zend_hash_get_current_data((*input)->value.ht, (void **)&entry) == SUCCESS) { + + convert_to_string_ex(entry); - /* Copy entry and convert to string */ - *entry = **entry_ptr; - zval_copy_ctor(entry); - convert_to_string(entry); - /* Perform the match */ - count = pcre_exec(re, extra, entry->value.str.val, - entry->value.str.len, 0, + count = pcre_exec(re, extra, (*entry)->value.str.val, + (*entry)->value.str.len, 0, 0, offsets, size_offsets); /* Check for too many substrings condition. */ @@ -1176,30 +1154,28 @@ PHP_FUNCTION(preg_grep) /* If something matched */ if (count > 0) { - (*entry_ptr)->refcount++; + (*entry)->refcount++; /* Add to return array */ switch(zend_hash_get_current_key((*input)->value.ht, &string_key, &num_key)) { case HASH_KEY_IS_STRING: zend_hash_update(return_value->value.ht, string_key, - strlen(string_key)+1, entry_ptr, sizeof(zval *), NULL); + strlen(string_key)+1, entry, sizeof(zval *), NULL); efree(string_key); break; case HASH_KEY_IS_LONG: - zend_hash_next_index_insert(return_value->value.ht, entry_ptr, + zend_hash_next_index_insert(return_value->value.ht, entry, sizeof(zval *), NULL); break; } } - zval_dtor(entry); zend_hash_move_forward((*input)->value.ht); } /* Clean up */ - efree(entry); efree(offsets); } /* }}} */ -- 2.40.0