summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyson Andre <tysonandre775@hotmail.com>2019-11-15 12:47:32 -0500
committerDmitry Stogov <dmitry@zend.com>2019-11-18 11:24:03 +0300
commita2c41c0ea6e6b6afbfaaeae25e66fd17e746a98a (patch)
tree3d599b8e163bc0596555a4a7b6b8ffbc5126b234
parent2c9926f156b2be6aa4f69a169d028c1ebc1eaa34 (diff)
downloadphp-git-a2c41c0ea6e6b6afbfaaeae25e66fd17e746a98a.tar.gz
Fix $x = (bool)$x; for undefined with opcache
And `$x = !$x` Noticed while working on GH-4912 The included test would not emit undefined variable errors in php 8.0 with opcache enabled. The command used: ``` php -d zend_extension=opcache.so --no-php-ini -d error_reporting=E_ALL \ -d opcache.file_cache= -d opcache.enable_cli=1 test.php ```
-rw-r--r--Zend/zend_vm_def.h8
-rw-r--r--Zend/zend_vm_execute.h24
-rw-r--r--ext/opcache/tests/bool_not_cv.phpt34
3 files changed, 58 insertions, 8 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index e4431e6a3a..ed84d17bb8 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -758,8 +758,10 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_TRUE(EX_VAR(opline->result.var));
- if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -4755,8 +4757,10 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_FALSE(EX_VAR(opline->result.var));
- if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d313e9502d..3f975dec0b 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -2653,8 +2653,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZE
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_TRUE(EX_VAR(opline->result.var));
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -3185,8 +3187,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_FALSE(EX_VAR(opline->result.var));
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -32866,8 +32870,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_TRUE(EX_VAR(opline->result.var));
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -33704,8 +33710,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_FALSE(EX_VAR(opline->result.var));
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -48537,8 +48545,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(Z
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_TRUE(EX_VAR(opline->result.var));
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -48801,8 +48811,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+ /* The result and op1 can be the same cv zval */
+ const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
ZVAL_FALSE(EX_VAR(opline->result.var));
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
diff --git a/ext/opcache/tests/bool_not_cv.phpt b/ext/opcache/tests/bool_not_cv.phpt
new file mode 100644
index 0000000000..ed3cf83514
--- /dev/null
+++ b/ext/opcache/tests/bool_not_cv.phpt
@@ -0,0 +1,34 @@
+--TEST--
+$v = !$v/(bool)$v checks for undefined variables
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_cache_only=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function undef_negation() {
+ echo "In undef_negation\n";
+ $v = !$v;
+ var_export($v);
+ echo "\n";
+}
+function undef_bool_cast() {
+ echo "In undef_bool_cast\n";
+ $v = (bool)$v;
+ var_export($v);
+ echo "\n";
+}
+undef_negation();
+undef_bool_cast();
+?>
+--EXPECTF--
+In undef_negation
+
+Notice: Undefined variable: v in %s on line 4
+true
+In undef_bool_cast
+
+Notice: Undefined variable: v in %s on line 10
+false