dmitry Wed, 16 Dec 2009 11:15:22 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=292195
Log:
Fixed str_replace() to work with both binary and unicode strings
Changed paths:
U php/php-src/trunk/ext/standard/string.c
Modified: php/php-src/trunk/ext/standard/string.c
===================================================================
--- php/php-src/trunk/ext/standard/string.c 2009-12-16 10:49:54 UTC (rev
292194)
+++ php/php-src/trunk/ext/standard/string.c 2009-12-16 11:15:22 UTC (rev
292195)
@@ -5402,17 +5402,25 @@
static void php_str_replace_in_subject(zval *search, zval *replace, zval
**subject, zval *result, int case_sensitivity, int *replace_count TSRMLS_DC)
{
zval **search_entry,
- **replace_entry = NULL,
+ **replace_entry,
+ *replace_value,
+ temp_replace,
temp_result;
- zstr replace_value = NULL_ZSTR;
- int replace_len = 0;
/* Make sure we're dealing with strings. */
- convert_to_unicode_ex(subject);
- Z_TYPE_P(result) = IS_UNICODE;
- if (Z_UNILEN_PP(subject) == 0) {
- ZVAL_EMPTY_UNICODE(result);
- return;
+ if (Z_TYPE_PP(subject) == IS_STRING) {
+ Z_TYPE_P(result) = IS_STRING;
+ if (Z_UNILEN_PP(subject) == 0) {
+ ZVAL_EMPTY_STRING(result);
+ return;
+ }
+ } else {
+ convert_to_unicode_ex(subject);
+ Z_TYPE_P(result) = IS_UNICODE;
+ if (Z_UNILEN_PP(subject) == 0) {
+ ZVAL_EMPTY_UNICODE(result);
+ return;
+ }
}
/* If search is an array */
@@ -5426,15 +5434,13 @@
zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace));
} else {
/* Set replacement value to the passed one */
- replace_value = Z_UNIVAL_P(replace);
- replace_len = Z_UNILEN_P(replace);
+ replace_value = replace;
}
/* For each entry in the search array, get the entry */
while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **)
&search_entry) == SUCCESS) {
/* Make sure we're dealing with strings. */
SEPARATE_ZVAL(search_entry);
- convert_to_unicode(*search_entry);
if (Z_UNILEN_PP(search_entry) == 0) {
zend_hash_move_forward(Z_ARRVAL_P(search));
if (Z_TYPE_P(replace) == IS_ARRAY) {
@@ -5447,47 +5453,23 @@
if (Z_TYPE_P(replace) == IS_ARRAY) {
/* Get current entry */
if
(zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) ==
SUCCESS) {
- /* Make sure we're dealing with
strings. */
SEPARATE_ZVAL(replace_entry);
- convert_to_unicode(*replace_entry);
-
- /* Set replacement value to the one we
got from array */
- replace_value =
Z_UNIVAL_PP(replace_entry);
- replace_len =
Z_UNILEN_PP(replace_entry);
-
+ replace_value = *replace_entry;
zend_hash_move_forward(Z_ARRVAL_P(replace));
} else {
/* We've run out of replacement
strings, so use an empty one. */
- replace_value = EMPTY_ZSTR;
- replace_len = 0;
+ replace_value = &temp_replace;
+ Z_UNILEN_P(replace_value) = 0;
+ Z_UNIVAL_P(replace_value) = EMPTY_ZSTR;
+ if (Z_TYPE_PP(subject) == IS_STRING) {
+ Z_TYPE_P(replace_value) =
IS_STRING;
+ } else {
+ Z_TYPE_P(replace_value) =
IS_UNICODE;
+ }
}
}
- if (Z_UNILEN_PP(search_entry) == 1) {
- if (case_sensitivity) {
-
php_u_char_to_str_ex(Z_USTRVAL_P(result), Z_USTRLEN_P(result),
-
Z_USTRVAL_PP(search_entry)[0],
-
replace_value.u, replace_len,
-
&temp_result, replace_count);
- } else {
- Z_USTRVAL(temp_result) =
php_u_str_to_str_case_ex(Z_USTRVAL_P(result), Z_USTRLEN_P(result),
-
Z_USTRVAL_PP(search_entry), Z_USTRLEN_PP(search_entry),
-
replace_value.u,
replace_len,
-
&Z_USTRLEN(temp_result), replace_count TSRMLS_CC);
- }
- } else if (Z_UNILEN_PP(search_entry) > 1) {
- if (case_sensitivity) {
- Z_USTRVAL(temp_result) =
php_u_str_to_str_ex(Z_USTRVAL_P(result), Z_USTRLEN_P(result),
-
Z_USTRVAL_PP(search_entry),
Z_USTRLEN_PP(search_entry),
-
replace_value.u, replace_len,
-
&Z_USTRLEN(temp_result),
replace_count);
- } else {
- Z_USTRVAL(temp_result) =
php_u_str_to_str_case_ex(Z_USTRVAL_P(result), Z_USTRLEN_P(result),
-
Z_USTRVAL_PP(search_entry), Z_USTRLEN_PP(search_entry),
-
replace_value.u,
replace_len,
-
&Z_USTRLEN(temp_result), replace_count TSRMLS_CC);
- }
- }
+ php_str_replace_in_subject(*search_entry,
replace_value, &result, &temp_result, case_sensitivity, replace_count
TSRMLS_CC);
efree(Z_UNIVAL_P(result).v);
Z_UNIVAL_P(result) = Z_UNIVAL(temp_result);
@@ -5500,32 +5482,55 @@
zend_hash_move_forward(Z_ARRVAL_P(search));
}
} else {
- if (Z_UNILEN_P(search) == 1) {
- if (case_sensitivity) {
- php_u_char_to_str_ex(Z_USTRVAL_PP(subject),
Z_USTRLEN_PP(subject),
-
Z_USTRVAL_P(search)[0],
-
Z_USTRVAL_P(replace), Z_USTRLEN_P(replace),
-
result, replace_count);
+ if (Z_TYPE_PP(subject) == IS_STRING) {
+ convert_to_string(search);
+ convert_to_string(replace);
+ if (Z_STRLEN_P(search) == 1) {
+ php_char_to_str_ex(Z_STRVAL_PP(subject),
+
Z_STRLEN_PP(subject),
+
Z_STRVAL_P(search)[0],
+
Z_STRVAL_P(replace),
+
Z_STRLEN_P(replace),
+ result,
+
case_sensitivity,
+ replace_count);
+ } else if (Z_STRLEN_P(search) > 1) {
+ Z_STRVAL_P(result) =
php_str_to_str_ex(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject),
+
Z_STRVAL_P(search), Z_STRLEN_P(search),
+
Z_STRVAL_P(replace), Z_STRLEN_P(replace),
&Z_STRLEN_P(result), case_sensitivity, replace_count);
} else {
- Z_USTRVAL_P(result) =
php_u_str_to_str_case_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
-
Z_USTRVAL_P(search),
Z_USTRLEN_P(search),
-
Z_USTRVAL_P(replace),
Z_USTRLEN_P(replace),
-
&Z_USTRLEN_P(result), replace_count
TSRMLS_CC);
+ MAKE_COPY_ZVAL(subject, result);
}
- } else if (Z_STRLEN_P(search) > 1) {
- if (case_sensitivity) {
- Z_USTRVAL_P(result) =
php_u_str_to_str_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
-
Z_USTRVAL_P(search), Z_USTRLEN_P(search),
-
Z_USTRVAL_P(replace), Z_USTRLEN_P(replace),
-
&Z_USTRLEN_P(result), replace_count);
+ } else {
+ convert_to_unicode(search);
+ convert_to_unicode(replace);
+ if (Z_UNILEN_P(search) == 1) {
+ if (case_sensitivity) {
+
php_u_char_to_str_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
+
Z_USTRVAL_P(search)[0],
+
Z_USTRVAL_P(replace), Z_USTRLEN_P(replace),
+
result, replace_count);
+ } else {
+ Z_USTRVAL_P(result) =
php_u_str_to_str_case_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
+
Z_USTRVAL_P(search),
Z_USTRLEN_P(search),
+
Z_USTRVAL_P(replace),
Z_USTRLEN_P(replace),
+
&Z_USTRLEN_P(result),
replace_count TSRMLS_CC);
+ }
+ } else if (Z_STRLEN_P(search) > 1) {
+ if (case_sensitivity) {
+ Z_USTRVAL_P(result) =
php_u_str_to_str_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
+
Z_USTRVAL_P(search),
Z_USTRLEN_P(search),
+
Z_USTRVAL_P(replace),
Z_USTRLEN_P(replace),
+
&Z_USTRLEN_P(result), replace_count);
+ } else {
+ Z_USTRVAL_P(result) =
php_u_str_to_str_case_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
+
Z_USTRVAL_P(search),
Z_USTRLEN_P(search),
+
Z_USTRVAL_P(replace),
Z_USTRLEN_P(replace),
+
&Z_USTRLEN_P(result),
replace_count TSRMLS_CC);
+ }
} else {
- Z_USTRVAL_P(result) =
php_u_str_to_str_case_ex(Z_USTRVAL_PP(subject), Z_USTRLEN_PP(subject),
-
Z_USTRVAL_P(search),
Z_USTRLEN_P(search),
-
Z_USTRVAL_P(replace),
Z_USTRLEN_P(replace),
-
&Z_USTRLEN_P(result), replace_count
TSRMLS_CC);
+ MAKE_COPY_ZVAL(subject, result);
}
- } else {
- MAKE_COPY_ZVAL(subject, result);
}
}
}
@@ -5548,14 +5553,6 @@
return;
}
- /* Make sure we're dealing with strings and do the replacement. */
- if (Z_TYPE_P(search) != IS_ARRAY) {
- convert_to_unicode(search);
- convert_to_unicode(replace);
- } else if (Z_TYPE_P(replace) != IS_ARRAY) {
- convert_to_unicode(replace);
- }
-
/* if subject is an array */
if (Z_TYPE_P(subject) == IS_ARRAY) {
array_init(return_value);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
