com php-src: Fix Foo::${42} and similar: Zend/tests/int_stati c_prop_name.phpt Zend/zend_compile.c Zend/zend_ vm_def.h Zend/zend_vm_execute.h
ext/opcache/Optim izer/zend_optimizer.c
| From: | Nikita Popov | Date: | Thu, 10 Dec 2015 17:14:40 +0000 |
| Subject: | com php-src: Fix Foo::${42} and similar: Zend/tests/int_stati c_prop_name.phpt Zend/zend_compile.c Zend/zend_ vm_def.h Zend/zend_vm_execute.h ext/opcache/Optim izer/zend_optimizer.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-90207@lists.php.net to get a copy of this message | ||
Commit: 37f3425263f5d0f7f8bc8f8f9091efb26384a4f5
Author: Nikita Popov <nikic@php.net> Thu, 10 Dec 2015 18:12:59 +0100
Parents: a19f511345d97b787b0889112d5df89e87fcbd79
Branches: PHP-7.0 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=37f3425263f5d0f7f8bc8f8f9091efb26384a4f5
Log:
Fix Foo::${42} and similar
Fixes segfault on direct use, segfault on opcache evaluated use,
leak on temporary use.
Fixes analogeous segfault for ${42} on opcache eval as well.
Changed paths:
A Zend/tests/int_static_prop_name.phpt
M Zend/zend_compile.c
M Zend/zend_vm_def.h
M Zend/zend_vm_execute.h
M ext/opcache/Optimizer/zend_optimizer.c
Diff:
diff --git a/Zend/tests/int_static_prop_name.phpt b/Zend/tests/int_static_prop_name.phpt
new file mode 100644
index 0000000..bfdfc42
--- /dev/null
+++ b/Zend/tests/int_static_prop_name.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Using an integer as a static property name
+--FILE--
+<?php
+
+class Foo {
+ public static $bar = 42;
+}
+
+$n = 42;
+
+${42} = 24;
+var_dump(${42});
+var_dump(${(int) 42});
+var_dump(${(int) $n});
+
+try {
+ var_dump(Foo::${42});
+} catch (Error $e) {
+ echo $e->getMessage(), "\n";
+}
+
+try {
+ var_dump(Foo::${(int) 42});
+} catch (Error $e) {
+ echo $e->getMessage(), "\n";
+}
+
+try {
+ var_dump(Foo::${(int) $n});
+} catch (Error $e) {
+ echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+int(24)
+int(24)
+int(24)
+Access to undeclared static property: Foo::$42
+Access to undeclared static property: Foo::$42
+Access to undeclared static property: Foo::$42
+
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index da4b051..34246bd 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2379,6 +2379,7 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast,
uint32_t
opline = zend_emit_op(result, ZEND_FETCH_R, &prop_node, NULL);
}
if (opline->op1_type == IS_CONST) {
+ convert_to_string(CT_CONSTANT(opline->op1));
zend_alloc_polymorphic_cache_slot(opline->op1.constant);
}
if (class_node.op_type == IS_CONST) {
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index bc41a0b..4c01a5d 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1537,6 +1537,9 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV,
UNUSED|CONST|V
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (OP1_TYPE != IS_CONST) {
+ zend_string_release(name);
+ }
FREE_OP1();
HANDLE_EXCEPTION();
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 74adfe4..0fd696d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4996,6 +4996,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(name);
+ }
HANDLE_EXCEPTION();
}
@@ -6912,6 +6915,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(name);
+ }
HANDLE_EXCEPTION();
}
@@ -7415,6 +7421,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(name);
+ }
HANDLE_EXCEPTION();
}
@@ -31013,6 +31022,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (IS_CV != IS_CONST) {
+ zend_string_release(name);
+ }
HANDLE_EXCEPTION();
}
@@ -33221,6 +33233,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (IS_CV != IS_CONST) {
+ zend_string_release(name);
+ }
HANDLE_EXCEPTION();
}
@@ -34165,6 +34180,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if (IS_CV != IS_CONST) {
+ zend_string_release(name);
+ }
HANDLE_EXCEPTION();
}
@@ -41357,6 +41375,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(name);
+ }
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -42345,6 +42366,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(name);
+ }
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -42753,6 +42777,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL
zend_fetch_var_address_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(name);
+ }
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index aa5b6a8..e6cd116 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -175,6 +175,21 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
op_array->cache_size += sizeof(void*);
zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
break;
+ case ZEND_FETCH_R:
+ case ZEND_FETCH_W:
+ case ZEND_FETCH_RW:
+ case ZEND_FETCH_IS:
+ case ZEND_FETCH_UNSET:
+ case ZEND_FETCH_FUNC_ARG:
+ TO_STRING_NOWARN(val);
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val);
+ zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
+ if (opline->extended_value == ZEND_FETCH_STATIC_MEMBER) {
+ Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size;
+ op_array->cache_size += 2 * sizeof(void*);
+ }
+ break;
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
TO_STRING_NOWARN(val);