Skip to content

Commit 712dd6c

Browse files
committed
Fixed "foreach ($reference as $val)"
1 parent c5af715 commit 712dd6c

File tree

2 files changed

+155
-142
lines changed

2 files changed

+155
-142
lines changed

Zend/zend_vm_def.h

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4213,20 +4213,18 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
42134213
{
42144214
USE_OPLINE
42154215
zend_free_op free_op1;
4216-
zval *array_ptr;
4216+
zval *array_ptr, *array_ref;
42174217
HashTable *fe_ht;
42184218
zend_object_iterator *iter = NULL;
42194219
zend_class_entry *ce = NULL;
42204220
zend_bool is_empty = 0;
4221-
zval *array_ref = NULL;
42224221

42234222
SAVE_OPLINE();
42244223

42254224
if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
42264225
(opline->extended_value & ZEND_FE_RESET_VARIABLE)) {
4227-
array_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
4228-
if (Z_ISREF_P(array_ptr)) {
4229-
array_ref = array_ptr;
4226+
array_ptr = array_ref = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
4227+
if (Z_ISREF_P(array_ref)) {
42304228
array_ptr = Z_REFVAL_P(array_ptr);
42314229
}
42324230
if (Z_TYPE_P(array_ptr) == IS_NULL) {
@@ -4238,27 +4236,29 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
42384236

42394237
ce = Z_OBJCE_P(array_ptr);
42404238
if (!ce || ce->get_iterator == NULL) {
4241-
if (!array_ref) {
4239+
if (!Z_ISREF_P(array_ref)) {
42424240
SEPARATE_ZVAL(array_ptr);
42434241
}
42444242
Z_ADDREF_P(array_ptr);
42454243
}
4244+
array_ref = array_ptr;
42464245
} else {
42474246
if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
4248-
if (!array_ref) {
4247+
if (!Z_ISREF_P(array_ref)) {
42494248
SEPARATE_ZVAL(array_ptr);
4249+
array_ref = array_ptr;
42504250
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
42514251
ZVAL_NEW_REF(array_ptr, array_ptr);
4252+
array_ref = array_ptr;
42524253
array_ptr = Z_REFVAL_P(array_ptr);
42534254
}
42544255
}
42554256
}
4256-
if (Z_REFCOUNTED_P(array_ptr)) Z_ADDREF_P(array_ptr);
4257+
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
42574258
}
42584259
} else {
4259-
array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
4260-
if (Z_ISREF_P(array_ptr)) {
4261-
array_ref = array_ptr;
4260+
array_ptr = array_ref = GET_OP1_ZVAL_PTR(BP_VAR_R);
4261+
if (Z_ISREF_P(array_ref)) {
42624262
array_ptr = Z_REFVAL_P(array_ptr);
42634263
}
42644264
if (IS_OP1_TMP_FREE()) { /* IS_TMP_VAR */
@@ -4269,33 +4269,33 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
42694269
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
42704270
ce = Z_OBJCE_P(array_ptr);
42714271
if (ce && ce->get_iterator) {
4272-
Z_DELREF_P(array_ptr);
4272+
Z_DELREF_P(array_ref);
42734273
}
42744274
}
42754275
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
42764276
ce = Z_OBJCE_P(array_ptr);
42774277
if (!ce || !ce->get_iterator) {
42784278
if (OP1_TYPE == IS_CV) {
4279-
Z_ADDREF_P(array_ptr);
4279+
Z_ADDREF_P(array_ref);
42804280
}
42814281
}
4282-
} else if (Z_REFCOUNTED_P(array_ptr)) {
4282+
} else if (Z_REFCOUNTED_P(array_ref)) {
42834283
if (OP1_TYPE == IS_CONST ||
42844284
(OP1_TYPE == IS_CV &&
4285-
(array_ref == NULL) &&
4286-
Z_REFCOUNT_P(array_ptr) > 1) ||
4285+
!Z_ISREF_P(array_ref) &&
4286+
Z_REFCOUNT_P(array_ref) > 1) ||
42874287
(OP1_TYPE == IS_VAR &&
4288-
(array_ref == NULL) &&
4289-
Z_REFCOUNT_P(array_ptr) > 2)) {
4288+
!Z_ISREF_P(array_ref) &&
4289+
Z_REFCOUNT_P(array_ref) > 2)) {
42904290
zval tmp;
42914291

42924292
if (OP1_TYPE == IS_VAR) {
4293-
Z_DELREF_P(array_ptr);
4293+
Z_DELREF_P(array_ref);
42944294
}
4295-
ZVAL_DUP(&tmp, array_ptr);
4296-
array_ptr = &tmp;
4295+
ZVAL_DUP(&tmp, array_ref);
4296+
array_ptr = array_ref = &tmp;
42974297
} else if (OP1_TYPE == IS_CV) {
4298-
Z_ADDREF_P(array_ptr);
4298+
Z_ADDREF_P(array_ref);
42994299
}
43004300
}
43014301
}
@@ -4309,8 +4309,9 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
43094309
if (iter && EXPECTED(EG(exception) == NULL)) {
43104310
zval iterator;
43114311

4312-
array_ptr = &iterator;
4312+
array_ptr = array_ref = &iterator;
43134313
ZVAL_OBJ(array_ptr, &iter->std);
4314+
43144315
} else {
43154316
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
43164317
FREE_OP1_VAR_PTR();
@@ -4323,14 +4324,14 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
43234324
}
43244325
}
43254326

4326-
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ptr);
4327+
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
43274328

43284329
if (iter) {
43294330
iter->index = 0;
43304331
if (iter->funcs->rewind) {
43314332
iter->funcs->rewind(iter TSRMLS_CC);
43324333
if (UNEXPECTED(EG(exception) != NULL)) {
4333-
zval_ptr_dtor(array_ptr);
4334+
zval_ptr_dtor(array_ref);
43344335
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
43354336
FREE_OP1_VAR_PTR();
43364337
}
@@ -4339,7 +4340,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
43394340
}
43404341
is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
43414342
if (UNEXPECTED(EG(exception) != NULL)) {
4342-
zval_ptr_dtor(array_ptr);
4343+
zval_ptr_dtor(array_ref);
43434344
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
43444345
FREE_OP1_VAR_PTR();
43454346
}
@@ -4386,12 +4387,16 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
43864387
{
43874388
USE_OPLINE
43884389
zend_free_op free_op1;
4389-
zval *array = EX_VAR(opline->op1.var);
4390+
zval *array, *array_ref;
43904391
zval *value;
43914392
HashTable *fe_ht;
43924393
zend_object_iterator *iter = NULL;
4393-
43944394
zval *key = NULL;
4395+
4396+
array = array_ref = EX_VAR(opline->op1.var);
4397+
if (Z_TYPE_P(array) == IS_REFERENCE) {
4398+
array = Z_REFVAL_P(array);
4399+
}
43954400
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
43964401
key = EX_VAR((opline+1)->result.var);
43974402
}
@@ -4461,22 +4466,22 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
44614466
* In case that ever happens we need an additional flag. */
44624467
iter->funcs->move_forward(iter TSRMLS_CC);
44634468
if (UNEXPECTED(EG(exception) != NULL)) {
4464-
zval_ptr_dtor(array);
4469+
zval_ptr_dtor(array_ref);
44654470
HANDLE_EXCEPTION();
44664471
}
44674472
}
44684473
/* If index is zero we come from FE_RESET and checked valid() already. */
44694474
if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) {
44704475
/* reached end of iteration */
44714476
if (UNEXPECTED(EG(exception) != NULL)) {
4472-
zval_ptr_dtor(array);
4477+
zval_ptr_dtor(array_ref);
44734478
HANDLE_EXCEPTION();
44744479
}
44754480
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
44764481
}
44774482
value = iter->funcs->get_current_data(iter TSRMLS_CC);
44784483
if (UNEXPECTED(EG(exception) != NULL)) {
4479-
zval_ptr_dtor(array);
4484+
zval_ptr_dtor(array_ref);
44804485
HANDLE_EXCEPTION();
44814486
}
44824487
if (!value) {
@@ -4487,7 +4492,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
44874492
if (iter->funcs->get_current_key) {
44884493
iter->funcs->get_current_key(iter, key TSRMLS_CC);
44894494
if (UNEXPECTED(EG(exception) != NULL)) {
4490-
zval_ptr_dtor(array);
4495+
zval_ptr_dtor(array_ref);
44914496
HANDLE_EXCEPTION();
44924497
}
44934498
} else {

0 commit comments

Comments
 (0)