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