mirror of
https://github.com/php/php-src.git
synced 2024-11-23 09:54:15 +08:00
Adjust filename/lineno for constant expressions
Closes GH-7771 Closes GH-8124
This commit is contained in:
parent
634b2141de
commit
e3ef7bbbb8
1
NEWS
1
NEWS
@ -7,6 +7,7 @@ PHP NEWS
|
||||
|
||||
- Core:
|
||||
. Fixed bug #81380 (Observer may not be initialized properly). (krakjoe)
|
||||
. Fixed bug GH-7771 (Fix filename/lineno of constant expressions). (ilutov)
|
||||
|
||||
- Intl:
|
||||
. Update all grandfathered language tags with preferred values
|
||||
|
@ -11,4 +11,4 @@ echo Foo::A."\n";
|
||||
Fatal error: Uncaught Error: Undefined constant self::B in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %sbug41633_2.php on line 5
|
||||
thrown in %sbug41633_2.php on line 3
|
||||
|
15
Zend/tests/gh7771_1.phpt
Normal file
15
Zend/tests/gh7771_1.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
GH-7771 (Incorrect file/line for class constant expression exceptions)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include __DIR__ . '/gh7771_1_definition.inc';
|
||||
|
||||
new Foo();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_1_definition.inc:4
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %sgh7771_1_definition.inc on line 4
|
5
Zend/tests/gh7771_1_definition.inc
Normal file
5
Zend/tests/gh7771_1_definition.inc
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
public const BAR = NonExistent::CLASS_CONSTANT;
|
||||
}
|
15
Zend/tests/gh7771_2.phpt
Normal file
15
Zend/tests/gh7771_2.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
GH-7771 (Incorrect file/line for class constant expression exceptions)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include __DIR__ . '/gh7771_2_definition.inc';
|
||||
|
||||
new Foo();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_2_definition.inc:6
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %sgh7771_2_definition.inc on line 6
|
8
Zend/tests/gh7771_2_definition.inc
Normal file
8
Zend/tests/gh7771_2_definition.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
public const BAR =
|
||||
self::BAZ
|
||||
+ NonExistent::CLASS_CONSTANT;
|
||||
public const BAZ = 42;
|
||||
}
|
@ -789,7 +789,20 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast
|
||||
{
|
||||
zend_string *class_name = zend_ast_get_str(ast->child[0]);
|
||||
zend_string *const_name = zend_ast_get_str(ast->child[1]);
|
||||
|
||||
zend_string *previous_filename;
|
||||
zend_long previous_lineno;
|
||||
if (scope) {
|
||||
previous_filename = EG(filename_override);
|
||||
previous_lineno = EG(lineno_override);
|
||||
EG(filename_override) = scope->info.user.filename;
|
||||
EG(lineno_override) = zend_ast_get_lineno(ast);
|
||||
}
|
||||
zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr);
|
||||
if (scope) {
|
||||
EG(filename_override) = previous_filename;
|
||||
EG(lineno_override) = previous_lineno;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(zv == NULL)) {
|
||||
ZVAL_UNDEF(result);
|
||||
@ -951,6 +964,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
|
||||
zend_ast *new = (zend_ast*)buf;
|
||||
new->kind = ast->kind;
|
||||
new->attr = ast->attr;
|
||||
new->lineno = ast->lineno;
|
||||
buf = (void*)((char*)buf + zend_ast_size(children));
|
||||
for (i = 0; i < children; i++) {
|
||||
if (ast->child[i]) {
|
||||
|
@ -192,6 +192,9 @@ void init_executor(void) /* {{{ */
|
||||
EG(num_errors) = 0;
|
||||
EG(errors) = NULL;
|
||||
|
||||
EG(filename_override) = NULL;
|
||||
EG(lineno_override) = -1;
|
||||
|
||||
zend_fiber_init();
|
||||
zend_weakrefs_init();
|
||||
|
||||
@ -462,6 +465,8 @@ void shutdown_executor(void) /* {{{ */
|
||||
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
|
||||
efree(EG(ht_iterators));
|
||||
}
|
||||
|
||||
ZEND_ASSERT(EG(filename_override) == NULL);
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
@ -591,21 +596,18 @@ ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t a
|
||||
|
||||
ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
|
||||
{
|
||||
zend_execute_data *ex = EG(current_execute_data);
|
||||
|
||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||
ex = ex->prev_execute_data;
|
||||
}
|
||||
if (ex) {
|
||||
return ZSTR_VAL(ex->func->op_array.filename);
|
||||
} else {
|
||||
return "[no active file]";
|
||||
}
|
||||
zend_string *filename = zend_get_executed_filename_ex();
|
||||
return filename != NULL ? ZSTR_VAL(filename) : "[no active file]";
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
|
||||
{
|
||||
zend_string *filename_override = EG(filename_override);
|
||||
if (filename_override != NULL) {
|
||||
return filename_override;
|
||||
}
|
||||
|
||||
zend_execute_data *ex = EG(current_execute_data);
|
||||
|
||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||
@ -621,6 +623,11 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
|
||||
|
||||
ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
|
||||
{
|
||||
zend_long lineno_override = EG(lineno_override);
|
||||
if (lineno_override != -1) {
|
||||
return lineno_override;
|
||||
}
|
||||
|
||||
zend_execute_data *ex = EG(current_execute_data);
|
||||
|
||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||
|
@ -266,6 +266,10 @@ struct _zend_executor_globals {
|
||||
uint32_t num_errors;
|
||||
zend_error_info **errors;
|
||||
|
||||
/* Override filename or line number of thrown errors and exceptions */
|
||||
zend_string *filename_override;
|
||||
zend_long lineno_override;
|
||||
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user