Skip to content

Commit e080fb6

Browse files
committed
Do not continue extract()ing after an exception has been thrown
Make behavior consistent with a loop of normal assignments. This is not a big issue now, because $this is the only case that may generate an error. However typed references introduce additional error conditions, which would be silenced by this kind of behavior.
1 parent 2af3234 commit e080fb6

File tree

2 files changed

+42
-94
lines changed

2 files changed

+42
-94
lines changed

Zend/tests/this_in_extract.phpt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ $this re-assign in extract()
33
--FILE--
44
<?php
55
function foo() {
6-
extract(["this"=>42]);
7-
var_dump($this);
6+
try {
7+
extract(["this"=>42, "a"=>24]);
8+
} catch (Error $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
var_dump($a);
812
}
913
foo();
1014
?>
1115
--EXPECTF--
12-
Fatal error: Uncaught Error: Cannot re-assign $this in %sthis_in_extract.php:3
13-
Stack trace:
14-
#0 %sthis_in_extract.php(3): extract(Array)
15-
#1 %sthis_in_extract.php(6): foo()
16-
#2 {main}
17-
thrown in %sthis_in_extract.php on line 3
16+
Cannot re-assign $this
17+
18+
Notice: Undefined variable: a in %s on line %d
19+
NULL

ext/standard/array.c

Lines changed: 32 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,7 +1730,6 @@ PHPAPI int php_prefix_varname(zval *result, const zval *prefix, const char *var_
17301730

17311731
static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_table) /* {{{ */
17321732
{
1733-
int exception_thrown = 0;
17341733
zend_long count = 0;
17351734
zend_string *var_name;
17361735
zval *entry, *orig_var;
@@ -1754,11 +1753,8 @@ static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_t
17541753
continue;
17551754
}
17561755
if (zend_string_equals_literal(var_name, "this")) {
1757-
if (!exception_thrown) {
1758-
exception_thrown = 1;
1759-
zend_throw_error(NULL, "Cannot re-assign $this");
1760-
}
1761-
continue;
1756+
zend_throw_error(NULL, "Cannot re-assign $this");
1757+
return -1;
17621758
}
17631759
if (Z_ISREF_P(entry)) {
17641760
Z_ADDREF_P(entry);
@@ -1777,7 +1773,6 @@ static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_t
17771773

17781774
static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table) /* {{{ */
17791775
{
1780-
int exception_thrown = 0;
17811776
zend_long count = 0;
17821777
zend_string *var_name;
17831778
zval *entry, *orig_var;
@@ -1801,11 +1796,8 @@ static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table
18011796
continue;
18021797
}
18031798
if (zend_string_equals_literal(var_name, "this")) {
1804-
if (!exception_thrown) {
1805-
exception_thrown = 1;
1806-
zend_throw_error(NULL, "Cannot re-assign $this");
1807-
}
1808-
continue;
1799+
zend_throw_error(NULL, "Cannot re-assign $this");
1800+
return -1;
18091801
}
18101802
ZVAL_DEREF(entry);
18111803
ZVAL_DEREF(orig_var);
@@ -1821,7 +1813,6 @@ static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table
18211813

18221814
static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_table) /* {{{ */
18231815
{
1824-
int exception_thrown = 0;
18251816
zend_long count = 0;
18261817
zend_string *var_name;
18271818
zval *entry, *orig_var;
@@ -1834,11 +1825,8 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t
18341825
continue;
18351826
}
18361827
if (zend_string_equals_literal(var_name, "this")) {
1837-
if (!exception_thrown) {
1838-
exception_thrown = 1;
1839-
zend_throw_error(NULL, "Cannot re-assign $this");
1840-
}
1841-
continue;
1828+
zend_throw_error(NULL, "Cannot re-assign $this");
1829+
return -1;
18421830
}
18431831
orig_var = zend_hash_find_ex(symbol_table, var_name, 1);
18441832
if (orig_var) {
@@ -1872,7 +1860,6 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t
18721860

18731861
static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table) /* {{{ */
18741862
{
1875-
int exception_thrown = 0;
18761863
zend_long count = 0;
18771864
zend_string *var_name;
18781865
zval *entry, *orig_var;
@@ -1885,11 +1872,8 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table
18851872
continue;
18861873
}
18871874
if (zend_string_equals_literal(var_name, "this")) {
1888-
if (!exception_thrown) {
1889-
exception_thrown = 1;
1890-
zend_throw_error(NULL, "Cannot re-assign $this");
1891-
}
1892-
continue;
1875+
zend_throw_error(NULL, "Cannot re-assign $this");
1876+
return -1;
18931877
}
18941878
orig_var = zend_hash_find_ex(symbol_table, var_name, 1);
18951879
if (orig_var) {
@@ -1917,7 +1901,6 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table
19171901

19181902
static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
19191903
{
1920-
int exception_thrown = 0;
19211904
zend_long count = 0;
19221905
zend_string *var_name;
19231906
zval *entry, *orig_var, final_name;
@@ -1944,10 +1927,8 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s
19441927
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
19451928
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
19461929
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
1947-
if (!exception_thrown) {
1948-
exception_thrown = 1;
1949-
zend_throw_error(NULL, "Cannot re-assign $this");
1950-
}
1930+
zend_throw_error(NULL, "Cannot re-assign $this");
1931+
return -1;
19511932
} else {
19521933
if (Z_ISREF_P(entry)) {
19531934
Z_ADDREF_P(entry);
@@ -1976,7 +1957,6 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s
19761957

19771958
static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
19781959
{
1979-
int exception_thrown = 0;
19801960
zend_long count = 0;
19811961
zend_string *var_name;
19821962
zval *entry, *orig_var, final_name;
@@ -1999,10 +1979,8 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo
19991979
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
20001980
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
20011981
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2002-
if (!exception_thrown) {
2003-
exception_thrown = 1;
2004-
zend_throw_error(NULL, "Cannot re-assign $this");
2005-
}
1982+
zend_throw_error(NULL, "Cannot re-assign $this");
1983+
return -1;
20061984
} else {
20071985
ZVAL_DEREF(entry);
20081986
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
@@ -2029,7 +2007,6 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo
20292007

20302008
static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
20312009
{
2032-
int exception_thrown = 0;
20332010
zend_long count = 0;
20342011
zend_string *var_name;
20352012
zval *entry, *orig_var, final_name;
@@ -2059,10 +2036,8 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
20592036
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
20602037
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
20612038
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2062-
if (!exception_thrown) {
2063-
exception_thrown = 1;
2064-
zend_throw_error(NULL, "Cannot re-assign $this");
2065-
}
2039+
zend_throw_error(NULL, "Cannot re-assign $this");
2040+
return -1;
20662041
} else {
20672042
if (Z_ISREF_P(entry)) {
20682043
Z_ADDREF_P(entry);
@@ -2087,11 +2062,8 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
20872062
continue;
20882063
}
20892064
if (zend_string_equals_literal(var_name, "this")) {
2090-
if (!exception_thrown) {
2091-
exception_thrown = 1;
2092-
zend_throw_error(NULL, "Cannot re-assign $this");
2093-
}
2094-
continue;
2065+
zend_throw_error(NULL, "Cannot re-assign $this");
2066+
return -1;
20952067
}
20962068
if (Z_ISREF_P(entry)) {
20972069
Z_ADDREF_P(entry);
@@ -2109,7 +2081,6 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
21092081

21102082
static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
21112083
{
2112-
int exception_thrown = 0;
21132084
zend_long count = 0;
21142085
zend_string *var_name;
21152086
zval *entry, *orig_var, final_name;
@@ -2135,10 +2106,8 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab
21352106
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
21362107
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
21372108
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2138-
if (!exception_thrown) {
2139-
exception_thrown = 1;
2140-
zend_throw_error(NULL, "Cannot re-assign $this");
2141-
}
2109+
zend_throw_error(NULL, "Cannot re-assign $this");
2110+
return -1;
21422111
} else {
21432112
ZVAL_DEREF(entry);
21442113
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
@@ -2161,11 +2130,8 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab
21612130
continue;
21622131
}
21632132
if (zend_string_equals_literal(var_name, "this")) {
2164-
if (!exception_thrown) {
2165-
exception_thrown = 1;
2166-
zend_throw_error(NULL, "Cannot re-assign $this");
2167-
}
2168-
continue;
2133+
zend_throw_error(NULL, "Cannot re-assign $this");
2134+
return -1;
21692135
}
21702136
ZVAL_DEREF(entry);
21712137
Z_TRY_ADDREF_P(entry);
@@ -2180,7 +2146,6 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab
21802146

21812147
static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
21822148
{
2183-
int exception_thrown = 0;
21842149
zend_long count = 0;
21852150
zend_string *var_name;
21862151
zend_ulong num_key;
@@ -2199,10 +2164,8 @@ static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_
21992164
}
22002165
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
22012166
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2202-
if (!exception_thrown) {
2203-
exception_thrown = 1;
2204-
zend_throw_error(NULL, "Cannot re-assign $this");
2205-
}
2167+
zend_throw_error(NULL, "Cannot re-assign $this");
2168+
return -1;
22062169
} else {
22072170
if (Z_ISREF_P(entry)) {
22082171
Z_ADDREF_P(entry);
@@ -2230,7 +2193,6 @@ static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_
22302193

22312194
static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
22322195
{
2233-
int exception_thrown = 0;
22342196
zend_long count = 0;
22352197
zend_string *var_name;
22362198
zend_ulong num_key;
@@ -2249,10 +2211,8 @@ static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_tabl
22492211
}
22502212
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
22512213
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2252-
if (!exception_thrown) {
2253-
exception_thrown = 1;
2254-
zend_throw_error(NULL, "Cannot re-assign $this");
2255-
}
2214+
zend_throw_error(NULL, "Cannot re-assign $this");
2215+
return -1;
22562216
} else {
22572217
ZVAL_DEREF(entry);
22582218
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
@@ -2278,7 +2238,6 @@ static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_tabl
22782238

22792239
static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
22802240
{
2281-
int exception_thrown = 0;
22822241
zend_long count = 0;
22832242
zend_string *var_name;
22842243
zend_ulong num_key;
@@ -2305,10 +2264,8 @@ static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *sym
23052264
}
23062265
}
23072266
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2308-
if (!exception_thrown) {
2309-
exception_thrown = 1;
2310-
zend_throw_error(NULL, "Cannot re-assign $this");
2311-
}
2267+
zend_throw_error(NULL, "Cannot re-assign $this");
2268+
return -1;
23122269
} else {
23132270
if (Z_ISREF_P(entry)) {
23142271
Z_ADDREF_P(entry);
@@ -2335,7 +2292,6 @@ static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *sym
23352292

23362293
static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
23372294
{
2338-
int exception_thrown = 0;
23392295
zend_long count = 0;
23402296
zend_string *var_name;
23412297
zend_ulong num_key;
@@ -2362,10 +2318,8 @@ static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_
23622318
}
23632319
}
23642320
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
2365-
if (!exception_thrown) {
2366-
exception_thrown = 1;
2367-
zend_throw_error(NULL, "Cannot re-assign $this");
2368-
}
2321+
zend_throw_error(NULL, "Cannot re-assign $this");
2322+
return -1;
23692323
} else {
23702324
ZVAL_DEREF(entry);
23712325
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
@@ -2390,7 +2344,6 @@ static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_
23902344

23912345
static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table) /* {{{ */
23922346
{
2393-
int exception_thrown = 0;
23942347
zend_long count = 0;
23952348
zend_string *var_name;
23962349
zval *entry, *orig_var;
@@ -2403,11 +2356,8 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table)
24032356
continue;
24042357
}
24052358
if (zend_string_equals_literal(var_name, "this")) {
2406-
if (!exception_thrown) {
2407-
exception_thrown = 1;
2408-
zend_throw_error(NULL, "Cannot re-assign $this");
2409-
}
2410-
continue;
2359+
zend_throw_error(NULL, "Cannot re-assign $this");
2360+
return -1;
24112361
}
24122362
orig_var = zend_hash_find_ex(symbol_table, var_name, 1);
24132363
if (orig_var) {
@@ -2440,7 +2390,6 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table)
24402390

24412391
static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /* {{{ */
24422392
{
2443-
int exception_thrown = 0;
24442393
zend_long count = 0;
24452394
zend_string *var_name;
24462395
zval *entry, *orig_var;
@@ -2453,11 +2402,8 @@ static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /*
24532402
continue;
24542403
}
24552404
if (zend_string_equals_literal(var_name, "this")) {
2456-
if (!exception_thrown) {
2457-
exception_thrown = 1;
2458-
zend_throw_error(NULL, "Cannot re-assign $this");
2459-
}
2460-
continue;
2405+
zend_throw_error(NULL, "Cannot re-assign $this");
2406+
return -1;
24612407
}
24622408
orig_var = zend_hash_find_ex(symbol_table, var_name, 1);
24632409
if (orig_var) {

0 commit comments

Comments
 (0)