summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-07-27 10:27:26 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-07-27 10:27:26 +0200
commit08e6c209550a268500bbdef48c1b19494272e6e8 (patch)
treeb5f2b3dae374a07a26a90ab5e9b1bdfc5c561697
parent3b5b288127db317b7a6fecf4fd00ae59a8e41da9 (diff)
downloadphp-git-08e6c209550a268500bbdef48c1b19494272e6e8.tar.gz
Fix null pointer deref in compile_return()
Fixes oss-fuzz #24387.
-rw-r--r--Zend/tests/return_ref_none.phpt14
-rw-r--r--Zend/zend_compile.c8
2 files changed, 18 insertions, 4 deletions
diff --git a/Zend/tests/return_ref_none.phpt b/Zend/tests/return_ref_none.phpt
new file mode 100644
index 0000000000..39c41d032b
--- /dev/null
+++ b/Zend/tests/return_ref_none.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Argument-less return from by-ref function
+--FILE--
+<?php
+
+function &test() {
+ return;
+}
+
+$ref =& test();
+
+?>
+--EXPECTF--
+Notice: Only variable references should be returned by reference in %s on line %d
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 51849a2f94..28abcf272d 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -4631,14 +4631,14 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
by_ref = 0;
}
- if (by_ref && zend_ast_is_short_circuited(expr_ast)) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
- }
-
if (!expr_ast) {
expr_node.op_type = IS_CONST;
ZVAL_NULL(&expr_node.u.constant);
} else if (by_ref && zend_is_variable(expr_ast)) {
+ if (zend_ast_is_short_circuited(expr_ast)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
+ }
+
zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1);
} else {
zend_compile_expr(&expr_node, expr_ast);