Throw exception on attempt to re-assign $this through extract() and parse_str().

This commit is contained in:
Dmitry Stogov 2016-05-24 02:02:43 +03:00
parent 41f1531b52
commit e32cc528c0
6 changed files with 71 additions and 10 deletions

View File

@ -0,0 +1,17 @@
--TEST--
$this re-assign in extract()
--FILE--
<?php
function foo() {
extract(["this"=>42]);
var_dump($this);
}
foo();
?>
--EXPECTF--
Fatal error: Uncaught Error: Cannot re-assign $this in %sthis_in_extract.php:3
Stack trace:
#0 %sthis_in_extract.php(3): extract(Array)
#1 %sthis_in_extract.php(6): foo()
#2 {main}
thrown in %sthis_in_extract.php on line 3

View File

@ -0,0 +1,17 @@
--TEST--
$this re-assign in parse_str()
--FILE--
<?php
function foo() {
parse_str("this=42");
var_dump($this);
}
foo();
?>
--EXPECTF--
Fatal error: Uncaught Error: Cannot re-assign $this in %sthis_in_parse_str.php:3
Stack trace:
#0 %sthis_in_parse_str.php(3): parse_str('this=42')
#1 %sthis_in_parse_str.php(6): foo()
#2 {main}
thrown in %sthis_in_parse_str.php on line 3

View File

@ -1494,8 +1494,10 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
zval *result = EX_VAR(opline->result.var);
zval *result;
ZEND_VM_C_LABEL(fetch_this):
result = EX_VAR(opline->result.var);
switch (type) {
case BP_VAR_R:
if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
@ -1549,6 +1551,9 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
retval = Z_INDIRECT_P(retval);
if (Z_TYPE_P(retval) == IS_UNDEF) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
ZEND_VM_C_GOTO(fetch_this);
}
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:

View File

@ -6977,8 +6977,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
zval *result = EX_VAR(opline->result.var);
zval *result;
fetch_this:
result = EX_VAR(opline->result.var);
switch (type) {
case BP_VAR_R:
if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
@ -7032,6 +7034,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
retval = Z_INDIRECT_P(retval);
if (Z_TYPE_P(retval) == IS_UNDEF) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
goto fetch_this;
}
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:
@ -44351,8 +44356,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
zval *result = EX_VAR(opline->result.var);
zval *result;
fetch_this:
result = EX_VAR(opline->result.var);
switch (type) {
case BP_VAR_R:
if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
@ -44406,6 +44413,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
retval = Z_INDIRECT_P(retval);
if (Z_TYPE_P(retval) == IS_UNDEF) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
goto fetch_this;
}
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:
@ -56353,8 +56363,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
retval = zend_hash_find(target_symbol_table, name);
if (retval == NULL) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
zval *result = EX_VAR(opline->result.var);
zval *result;
fetch_this:
result = EX_VAR(opline->result.var);
switch (type) {
case BP_VAR_R:
if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
@ -56408,6 +56420,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
retval = Z_INDIRECT_P(retval);
if (Z_TYPE_P(retval) == IS_UNDEF) {
if (UNEXPECTED(zend_string_equals(name, CG(known_strings)[ZEND_STR_THIS]))) {
goto fetch_this;
}
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:

View File

@ -1765,6 +1765,7 @@ PHP_FUNCTION(extract)
zend_ulong num_key;
int var_exists, count = 0;
int extract_refs = 0;
int exception_thrown = 0;
zend_array *symbol_table;
zval var_array;
@ -1843,12 +1844,6 @@ PHP_FUNCTION(extract)
if (var_exists && ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) {
break;
}
if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
zend_class_entry *scope = zend_get_executed_scope();
if (scope && ZSTR_LEN(scope->name) != 0) {
break;
}
}
ZVAL_STR_COPY(&final_name, var_name);
break;
@ -1889,6 +1884,15 @@ PHP_FUNCTION(extract)
if (Z_TYPE(final_name) == IS_STRING && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
zval *orig_var;
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
if (!exception_thrown) {
exception_thrown = 1;
zend_throw_error(NULL, "Cannot re-assign $this");
}
zval_dtor(&final_name);
continue;
}
if (extract_refs) {
ZVAL_MAKE_REF(entry);

View File

@ -4609,6 +4609,9 @@ PHP_FUNCTION(parse_str)
ZVAL_ARR(&tmp, symbol_table);
sapi_module.treat_data(PARSE_STRING, res, &tmp);
if (UNEXPECTED(zend_hash_del(symbol_table, CG(known_strings)[ZEND_STR_THIS]) == SUCCESS)) {
zend_throw_error(NULL, "Cannot re-assign $this");
}
} else {
zval ret;