From: Nikita Popov Date: Mon, 13 Jul 2020 07:55:13 +0000 (+0200) Subject: Fixed bug #79828 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=213852de782df32a4de2cfc56a3d112c74db4ccf;p=php Fixed bug #79828 --- diff --git a/NEWS b/NEWS index 1d7e8885d9..222789cf01 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ PHP NEWS op). (Nikita) . Fixed bug #79841 (Syntax error in configure / unescaped "[]" in php.m4). (Nikita) + . Fixed bug #79828 (Segfault when trying to access non-existing variable). + (Nikita) 09 Jul 2020, PHP 8.0.0alpha2 diff --git a/Zend/tests/bug79828.phpt b/Zend/tests/bug79828.phpt new file mode 100644 index 0000000000..2bcb18e3e9 --- /dev/null +++ b/Zend/tests/bug79828.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #79828: Segfault when trying to access non-existing variable +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $uninitialized in %s on line %d + +Fatal error: Uncaught TypeError: foo(): Return value must be of type AnyType, null returned in %s:%d +Stack trace: +#0 %s(%d): foo() +#1 {main} + thrown in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 550a251cac..10266f4792 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4126,7 +4126,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV #if !ZEND_VM_SPEC || (OP1_TYPE != IS_UNUSED) zval *retval_ref, *retval_ptr; zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); + retval_ref = retval_ptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP1_TYPE == IS_CONST) { ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); @@ -4144,6 +4144,14 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV ZEND_VM_NEXT_OPCODE(); } + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + zend_reference *ref = NULL; void *cache_slot = CACHE_ADDR(opline->op2.num); if (UNEXPECTED(retval_ref != retval_ptr)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5dcd4812e9..de4b37e9c3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8825,6 +8825,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP ZEND_VM_NEXT_OPCODE(); } + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + zend_reference *ref = NULL; void *cache_slot = CACHE_ADDR(opline->op2.num); if (UNEXPECTED(retval_ref != retval_ptr)) { @@ -18934,6 +18942,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN ZEND_VM_NEXT_OPCODE(); } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + zend_reference *ref = NULL; void *cache_slot = CACHE_ADDR(opline->op2.num); if (UNEXPECTED(retval_ref != retval_ptr)) { @@ -26456,6 +26472,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN ZEND_VM_NEXT_OPCODE(); } + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + zend_reference *ref = NULL; void *cache_slot = CACHE_ADDR(opline->op2.num); if (UNEXPECTED(retval_ref != retval_ptr)) { @@ -33176,6 +33200,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED ZEND_VM_NEXT_OPCODE(); } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + zend_reference *ref = NULL; void *cache_slot = CACHE_ADDR(opline->op2.num); if (UNEXPECTED(retval_ref != retval_ptr)) { @@ -44739,7 +44771,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU #if 0 || (IS_CV != IS_UNUSED) zval *retval_ref, *retval_ptr; zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + retval_ref = retval_ptr = EX_VAR(opline->op1.var); if (IS_CV == IS_CONST) { ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); @@ -44757,6 +44789,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU ZEND_VM_NEXT_OPCODE(); } + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + zend_reference *ref = NULL; void *cache_slot = CACHE_ADDR(opline->op2.num); if (UNEXPECTED(retval_ref != retval_ptr)) {