diff options
author | Nikita Popov <nikic@php.net> | 2016-09-24 13:18:43 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2016-09-24 13:18:43 +0200 |
commit | 8831a12da1671bcfca8607d5af505d69ba938917 (patch) | |
tree | f0d182c9575e2309258fe7afddd48fdb418c1080 | |
parent | 5c81298597f291f7785d9f0ff2c331b4c53ced6c (diff) | |
download | php-git-8831a12da1671bcfca8607d5af505d69ba938917.tar.gz |
Fixed bug #73163
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug73163.phpt | 22 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 48 |
3 files changed, 43 insertions, 29 deletions
@@ -11,6 +11,8 @@ PHP NEWS password_verify). (Anatol) . Fixed bug #73058 (crypt broken when salt is 'too' long). (Anatol) . Fixed bug #69579 (Invalid free in extension trait). (John Boehr) + . Fixed bug #73163 (PHP hangs if error handler throws while accessing undef + const in default value). (Nikita) - COM: . Fixed bug #73126 (Cannot pass parameter 1 by reference). (Anatol) diff --git a/Zend/tests/bug73163.phpt b/Zend/tests/bug73163.phpt new file mode 100644 index 0000000000..448d7f5959 --- /dev/null +++ b/Zend/tests/bug73163.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #73163 (PHP hangs if error handler throws while accessing undef const in default value) +--FILE-- +<?php + +function doSomething(string $value = UNDEFINED) { +} + +set_error_handler(function($errno, $errstr) { + throw new Exception($errstr); +}); + +doSomething(); + +?> +--EXPECTF-- +Fatal error: Uncaught Exception: Use of undefined constant UNDEFINED - assumed 'UNDEFINED' in %s:%d +Stack trace: +#0 %s(%d): {closure}(%s) +#1 %s(%d): doSomething() +#2 {main} + thrown in %s on line %d diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1cbbc1a0a1..194f16df48 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -573,8 +573,6 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas ZVAL_EMPTY_STRING(p); } } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) { - char *actual = Z_STRVAL_P(p); - if (UNEXPECTED(EG(exception))) { RESET_CONSTANT_VISITED(p); return FAILURE; @@ -584,46 +582,38 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas return FAILURE; } else { zend_string *save = Z_STR_P(p); - char *slash; - size_t actual_len = Z_STRLEN_P(p); - if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { - actual = slash + 1; - actual_len -= (actual - Z_STRVAL_P(p)); - if (inline_change) { - zend_string *s = zend_string_init(actual, actual_len, 0); - Z_STR_P(p) = s; - Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; - } - } - if (actual[0] == '\\') { - if (inline_change) { - memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); - --Z_STRLEN_P(p); - } else { - ++actual; - } - --actual_len; - } if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { if (ZSTR_VAL(save)[0] == '\\') { zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(save) + 1); } else { zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(save)); } - if (inline_change) { - zend_string_release(save); - } RESET_CONSTANT_VISITED(p); return FAILURE; } else { - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); + char *actual = Z_STRVAL_P(p); + size_t actual_len = Z_STRLEN_P(p); + char *slash = (char *) zend_memrchr(actual, '\\', actual_len); + if (slash) { + actual = slash + 1; + actual_len -= (actual - Z_STRVAL_P(p)); + } + + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); + if (EG(exception)) { + RESET_CONSTANT_VISITED(p); + return FAILURE; + } + if (!inline_change) { ZVAL_STRINGL(p, actual, actual_len); } else { - Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? - IS_STRING_EX : IS_INTERNED_STRING_EX; - if (save && ZSTR_VAL(save) != actual) { + if (slash) { + ZVAL_STRINGL(p, actual, actual_len); zend_string_release(save); + } else { + Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? + IS_STRING_EX : IS_INTERNED_STRING_EX; } } } |