]> granicus.if.org Git - php/commitdiff
Fix null pointer deref in compile_return()
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 27 Jul 2020 08:27:26 +0000 (10:27 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 27 Jul 2020 08:27:26 +0000 (10:27 +0200)
Fixes oss-fuzz #24387.

Zend/tests/return_ref_none.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/Zend/tests/return_ref_none.phpt b/Zend/tests/return_ref_none.phpt
new file mode 100644 (file)
index 0000000..39c41d0
--- /dev/null
@@ -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
index 51849a2f9439d8de61207ab6e9a214c648d0d92d..28abcf272d9f92be7b2c36ce8c9b7d35b7005e32 100644 (file)
@@ -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);