Skip to content

Commit a3e44bb

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Revert "Fix GH-10168: heap-buffer-overflow at zval_undefined_cv"
2 parents d62968c + efb9181 commit a3e44bb

File tree

7 files changed

+210
-502
lines changed

7 files changed

+210
-502
lines changed

Zend/tests/gh10168_1.phpt

Lines changed: 0 additions & 32 deletions
This file was deleted.

Zend/tests/gh10168_2.phpt

Lines changed: 0 additions & 32 deletions
This file was deleted.

Zend/tests/gh10168_3.phpt

Lines changed: 0 additions & 30 deletions
This file was deleted.

Zend/zend_execute.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3587,7 +3587,7 @@ static zend_always_inline void i_zval_ptr_dtor_noref(zval *zval_ptr) {
35873587
}
35883588
}
35893589

3590-
ZEND_API zval* zend_assign_to_typed_ref_and_result(zval *variable_ptr, zval *orig_value, zend_uchar value_type, bool strict, zval *result_variable_ptr)
3590+
ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *orig_value, zend_uchar value_type, bool strict)
35913591
{
35923592
bool ret;
35933593
zval value;
@@ -3607,9 +3607,6 @@ ZEND_API zval* zend_assign_to_typed_ref_and_result(zval *variable_ptr, zval *ori
36073607
} else {
36083608
zval_ptr_dtor_nogc(&value);
36093609
}
3610-
if (result_variable_ptr) {
3611-
ZVAL_COPY(result_variable_ptr, variable_ptr);
3612-
}
36133610
if (value_type & (IS_VAR|IS_TMP_VAR)) {
36143611
if (UNEXPECTED(ref)) {
36153612
if (UNEXPECTED(GC_DELREF(ref) == 0)) {
@@ -3623,11 +3620,6 @@ ZEND_API zval* zend_assign_to_typed_ref_and_result(zval *variable_ptr, zval *ori
36233620
return variable_ptr;
36243621
}
36253622

3626-
ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *orig_value, zend_uchar value_type, bool strict)
3627-
{
3628-
return zend_assign_to_typed_ref_and_result(variable_ptr, orig_value, value_type, strict, NULL);
3629-
}
3630-
36313623
ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref_ex(const zend_property_info *prop_info, zval *orig_val, bool strict, zend_verify_prop_assignable_by_ref_context context) {
36323624
zval *val = orig_val;
36333625
if (Z_ISREF_P(val) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(val))) {

Zend/zend_execute.h

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ ZEND_API bool zend_verify_internal_return_type(zend_function *zf, zval *ret);
118118
ZEND_API void ZEND_FASTCALL zend_ref_add_type_source(zend_property_info_source_list *source_list, zend_property_info *prop);
119119
ZEND_API void ZEND_FASTCALL zend_ref_del_type_source(zend_property_info_source_list *source_list, const zend_property_info *prop);
120120

121-
ZEND_API zval* zend_assign_to_typed_ref_and_result(zval *variable_ptr, zval *orig_value, zend_uchar value_type, bool strict, zval *result_variable_ptr);
122121
ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *value, zend_uchar value_type, bool strict);
123122

124123
static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type)
@@ -148,22 +147,12 @@ static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, zval *v
148147
}
149148
}
150149

151-
static zend_always_inline void zend_handle_garbage_from_variable_assignment(zend_refcounted *garbage)
152-
{
153-
if (GC_DELREF(garbage) == 0) {
154-
rc_dtor_func(garbage);
155-
} else { /* we need to split */
156-
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
157-
if (UNEXPECTED(GC_MAY_LEAK(garbage))) {
158-
gc_possible_root(garbage);
159-
}
160-
}
161-
}
162-
163150
static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type, bool strict)
164151
{
165152
do {
166153
if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
154+
zend_refcounted *garbage;
155+
167156
if (Z_ISREF_P(variable_ptr)) {
168157
if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
169158
return zend_assign_to_typed_ref(variable_ptr, value, value_type, strict);
@@ -174,42 +163,21 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
174163
break;
175164
}
176165
}
177-
zend_refcounted *garbage = Z_COUNTED_P(variable_ptr);
166+
garbage = Z_COUNTED_P(variable_ptr);
178167
zend_copy_to_variable(variable_ptr, value, value_type);
179-
zend_handle_garbage_from_variable_assignment(garbage);
180-
return variable_ptr;
181-
}
182-
} while (0);
183-
184-
zend_copy_to_variable(variable_ptr, value, value_type);
185-
return variable_ptr;
186-
}
187-
188-
static zend_always_inline zval* zend_assign_to_two_variables(zval *result_variable_ptr, zval *variable_ptr, zval *value, zend_uchar value_type, bool strict)
189-
{
190-
do {
191-
if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
192-
if (Z_ISREF_P(variable_ptr)) {
193-
if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
194-
variable_ptr = zend_assign_to_typed_ref_and_result(variable_ptr, value, value_type, strict, result_variable_ptr);
195-
return variable_ptr;
196-
}
197-
198-
variable_ptr = Z_REFVAL_P(variable_ptr);
199-
if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) {
200-
break;
168+
if (GC_DELREF(garbage) == 0) {
169+
rc_dtor_func(garbage);
170+
} else { /* we need to split */
171+
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
172+
if (UNEXPECTED(GC_MAY_LEAK(garbage))) {
173+
gc_possible_root(garbage);
201174
}
202175
}
203-
zend_refcounted *garbage = Z_COUNTED_P(variable_ptr);
204-
zend_copy_to_variable(variable_ptr, value, value_type);
205-
ZVAL_COPY(result_variable_ptr, variable_ptr);
206-
zend_handle_garbage_from_variable_assignment(garbage);
207176
return variable_ptr;
208177
}
209178
} while (0);
210179

211180
zend_copy_to_variable(variable_ptr, value, value_type);
212-
ZVAL_COPY(result_variable_ptr, variable_ptr);
213181
return variable_ptr;
214182
}
215183

Zend/zend_vm_def.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,9 +2587,6 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
25872587
Z_ADDREF_P(value);
25882588
}
25892589
}
2590-
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2591-
ZVAL_COPY(EX_VAR(opline->result.var), value);
2592-
}
25932590
} else {
25942591
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
25952592
if (OP2_TYPE == IS_CONST) {
@@ -2601,11 +2598,10 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
26012598
ZEND_VM_C_GOTO(assign_dim_error);
26022599
}
26032600
value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R);
2604-
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2605-
zend_assign_to_two_variables(EX_VAR(opline->result.var), variable_ptr, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2606-
} else {
2607-
zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2608-
}
2601+
value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
2602+
}
2603+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2604+
ZVAL_COPY(EX_VAR(opline->result.var), value);
26092605
}
26102606
} else {
26112607
if (EXPECTED(Z_ISREF_P(object_ptr))) {
@@ -2699,14 +2695,12 @@ ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
26992695
value = GET_OP2_ZVAL_PTR(BP_VAR_R);
27002696
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
27012697

2702-
if (RETURN_VALUE_USED(opline)) {
2703-
zend_assign_to_two_variables(EX_VAR(opline->result.var), variable_ptr, value, OP2_TYPE, EX_USES_STRICT_TYPES());
2704-
} else {
2705-
zend_assign_to_variable(variable_ptr, value, OP2_TYPE, EX_USES_STRICT_TYPES());
2698+
value = zend_assign_to_variable(variable_ptr, value, OP2_TYPE, EX_USES_STRICT_TYPES());
2699+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2700+
ZVAL_COPY(EX_VAR(opline->result.var), value);
27062701
}
2707-
27082702
FREE_OP1();
2709-
/* zend_assign_to_(two_)variable(s)() always takes care of op2, never free it! */
2703+
/* zend_assign_to_variable() always takes care of op2, never free it! */
27102704

27112705
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
27122706
}

0 commit comments

Comments
 (0)