diff --git a/Zend/tests/gh418106144.phpt b/Zend/tests/gh418106144.phpt new file mode 100644 index 00000000000..9357b0a179b --- /dev/null +++ b/Zend/tests/gh418106144.phpt @@ -0,0 +1,20 @@ +--TEST-- +OSS-Fuzz #418106144 +--FILE-- +''){ + var_dump(); +} +try { + test(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Foo::__toString(): Return value must be of type string, none returned diff --git a/Zend/tests/oss_fuzz_417078295.phpt b/Zend/tests/oss_fuzz_417078295.phpt new file mode 100644 index 00000000000..6e53f9478e1 --- /dev/null +++ b/Zend/tests/oss_fuzz_417078295.phpt @@ -0,0 +1,17 @@ +--TEST-- +OSS-Fuzz #417078295 +--FILE-- + +--EXPECT-- +object(stdClass)#1 (0) refcount(2){ +} diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 5437208694d..8bdd29c5512 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -626,9 +626,10 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( /* op1 > op2 is the same as op2 < op1 */ binary_op_type op = ast->kind == ZEND_AST_GREATER ? is_smaller_function : is_smaller_or_equal_function; - ret = op(result, &op2, &op1); + op(result, &op2, &op1); zval_ptr_dtor_nogc(&op1); zval_ptr_dtor_nogc(&op2); + ret = EG(exception) ? FAILURE : SUCCESS; } break; case ZEND_AST_UNARY_OP: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 542692721fe..ef279f5395d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6438,6 +6438,7 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSE uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (OP1_TYPE != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -9111,7 +9112,6 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, ANY, REF) value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))); if (opline->extended_value & ZEND_BIND_REF) { - i_zval_ptr_dtor(variable_ptr); if (UNEXPECTED(!Z_ISREF_P(value))) { zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); GC_SET_REFCOUNT(ref, 2); @@ -9126,9 +9126,11 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, ANY, REF) ref->sources.ptr = NULL; Z_REF_P(value) = ref; Z_TYPE_INFO_P(value) = IS_REFERENCE_EX; + i_zval_ptr_dtor(variable_ptr); ZVAL_REF(variable_ptr, ref); } else { Z_ADDREF_P(value); + i_zval_ptr_dtor(variable_ptr); ZVAL_REF(variable_ptr, Z_REF_P(value)); if (OP2_TYPE != IS_UNUSED) { FREE_OP2(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a60ad827998..d55cad75d02 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7815,6 +7815,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HA uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -10244,6 +10245,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_H uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -11168,6 +11170,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_H uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -12734,6 +12737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDL uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -20945,6 +20949,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CONST_HAND uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -21385,6 +21390,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HAN uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -21841,6 +21847,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HAN uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -22241,6 +22248,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -26108,6 +26116,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CONST_HAND uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -28625,6 +28634,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HAN uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -30698,6 +30708,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HAN uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -33073,6 +33084,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -35423,6 +35435,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_H uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_UNUSED != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -37421,6 +37434,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_ uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_UNUSED != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -38053,6 +38067,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_ uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_UNUSED != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -40065,6 +40080,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HAND uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_UNUSED != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -41800,7 +41816,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZE value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))); if (opline->extended_value & ZEND_BIND_REF) { - i_zval_ptr_dtor(variable_ptr); if (UNEXPECTED(!Z_ISREF_P(value))) { zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); GC_SET_REFCOUNT(ref, 2); @@ -41815,9 +41830,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZE ref->sources.ptr = NULL; Z_REF_P(value) = ref; Z_TYPE_INFO_P(value) = IS_REFERENCE_EX; + i_zval_ptr_dtor(variable_ptr); ZVAL_REF(variable_ptr, ref); } else { Z_ADDREF_P(value); + i_zval_ptr_dtor(variable_ptr); ZVAL_REF(variable_ptr, Z_REF_P(value)); if (opline->op2_type != IS_UNUSED) { FREE_OP(opline->op2_type, opline->op2.var); @@ -45241,6 +45258,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDL uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -48994,6 +49012,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HAND uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -50957,6 +50976,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HAND uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; @@ -54588,6 +54608,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER( uint32_t size; USE_OPLINE + SAVE_OPLINE(); array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;