]> granicus.if.org Git - php/commitdiff
Fixed bug #80225
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 12 Oct 2020 14:34:19 +0000 (16:34 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 12 Oct 2020 14:35:09 +0000 (16:35 +0200)
Namespaced and declares have a different interpretation of what
"first statement" means.

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

diff --git a/NEWS b/NEWS
index 85e48c5e0e9a202d6e9ea6dda233159c77ee212c..86d1f2994d9ccd9b3e8248d8ab562c4cfc153e12 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? ????, PHP 8.0.0rc2
 
+- Core:
+  . Fixed bug #80225 (broken namespace usage in eval code). (Nikita)
+
 - Curl:
   . Fixed bug #80121 (Null pointer deref if CurlHandle directly instantiated).
     (Nikita)
diff --git a/Zend/tests/namespace_first_stmt_nop.phpt b/Zend/tests/namespace_first_stmt_nop.phpt
new file mode 100644 (file)
index 0000000..8f26fdc
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Nop statement before namespace
+--FILE--
+<?php
+;
+namespace Foo;
+?>
+===DONE===
+--EXPECT--
+===DONE===
index 7debd55accf3b18fdccd55c4880abd31cc7013c0..d5318f30a5a0eec2b7e241fbb7adbdca1d20add7 100644 (file)
@@ -5865,7 +5865,7 @@ zend_bool zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */
 /* }}} */
 
 /* Check whether this is the first statement, not counting declares. */
-static zend_result zend_is_first_statement(zend_ast *ast) /* {{{ */
+static zend_result zend_is_first_statement(zend_ast *ast, zend_bool allow_nop) /* {{{ */
 {
        uint32_t i = 0;
        zend_ast_list *file_ast = zend_ast_get_list(CG(ast));
@@ -5874,8 +5874,9 @@ static zend_result zend_is_first_statement(zend_ast *ast) /* {{{ */
                if (file_ast->child[i] == ast) {
                        return SUCCESS;
                } else if (file_ast->child[i] == NULL) {
-                       /* Empty statements count as statements. */
-                       return FAILURE;
+                       if (!allow_nop) {
+                               return FAILURE;
+                       }
                } else if (file_ast->child[i]->kind != ZEND_AST_DECLARE) {
                        return FAILURE;
                }
@@ -5909,14 +5910,14 @@ void zend_compile_declare(zend_ast *ast) /* {{{ */
                        zval_ptr_dtor_nogc(&value_zv);
                } else if (zend_string_equals_literal_ci(name, "encoding")) {
 
-                       if (FAILURE == zend_is_first_statement(ast)) {
+                       if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ 0)) {
                                zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be "
                                        "the very first statement in the script");
                        }
                } else if (zend_string_equals_literal_ci(name, "strict_types")) {
                        zval value_zv;
 
-                       if (FAILURE == zend_is_first_statement(ast)) {
+                       if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ 0)) {
                                zend_error_noreturn(E_COMPILE_ERROR, "strict_types declaration must be "
                                        "the very first statement in the script");
                        }
@@ -7669,7 +7670,7 @@ void zend_compile_namespace(zend_ast *ast) /* {{{ */
 
        zend_bool is_first_namespace = (!with_bracket && !FC(current_namespace))
                || (with_bracket && !FC(has_bracketed_namespaces));
-       if (is_first_namespace && FAILURE == zend_is_first_statement(ast)) {
+       if (is_first_namespace && FAILURE == zend_is_first_statement(ast, /* allow_nop */ 1)) {
                zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be "
                        "the very first statement or after any declare call in the script");
        }