From: Antony Dovgal Date: Mon, 21 Jan 2008 14:37:19 +0000 (+0000) Subject: fix #42861 (strtr() crashes in Unicode mode when $from argument is empty) X-Git-Tag: RELEASE_2_0_0a1~823 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=596403f22622ab740918605059f69382c97147cd;p=php fix #42861 (strtr() crashes in Unicode mode when $from argument is empty) --- diff --git a/ext/standard/string.c b/ext/standard/string.c index f1b553de77..1aed7b1de6 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4151,6 +4151,7 @@ PHPAPI UChar *php_u_strtr(UChar *str, int len, UChar *str_from, int str_from_len int can_optimize = 1; if ((trlen < 1) || (len < 1)) { + *outlen = len; return str; } @@ -4270,6 +4271,7 @@ static HashTable* php_u_strtr_array_prepare_hashtable(HashTable *hash, int *minl len = string_key_len-1; if (len < 1) { zend_hash_destroy(tmp_hash); + efree(tmp_hash); return NULL; } zend_u_hash_add(tmp_hash, IS_UNICODE, string_key, string_key_len, entry, sizeof(zval*), NULL); @@ -4506,19 +4508,23 @@ PHP_FUNCTION(strtr) } if (Z_TYPE_PP(str) == IS_UNICODE) { - int outlen; + int outlen = 0; UChar *outstr; if (ac == 2) { - int minlen, maxlen; + int minlen = 0, maxlen = 0; HashTable *hash; hash = php_u_strtr_array_prepare_hashtable(HASH_OF(*from), &minlen, &maxlen TSRMLS_CC); - outstr = php_u_strtr_array(Z_USTRVAL_PP(str), Z_USTRLEN_PP(str), hash, minlen, maxlen, &outlen TSRMLS_CC); - zend_hash_destroy(hash); - efree(hash); - RETVAL_UNICODEL(outstr, outlen, 0); - Z_TYPE_P(return_value) = IS_UNICODE; + if (hash) { + outstr = php_u_strtr_array(Z_USTRVAL_PP(str), Z_USTRLEN_PP(str), hash, minlen, maxlen, &outlen TSRMLS_CC); + zend_hash_destroy(hash); + efree(hash); + RETVAL_UNICODEL(outstr, outlen, 0); + Z_TYPE_P(return_value) = IS_UNICODE; + } else { + RETURN_ZVAL(*str, 1, 0); + } } else { convert_to_unicode_ex(from); convert_to_unicode_ex(to); @@ -4531,7 +4537,12 @@ PHP_FUNCTION(strtr) Z_USTRLEN_PP(to), MIN(Z_USTRLEN_PP(from), Z_USTRLEN_PP(to)), &outlen TSRMLS_CC); - ZVAL_UNICODEL(return_value, outstr, outlen, 0); + + if (Z_USTRVAL_PP(str) == outstr) { + ZVAL_UNICODEL(return_value, outstr, outlen, 1); + } else { + ZVAL_UNICODEL(return_value, outstr, outlen, 0); + } Z_TYPE_P(return_value) = IS_UNICODE; } diff --git a/ext/standard/tests/strings/bug42861.phpt b/ext/standard/tests/strings/bug42861.phpt new file mode 100644 index 0000000000..60be939c9d --- /dev/null +++ b/ext/standard/tests/strings/bug42861.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #42861 (strtr() crashes in Unicode mode when $from argument is empty) +--FILE-- + "string") ) ); +var_dump( strtr("hello", array('' => "string") ) ); +var_dump( strtr("hello", array(null => "string") ) ); +var_dump( strtr("hello", array(NULL => "string") ) ); + +var_dump( strtr("hello", "", "string") ); +var_dump( strtr("hello", '', "string") ); +var_dump( strtr("hello", NULL, "string") ); +var_dump( strtr("hello", null, "string") ); + +echo "Done\n"; +?> +--EXPECTF-- +bool(false) +bool(false) +bool(false) +bool(false) +string(5) "hello" +string(5) "hello" +string(5) "hello" +string(5) "hello" +Done +--UEXPECTF-- +unicode(5) "hello" +unicode(5) "hello" +unicode(5) "hello" +unicode(5) "hello" +unicode(5) "hello" +unicode(5) "hello" +unicode(5) "hello" +unicode(5) "hello" +Done