diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-26 15:32:18 +0100 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-06-05 14:25:07 +0200 |
| commit | a31f46421d7bf6f55dd9ac5876b8e2eacf7e0708 (patch) | |
| tree | 24ffd7c5ae5e321c3994048fdd0fd9f68ae7457c /ext/mbstring/mbstring.c | |
| parent | 528aa7932a839fc6319979c34aa372805d8dc41c (diff) | |
| download | php-git-a31f46421d7bf6f55dd9ac5876b8e2eacf7e0708.tar.gz | |
Allow exceptions in __toString()
RFC: https://wiki.php.net/rfc/tostring_exceptions
And convert some object to string conversion related recoverable
fatal errors into Error exceptions.
Improve exception safety of internal code performing string
conversions.
Diffstat (limited to 'ext/mbstring/mbstring.c')
| -rw-r--r-- | ext/mbstring/mbstring.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 69d5fa9101..e3611562e5 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -826,8 +826,13 @@ php_mb_parse_encoding_array(zval *array, const mbfl_encoding ***return_list, siz bauto = 0; n = 0; ZEND_HASH_FOREACH_VAL(target_hash, hash_entry) { - convert_to_string_ex(hash_entry); - if (strcasecmp(Z_STRVAL_P(hash_entry), "auto") == 0) { + zend_string *encoding_str = zval_get_string(hash_entry); + if (EG(exception)) { + ret = FAILURE; + break; + } + + if (strcasecmp(ZSTR_VAL(encoding_str), "auto") == 0) { if (!bauto) { const enum mbfl_no_encoding *src = MBSTRG(default_detect_order_list); const size_t identify_list_size = MBSTRG(default_detect_order_list_size); @@ -840,7 +845,7 @@ php_mb_parse_encoding_array(zval *array, const mbfl_encoding ***return_list, siz } } } else { - const mbfl_encoding *encoding = mbfl_name2encoding(Z_STRVAL_P(hash_entry)); + const mbfl_encoding *encoding = mbfl_name2encoding(ZSTR_VAL(encoding_str)); if (encoding) { *entry++ = encoding; n++; @@ -849,6 +854,7 @@ php_mb_parse_encoding_array(zval *array, const mbfl_encoding ***return_list, siz } } i--; + zend_string_release(encoding_str); } ZEND_HASH_FOREACH_END(); if (n > 0) { if (return_list) { @@ -2000,7 +2006,9 @@ PHP_FUNCTION(mb_detect_order) } break; default: - convert_to_string_ex(arg1); + if (!try_convert_to_string(arg1)) { + return; + } if (FAILURE == php_mb_parse_encoding_list(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), &list, &size, 0)) { if (list) { efree(list); @@ -3328,7 +3336,9 @@ PHP_FUNCTION(mb_convert_encoding) } if (Z_TYPE_P(input) != IS_STRING && Z_TYPE_P(input) != IS_ARRAY) { - convert_to_string(input); + if (!try_convert_to_string(input)) { + return; + } } if (arg_old) { @@ -3338,8 +3348,13 @@ PHP_FUNCTION(mb_convert_encoding) _from_encodings = NULL; ZEND_HASH_FOREACH_VAL(target_hash, hash_entry) { - - convert_to_string_ex(hash_entry); + zend_string *encoding_str = zval_get_string(hash_entry); + if (EG(exception)) { + if (_from_encodings) { + efree(_from_encodings); + } + return; + } if ( _from_encodings) { l = strlen(_from_encodings); @@ -3350,6 +3365,7 @@ PHP_FUNCTION(mb_convert_encoding) } else { _from_encodings = estrdup(Z_STRVAL_P(hash_entry)); } + zend_string_release(encoding_str); } ZEND_HASH_FOREACH_END(); if (_from_encodings != NULL && !strlen(_from_encodings)) { @@ -3359,7 +3375,10 @@ PHP_FUNCTION(mb_convert_encoding) s_free = _from_encodings; break; default: - convert_to_string(arg_old); + if (!try_convert_to_string(arg_old)) { + return; + } + _from_encodings = Z_STRVAL_P(arg_old); break; } @@ -3535,7 +3554,9 @@ PHP_FUNCTION(mb_detect_encoding) } break; default: - convert_to_string(encoding_list); + if (!try_convert_to_string(encoding_list)) { + return; + } if (FAILURE == php_mb_parse_encoding_list(Z_STRVAL_P(encoding_list), Z_STRLEN_P(encoding_list), &list, &size, 0)) { if (list) { efree(list); @@ -3944,7 +3965,9 @@ PHP_FUNCTION(mb_convert_variables) php_mb_parse_encoding_array(zfrom_enc, &elist, &elistsz, 0); break; default: - convert_to_string_ex(zfrom_enc); + if (!try_convert_to_string(zfrom_enc)) { + return; + } php_mb_parse_encoding_list(Z_STRVAL_P(zfrom_enc), Z_STRLEN_P(zfrom_enc), &elist, &elistsz, 0); break; } |
