Skip to content

Commit fd463a9

Browse files
committed
Fixed bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in _get_zval_ptr_tmp failed).
1 parent ae926d8 commit fd463a9

File tree

6 files changed

+76
-105
lines changed

6 files changed

+76
-105
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 7.3.0beta3
44

5+
- Core:
6+
. Fixed bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in
7+
_get_zval_ptr_tmp failed). (Laruence)
8+
59
- Opcache:
610
. Fixed bug #76747 (Opcache treats path containing "test.pharma.tld" as a phar
711
file). (Laruence)

Zend/tests/bug76752.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in _get_zval_ptr_tmp failed)
3+
--FILE--
4+
<?php
5+
$obj = new stdClass;
6+
$val = 'foo';
7+
$obj->prop = &$val;
8+
var_dump($obj->prop ?? []);
9+
?>
10+
--EXPECT--
11+
string(3) "foo"

Zend/zend_vm_def.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6527,7 +6527,7 @@ ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
65276527
ZEND_VM_NEXT_OPCODE();
65286528
}
65296529

6530-
ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
6530+
ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMPVAR|CV, JMP_ADDR)
65316531
{
65326532
USE_OPLINE
65336533
zend_free_op free_op1;
@@ -6537,8 +6537,8 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
65376537
SAVE_OPLINE();
65386538
value = GET_OP1_ZVAL_PTR(BP_VAR_IS);
65396539

6540-
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
6541-
if (OP1_TYPE == IS_VAR) {
6540+
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
6541+
if (OP1_TYPE & IS_VAR) {
65426542
ref = value;
65436543
}
65446544
value = Z_REFVAL_P(value);
@@ -6551,7 +6551,7 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
65516551
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
65526552
} else if (OP1_TYPE == IS_CV) {
65536553
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
6554-
} else if (OP1_TYPE == IS_VAR && ref) {
6554+
} else if ((OP1_TYPE & IS_VAR) && ref) {
65556555
zend_reference *r = Z_REF_P(ref);
65566556

65576557
if (UNEXPECTED(GC_DELREF(r) == 0)) {

Zend/zend_vm_execute.h

Lines changed: 54 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -3545,8 +3545,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON
35453545
SAVE_OPLINE();
35463546
value = RT_CONSTANT(opline, opline->op1);
35473547

3548-
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) {
3549-
if (IS_CONST == IS_VAR) {
3548+
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
3549+
if (IS_CONST & IS_VAR) {
35503550
ref = value;
35513551
}
35523552
value = Z_REFVAL_P(value);
@@ -3559,7 +3559,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON
35593559
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
35603560
} else if (IS_CONST == IS_CV) {
35613561
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
3562-
} else if (IS_CONST == IS_VAR && ref) {
3562+
} else if ((IS_CONST & IS_VAR) && ref) {
35633563
zend_reference *r = Z_REF_P(ref);
35643564

35653565
if (UNEXPECTED(GC_DELREF(r) == 0)) {
@@ -12781,6 +12781,46 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_TMPVAR_
1278112781
ZEND_VM_NEXT_OPCODE(); /* Never reached */
1278212782
}
1278312783

12784+
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
12785+
{
12786+
USE_OPLINE
12787+
zend_free_op free_op1;
12788+
zval *value;
12789+
zval *ref = NULL;
12790+
12791+
SAVE_OPLINE();
12792+
value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
12793+
12794+
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
12795+
if ((IS_TMP_VAR|IS_VAR) & IS_VAR) {
12796+
ref = value;
12797+
}
12798+
value = Z_REFVAL_P(value);
12799+
}
12800+
12801+
if (Z_TYPE_P(value) > IS_NULL) {
12802+
zval *result = EX_VAR(opline->result.var);
12803+
ZVAL_COPY_VALUE(result, value);
12804+
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
12805+
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
12806+
} else if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
12807+
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
12808+
} else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && ref) {
12809+
zend_reference *r = Z_REF_P(ref);
12810+
12811+
if (UNEXPECTED(GC_DELREF(r) == 0)) {
12812+
efree_size(r, sizeof(zend_reference));
12813+
} else if (Z_OPT_REFCOUNTED_P(result)) {
12814+
Z_ADDREF_P(result);
12815+
}
12816+
}
12817+
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
12818+
}
12819+
12820+
zval_ptr_dtor_nogc(free_op1);
12821+
ZEND_VM_NEXT_OPCODE();
12822+
}
12823+
1278412824
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
1278512825
{
1278612826
USE_OPLINE
@@ -18393,46 +18433,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_
1839318433
ZEND_VM_NEXT_OPCODE();
1839418434
}
1839518435

18396-
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
18397-
{
18398-
USE_OPLINE
18399-
zend_free_op free_op1;
18400-
zval *value;
18401-
zval *ref = NULL;
18402-
18403-
SAVE_OPLINE();
18404-
value = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
18405-
18406-
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) {
18407-
if (IS_TMP_VAR == IS_VAR) {
18408-
ref = value;
18409-
}
18410-
value = Z_REFVAL_P(value);
18411-
}
18412-
18413-
if (Z_TYPE_P(value) > IS_NULL) {
18414-
zval *result = EX_VAR(opline->result.var);
18415-
ZVAL_COPY_VALUE(result, value);
18416-
if (IS_TMP_VAR == IS_CONST) {
18417-
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
18418-
} else if (IS_TMP_VAR == IS_CV) {
18419-
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
18420-
} else if (IS_TMP_VAR == IS_VAR && ref) {
18421-
zend_reference *r = Z_REF_P(ref);
18422-
18423-
if (UNEXPECTED(GC_DELREF(r) == 0)) {
18424-
efree_size(r, sizeof(zend_reference));
18425-
} else if (Z_OPT_REFCOUNTED_P(result)) {
18426-
Z_ADDREF_P(result);
18427-
}
18428-
}
18429-
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
18430-
}
18431-
18432-
zval_ptr_dtor_nogc(free_op1);
18433-
ZEND_VM_NEXT_OPCODE();
18434-
}
18435-
1843618436
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
1843718437
{
1843818438
USE_OPLINE
@@ -21755,46 +21755,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_
2175521755
ZEND_VM_NEXT_OPCODE();
2175621756
}
2175721757

21758-
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
21759-
{
21760-
USE_OPLINE
21761-
zend_free_op free_op1;
21762-
zval *value;
21763-
zval *ref = NULL;
21764-
21765-
SAVE_OPLINE();
21766-
value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
21767-
21768-
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) {
21769-
if (IS_VAR == IS_VAR) {
21770-
ref = value;
21771-
}
21772-
value = Z_REFVAL_P(value);
21773-
}
21774-
21775-
if (Z_TYPE_P(value) > IS_NULL) {
21776-
zval *result = EX_VAR(opline->result.var);
21777-
ZVAL_COPY_VALUE(result, value);
21778-
if (IS_VAR == IS_CONST) {
21779-
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
21780-
} else if (IS_VAR == IS_CV) {
21781-
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
21782-
} else if (IS_VAR == IS_VAR && ref) {
21783-
zend_reference *r = Z_REF_P(ref);
21784-
21785-
if (UNEXPECTED(GC_DELREF(r) == 0)) {
21786-
efree_size(r, sizeof(zend_reference));
21787-
} else if (Z_OPT_REFCOUNTED_P(result)) {
21788-
Z_ADDREF_P(result);
21789-
}
21790-
}
21791-
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
21792-
}
21793-
21794-
zval_ptr_dtor_nogc(free_op1);
21795-
ZEND_VM_NEXT_OPCODE();
21796-
}
21797-
2179821758
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
2179921759
{
2180021760
USE_OPLINE
@@ -37965,8 +37925,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_
3796537925
SAVE_OPLINE();
3796637926
value = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
3796737927

37968-
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) {
37969-
if (IS_CV == IS_VAR) {
37928+
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
37929+
if (IS_CV & IS_VAR) {
3797037930
ref = value;
3797137931
}
3797237932
value = Z_REFVAL_P(value);
@@ -37979,7 +37939,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_
3797937939
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
3798037940
} else if (IS_CV == IS_CV) {
3798137941
if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
37982-
} else if (IS_CV == IS_VAR && ref) {
37942+
} else if ((IS_CV & IS_VAR) && ref) {
3798337943
zend_reference *r = Z_REF_P(ref);
3798437944

3798537945
if (UNEXPECTED(GC_DELREF(r) == 0)) {
@@ -54125,8 +54085,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5412554085
(void*)&&ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_LABEL,
5412654086
(void*)&&ZEND_BIND_GLOBAL_SPEC_CV_CONST_LABEL,
5412754087
(void*)&&ZEND_COALESCE_SPEC_CONST_LABEL,
54128-
(void*)&&ZEND_COALESCE_SPEC_TMP_LABEL,
54129-
(void*)&&ZEND_COALESCE_SPEC_VAR_LABEL,
54088+
(void*)&&ZEND_COALESCE_SPEC_TMPVAR_LABEL,
54089+
(void*)&&ZEND_COALESCE_SPEC_TMPVAR_LABEL,
5413054090
(void*)&&ZEND_NULL_LABEL,
5413154091
(void*)&&ZEND_COALESCE_SPEC_CV_LABEL,
5413254092
(void*)&&ZEND_SPACESHIP_SPEC_CONST_CONST_LABEL,
@@ -56879,6 +56839,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5687956839
VM_TRACE(ZEND_EXIT_SPEC_TMPVAR)
5688056840
ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5688156841
HYBRID_BREAK();
56842+
HYBRID_CASE(ZEND_COALESCE_SPEC_TMPVAR):
56843+
VM_TRACE(ZEND_COALESCE_SPEC_TMPVAR)
56844+
ZEND_COALESCE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
56845+
HYBRID_BREAK();
5688256846
HYBRID_CASE(ZEND_STRLEN_SPEC_TMPVAR):
5688356847
VM_TRACE(ZEND_STRLEN_SPEC_TMPVAR)
5688456848
ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -57441,10 +57405,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5744157405
VM_TRACE(ZEND_JMP_SET_SPEC_TMP)
5744257406
ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5744357407
HYBRID_BREAK();
57444-
HYBRID_CASE(ZEND_COALESCE_SPEC_TMP):
57445-
VM_TRACE(ZEND_COALESCE_SPEC_TMP)
57446-
ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
57447-
HYBRID_BREAK();
5744857408
HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_TMP):
5744957409
VM_TRACE(ZEND_QM_ASSIGN_SPEC_TMP)
5745057410
ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -57759,10 +57719,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5775957719
VM_TRACE(ZEND_JMP_SET_SPEC_VAR)
5776057720
ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5776157721
HYBRID_BREAK();
57762-
HYBRID_CASE(ZEND_COALESCE_SPEC_VAR):
57763-
VM_TRACE(ZEND_COALESCE_SPEC_VAR)
57764-
ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
57765-
HYBRID_BREAK();
5776657722
HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_VAR):
5776757723
VM_TRACE(ZEND_QM_ASSIGN_SPEC_VAR)
5776857724
ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -63628,8 +63584,8 @@ void zend_vm_init(void)
6362863584
ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_HANDLER,
6362963585
ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER,
6363063586
ZEND_COALESCE_SPEC_CONST_HANDLER,
63631-
ZEND_COALESCE_SPEC_TMP_HANDLER,
63632-
ZEND_COALESCE_SPEC_VAR_HANDLER,
63587+
ZEND_COALESCE_SPEC_TMPVAR_HANDLER,
63588+
ZEND_COALESCE_SPEC_TMPVAR_HANDLER,
6363363589
ZEND_NULL_HANDLER,
6363463590
ZEND_COALESCE_SPEC_CV_HANDLER,
6363563591
ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER,

Zend/zend_vm_handlers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,8 +1404,8 @@
14041404
_(2738, ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ) \
14051405
_(2739, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \
14061406
_(2740, ZEND_COALESCE_SPEC_CONST) \
1407-
_(2741, ZEND_COALESCE_SPEC_TMP) \
1408-
_(2742, ZEND_COALESCE_SPEC_VAR) \
1407+
_(2741, ZEND_COALESCE_SPEC_TMPVAR) \
1408+
_(2742, ZEND_COALESCE_SPEC_TMPVAR) \
14091409
_(2744, ZEND_COALESCE_SPEC_CV) \
14101410
_(2745, ZEND_SPACESHIP_SPEC_CONST_CONST) \
14111411
_(2746, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \

Zend/zend_vm_opcodes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
394394
0x00000707,
395395
0x04046751,
396396
0x00040301,
397-
0x00002003,
397+
0x00002007,
398398
0x00000707,
399399
0x03000000,
400400
0x03000303,

0 commit comments

Comments
 (0)