Skip to content

Commit 83cdb89

Browse files
committed
Fixed bug #77135 (Extract with EXTR_SKIP should skip $this)
1 parent 7d1aa75 commit 83cdb89

File tree

3 files changed

+131
-44
lines changed

3 files changed

+131
-44
lines changed

NEWS

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ PHP NEWS
1313
- MySQLi:
1414
. Fixed bug #77956 (When mysqli.allow_local_infile = Off, use a meaningful
1515
error message). (Sjon Hortensius)
16-
. Fixed bug #38546 (bindParam incorrect processing of bool types).
17-
(camporter)
1816

1917
- OpenSSL:
2018
. Fixed bug #78079 (openssl_encrypt_ccm.phpt fails with OpenSSL 1.1.1c).
@@ -24,6 +22,10 @@ PHP NEWS
2422
. Fixed bug #78038 (Socket_select fails when resource array contains
2523
references). (Nikita)
2624

25+
- Standard:
26+
. Fixed bug #77135 (Extract with EXTR_SKIP should skip $this).
27+
(Craig Duncan, Dmitry)
28+
2729
- Zip:
2830
. Fixed bug #76345 (zip.h not found). (Michael Maroszek)
2931

ext/standard/array.c

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,10 +1756,10 @@ static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_t
17561756
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
17571757
continue;
17581758
}
1759-
if (ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) {
1759+
if (zend_string_equals_literal(var_name, "GLOBALS")) {
17601760
continue;
17611761
}
1762-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
1762+
if (zend_string_equals_literal(var_name, "this")) {
17631763
if (!exception_thrown) {
17641764
exception_thrown = 1;
17651765
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -1800,10 +1800,10 @@ static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table
18001800
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
18011801
continue;
18021802
}
1803-
if (ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) {
1803+
if (zend_string_equals_literal(var_name, "GLOBALS")) {
18041804
continue;
18051805
}
1806-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
1806+
if (zend_string_equals_literal(var_name, "this")) {
18071807
if (!exception_thrown) {
18081808
exception_thrown = 1;
18091809
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -1837,7 +1837,7 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t
18371837
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
18381838
continue;
18391839
}
1840-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
1840+
if (zend_string_equals_literal(var_name, "this")) {
18411841
if (!exception_thrown) {
18421842
exception_thrown = 1;
18431843
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -1849,7 +1849,7 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t
18491849
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
18501850
orig_var = Z_INDIRECT_P(orig_var);
18511851
}
1852-
if (ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) {
1852+
if (zend_string_equals_literal(var_name, "GLOBALS")) {
18531853
continue;
18541854
}
18551855
ZVAL_MAKE_REF(entry);
@@ -1882,7 +1882,7 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table
18821882
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
18831883
continue;
18841884
}
1885-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
1885+
if (zend_string_equals_literal(var_name, "this")) {
18861886
if (!exception_thrown) {
18871887
exception_thrown = 1;
18881888
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -1894,7 +1894,7 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table
18941894
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
18951895
orig_var = Z_INDIRECT_P(orig_var);
18961896
}
1897-
if (ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) {
1897+
if (zend_string_equals_literal(var_name, "GLOBALS")) {
18981898
continue;
18991899
}
19001900
ZVAL_DEREF(entry);
@@ -1939,7 +1939,7 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s
19391939
}
19401940
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
19411941
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
1942-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
1942+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
19431943
if (!exception_thrown) {
19441944
exception_thrown = 1;
19451945
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -1992,7 +1992,7 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo
19921992
}
19931993
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
19941994
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
1995-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
1995+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
19961996
if (!exception_thrown) {
19971997
exception_thrown = 1;
19981998
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2047,9 +2047,10 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
20472047
continue;
20482048
}
20492049
}
2050+
prefix:
20502051
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
20512052
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
2052-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
2053+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
20532054
if (!exception_thrown) {
20542055
exception_thrown = 1;
20552056
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2074,12 +2075,8 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
20742075
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
20752076
continue;
20762077
}
2077-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
2078-
if (!exception_thrown) {
2079-
exception_thrown = 1;
2080-
zend_throw_error(NULL, "Cannot re-assign $this");
2081-
}
2082-
continue;
2078+
if (zend_string_equals_literal(var_name, "this")) {
2079+
goto prefix;
20832080
}
20842081
ZVAL_MAKE_REF(entry);
20852082
Z_ADDREF_P(entry);
@@ -2118,9 +2115,10 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab
21182115
continue;
21192116
}
21202117
}
2118+
prefix:
21212119
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
21222120
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
2123-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
2121+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
21242122
if (!exception_thrown) {
21252123
exception_thrown = 1;
21262124
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2146,12 +2144,8 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab
21462144
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
21472145
continue;
21482146
}
2149-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
2150-
if (!exception_thrown) {
2151-
exception_thrown = 1;
2152-
zend_throw_error(NULL, "Cannot re-assign $this");
2153-
}
2154-
continue;
2147+
if (zend_string_equals_literal(var_name, "this")) {
2148+
goto prefix;
21552149
}
21562150
ZVAL_DEREF(entry);
21572151
if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
@@ -2184,7 +2178,7 @@ static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_
21842178
zend_string_release(str);
21852179
}
21862180
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
2187-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
2181+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
21882182
if (!exception_thrown) {
21892183
exception_thrown = 1;
21902184
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2231,7 +2225,7 @@ static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_tabl
22312225
zend_string_release(str);
22322226
}
22332227
if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
2234-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
2228+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
22352229
if (!exception_thrown) {
22362230
exception_thrown = 1;
22372231
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2269,7 +2263,8 @@ static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *sym
22692263

22702264
ZEND_HASH_FOREACH_KEY_VAL_IND(arr, num_key, var_name, entry) {
22712265
if (var_name) {
2272-
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
2266+
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))
2267+
|| zend_string_equals_literal(var_name, "this")) {
22732268
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
22742269
if (!php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
22752270
zend_string_release(Z_STR(final_name));
@@ -2287,7 +2282,7 @@ static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *sym
22872282
continue;
22882283
}
22892284
}
2290-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
2285+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
22912286
if (!exception_thrown) {
22922287
exception_thrown = 1;
22932288
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2323,7 +2318,8 @@ static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_
23232318

23242319
ZEND_HASH_FOREACH_KEY_VAL_IND(arr, num_key, var_name, entry) {
23252320
if (var_name) {
2326-
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
2321+
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))
2322+
|| zend_string_equals_literal(var_name, "this")) {
23272323
php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1);
23282324
if (!php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
23292325
zend_string_release(Z_STR(final_name));
@@ -2341,7 +2337,7 @@ static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_
23412337
continue;
23422338
}
23432339
}
2344-
if (Z_STRLEN(final_name) == sizeof("this")-1 && !strcmp(Z_STRVAL(final_name), "this")) {
2340+
if (zend_string_equals_literal(Z_STR(final_name), "this")) {
23452341
if (!exception_thrown) {
23462342
exception_thrown = 1;
23472343
zend_throw_error(NULL, "Cannot re-assign $this");
@@ -2370,7 +2366,6 @@ static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_
23702366

23712367
static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table) /* {{{ */
23722368
{
2373-
int exception_thrown = 0;
23742369
zend_long count = 0;
23752370
zend_string *var_name;
23762371
zval *entry, *orig_var;
@@ -2382,11 +2377,7 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table)
23822377
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
23832378
continue;
23842379
}
2385-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
2386-
if (!exception_thrown) {
2387-
exception_thrown = 1;
2388-
zend_throw_error(NULL, "Cannot re-assign $this");
2389-
}
2380+
if (zend_string_equals_literal(var_name, "this")) {
23902381
continue;
23912382
}
23922383
orig_var = zend_hash_find(symbol_table, var_name);
@@ -2414,7 +2405,6 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table)
24142405

24152406
static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /* {{{ */
24162407
{
2417-
int exception_thrown = 0;
24182408
zend_long count = 0;
24192409
zend_string *var_name;
24202410
zval *entry, *orig_var;
@@ -2426,11 +2416,7 @@ static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /*
24262416
if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) {
24272417
continue;
24282418
}
2429-
if (ZSTR_LEN(var_name) == sizeof("this")-1 && !strcmp(ZSTR_VAL(var_name), "this")) {
2430-
if (!exception_thrown) {
2431-
exception_thrown = 1;
2432-
zend_throw_error(NULL, "Cannot re-assign $this");
2433-
}
2419+
if (zend_string_equals_literal(var_name, "this")) {
24342420
continue;
24352421
}
24362422
orig_var = zend_hash_find(symbol_table, var_name);
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
--TEST--
2+
Test extract() with $this
3+
--FILE--
4+
<?php
5+
6+
class Extract
7+
{
8+
public function run(): void
9+
{
10+
$options = [
11+
'EXTR_OVERWRITE' => EXTR_OVERWRITE,
12+
'EXTR_SKIP' => EXTR_SKIP,
13+
'EXTR_PREFIX_SAME' => EXTR_PREFIX_SAME,
14+
'EXTR_PREFIX_ALL' => EXTR_PREFIX_ALL,
15+
'EXTR_PREFIX_INVALID' => EXTR_PREFIX_INVALID,
16+
'EXTR_IF_EXISTS' => EXTR_IF_EXISTS,
17+
'EXTR_PREFIX_IF_EXISTS' => EXTR_PREFIX_IF_EXISTS,
18+
];
19+
20+
foreach ($options as $name => $flags) {
21+
echo "{$name}\n";
22+
23+
$this->handle($name, $flags);
24+
$this->handle("{$name}_REFS", $flags | EXTR_REFS);
25+
echo "\n";
26+
}
27+
}
28+
29+
private function handle(string $name, int $flags): void
30+
{
31+
$array = ["this" => "value"];
32+
33+
try {
34+
$result = extract($array, $flags, "x");
35+
echo " extract() = {$result}\n";
36+
37+
echo " \$this = " . get_class($this) . "\n";
38+
echo " \$v_this = " . (isset($x_this) ? $x_this : "NULL") . "\n";
39+
} catch (\Throwable $e) {
40+
echo " Exception: " . $e->getMessage() . "\n";
41+
}
42+
}
43+
}
44+
45+
(new Extract)->run();
46+
47+
?>
48+
--EXPECT--
49+
EXTR_OVERWRITE
50+
Exception: Cannot re-assign $this
51+
Exception: Cannot re-assign $this
52+
53+
EXTR_SKIP
54+
extract() = 0
55+
$this = Extract
56+
$v_this = NULL
57+
extract() = 0
58+
$this = Extract
59+
$v_this = NULL
60+
61+
EXTR_PREFIX_SAME
62+
extract() = 1
63+
$this = Extract
64+
$v_this = value
65+
extract() = 1
66+
$this = Extract
67+
$v_this = value
68+
69+
EXTR_PREFIX_ALL
70+
extract() = 1
71+
$this = Extract
72+
$v_this = value
73+
extract() = 1
74+
$this = Extract
75+
$v_this = value
76+
77+
EXTR_PREFIX_INVALID
78+
extract() = 1
79+
$this = Extract
80+
$v_this = value
81+
extract() = 1
82+
$this = Extract
83+
$v_this = value
84+
85+
EXTR_IF_EXISTS
86+
extract() = 0
87+
$this = Extract
88+
$v_this = NULL
89+
extract() = 0
90+
$this = Extract
91+
$v_this = NULL
92+
93+
EXTR_PREFIX_IF_EXISTS
94+
extract() = 0
95+
$this = Extract
96+
$v_this = NULL
97+
extract() = 0
98+
$this = Extract
99+
$v_this = NULL

0 commit comments

Comments
 (0)