From: Andrei Zmievski <andrei@php.net>
Date: Fri, 15 Oct 1999 16:57:54 +0000 (+0000)
Subject: (_php_replace_in_subject)
X-Git-Tag: php-4.0b3_RC2~166
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d3a39771c1320bfc030423db394a5a06a434614c;p=php

(_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
---

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 **)&regex_entry_ptr) == SUCCESS) {
-			*regex_entry = **regex_entry_ptr;
-			zval_copy_ctor(regex_entry);
-
+		while (zend_hash_get_current_data(regex->value.ht,
+										  (void **)&regex_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);
 }
 /* }}} */