summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-12-06 11:10:31 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-12-06 11:10:31 +0100
commit07fc0764d1ca33bc9a7e5ccb0506f835827c402a (patch)
treec78ce7b8abc7cc8f2e8defd7458803aff14cab2f
parent8753975418e8737b433b2b8ad818d829f5edca96 (diff)
parent249e49092d0e7f4b38a83e59947797d4e255991f (diff)
downloadphp-git-07fc0764d1ca33bc9a7e5ccb0506f835827c402a.tar.gz
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fix constant evaluation of && and ||
-rw-r--r--Zend/tests/const_eval_and.phpt9
-rw-r--r--Zend/zend_compile.c27
2 files changed, 24 insertions, 12 deletions
diff --git a/Zend/tests/const_eval_and.phpt b/Zend/tests/const_eval_and.phpt
new file mode 100644
index 0000000000..90917bade5
--- /dev/null
+++ b/Zend/tests/const_eval_and.phpt
@@ -0,0 +1,9 @@
+--TEST--
+Incorrect constant evaluation of and/or (OSS-Fuzz #19255)
+--FILE--
+<?php
+const C = 0 && __namespace__;
+var_dump(C);
+?>
+--EXPECT--
+bool(false)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index b1f47673b9..dbbd9119a2 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -8778,25 +8778,28 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
case ZEND_AST_AND:
case ZEND_AST_OR:
{
- int i;
- for (i = 0; i <= 1; i++) {
- zend_eval_const_expr(&ast->child[i]);
- if (ast->child[i]->kind == ZEND_AST_ZVAL) {
- if (zend_is_true(zend_ast_get_zval(ast->child[i])) == (ast->kind == ZEND_AST_OR)) {
- ZVAL_BOOL(&result, ast->kind == ZEND_AST_OR);
- return;
- }
- }
+ zend_bool child0_is_true, child1_is_true;
+ zend_eval_const_expr(&ast->child[0]);
+ zend_eval_const_expr(&ast->child[1]);
+ if (ast->child[0]->kind != ZEND_AST_ZVAL) {
+ return;
}
- if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
+ child0_is_true = zend_is_true(zend_ast_get_zval(ast->child[0]));
+ if (child0_is_true == (ast->kind == ZEND_AST_OR)) {
+ ZVAL_BOOL(&result, ast->kind == ZEND_AST_OR);
+ break;
+ }
+
+ if (ast->child[1]->kind != ZEND_AST_ZVAL) {
return;
}
+ child1_is_true = zend_is_true(zend_ast_get_zval(ast->child[1]));
if (ast->kind == ZEND_AST_OR) {
- ZVAL_BOOL(&result, zend_is_true(zend_ast_get_zval(ast->child[0])) || zend_is_true(zend_ast_get_zval(ast->child[1])));
+ ZVAL_BOOL(&result, child0_is_true || child1_is_true);
} else {
- ZVAL_BOOL(&result, zend_is_true(zend_ast_get_zval(ast->child[0])) && zend_is_true(zend_ast_get_zval(ast->child[1])));
+ ZVAL_BOOL(&result, child0_is_true && child1_is_true);
}
break;
}