summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-09-24 13:18:43 +0200
committerNikita Popov <nikic@php.net>2016-09-24 13:18:43 +0200
commit8831a12da1671bcfca8607d5af505d69ba938917 (patch)
treef0d182c9575e2309258fe7afddd48fdb418c1080
parent5c81298597f291f7785d9f0ff2c331b4c53ced6c (diff)
downloadphp-git-8831a12da1671bcfca8607d5af505d69ba938917.tar.gz
Fixed bug #73163
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug73163.phpt22
-rw-r--r--Zend/zend_execute_API.c48
3 files changed, 43 insertions, 29 deletions
diff --git a/NEWS b/NEWS
index 6bff08b6a0..674a6cb05c 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}
}
}