summaryrefslogtreecommitdiff
path: root/Zend/zend_compile.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-09-21 12:37:44 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-09-21 12:37:44 +0200
commitc5f93d191e2bf5a9def069cf9701b5eb6e297a74 (patch)
tree7d0f822aacc7344e492f7007e7aeb1386c908e57 /Zend/zend_compile.c
parentef9ab9159b409c6d3ea184b4ba88764d85c4133b (diff)
downloadphp-git-c5f93d191e2bf5a9def069cf9701b5eb6e297a74.tar.gz
Fix detection of code outside namespace
Due to improvements to early binding, the opcode based check is no longer accurate. Reuse the syntactic check we're already using for declares instead.
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r--Zend/zend_compile.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f42542c6b2..ba6790a042 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5864,20 +5864,19 @@ zend_bool zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */
}
/* }}} */
-static zend_result zend_declare_is_first_statement(zend_ast *ast) /* {{{ */
+/* Check whether this is the first statement, not counting declares. */
+static zend_result zend_is_first_statement(zend_ast *ast) /* {{{ */
{
uint32_t i = 0;
zend_ast_list *file_ast = zend_ast_get_list(CG(ast));
- /* Check to see if this declare is preceded only by declare statements */
while (i < file_ast->children) {
if (file_ast->child[i] == ast) {
return SUCCESS;
} else if (file_ast->child[i] == NULL) {
- /* Empty statements are not allowed prior to a declare */
+ /* Empty statements count as statements. */
return FAILURE;
} else if (file_ast->child[i]->kind != ZEND_AST_DECLARE) {
- /* declares can only be preceded by other declares */
return FAILURE;
}
i++;
@@ -5910,14 +5909,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_declare_is_first_statement(ast)) {
+ if (FAILURE == zend_is_first_statement(ast)) {
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_declare_is_first_statement(ast)) {
+ if (FAILURE == zend_is_first_statement(ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "strict_types declaration must be "
"the very first statement in the script");
}
@@ -7682,20 +7681,11 @@ void zend_compile_namespace(zend_ast *ast) /* {{{ */
}
}
- if (((!with_bracket && !FC(current_namespace))
- || (with_bracket && !FC(has_bracketed_namespaces))) && CG(active_op_array)->last > 0
- ) {
- /* ignore ZEND_EXT_STMT and ZEND_TICKS */
- uint32_t num = CG(active_op_array)->last;
- while (num > 0 &&
- (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
- CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
- --num;
- }
- if (num > 0) {
- zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be "
- "the very first statement or after any declare call in the script");
- }
+ 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)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be "
+ "the very first statement or after any declare call in the script");
}
if (FC(current_namespace)) {