Skip to content

Commit e3ef7bb

Browse files
committed
Adjust filename/lineno for constant expressions
Closes GH-7771 Closes GH-8124
1 parent 634b214 commit e3ef7bb

9 files changed

+80
-11
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PHP NEWS
77

88
- Core:
99
. Fixed bug #81380 (Observer may not be initialized properly). (krakjoe)
10+
. Fixed bug GH-7771 (Fix filename/lineno of constant expressions). (ilutov)
1011

1112
- Intl:
1213
. Update all grandfathered language tags with preferred values

Zend/tests/bug41633_2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ echo Foo::A."\n";
1111
Fatal error: Uncaught Error: Undefined constant self::B in %s:%d
1212
Stack trace:
1313
#0 {main}
14-
thrown in %sbug41633_2.php on line 5
14+
thrown in %sbug41633_2.php on line 3

Zend/tests/gh7771_1.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-7771 (Incorrect file/line for class constant expression exceptions)
3+
--FILE--
4+
<?php
5+
6+
include __DIR__ . '/gh7771_1_definition.inc';
7+
8+
new Foo();
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_1_definition.inc:4
13+
Stack trace:
14+
#0 {main}
15+
thrown in %sgh7771_1_definition.inc on line 4

Zend/tests/gh7771_1_definition.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
class Foo {
4+
public const BAR = NonExistent::CLASS_CONSTANT;
5+
}

Zend/tests/gh7771_2.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-7771 (Incorrect file/line for class constant expression exceptions)
3+
--FILE--
4+
<?php
5+
6+
include __DIR__ . '/gh7771_2_definition.inc';
7+
8+
new Foo();
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Uncaught Error: Class "NonExistent" not found in %sgh7771_2_definition.inc:6
13+
Stack trace:
14+
#0 {main}
15+
thrown in %sgh7771_2_definition.inc on line 6

Zend/tests/gh7771_2_definition.inc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
class Foo {
4+
public const BAR =
5+
self::BAZ
6+
+ NonExistent::CLASS_CONSTANT;
7+
public const BAZ = 42;
8+
}

Zend/zend_ast.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,20 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast
789789
{
790790
zend_string *class_name = zend_ast_get_str(ast->child[0]);
791791
zend_string *const_name = zend_ast_get_str(ast->child[1]);
792+
793+
zend_string *previous_filename;
794+
zend_long previous_lineno;
795+
if (scope) {
796+
previous_filename = EG(filename_override);
797+
previous_lineno = EG(lineno_override);
798+
EG(filename_override) = scope->info.user.filename;
799+
EG(lineno_override) = zend_ast_get_lineno(ast);
800+
}
792801
zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr);
802+
if (scope) {
803+
EG(filename_override) = previous_filename;
804+
EG(lineno_override) = previous_lineno;
805+
}
793806

794807
if (UNEXPECTED(zv == NULL)) {
795808
ZVAL_UNDEF(result);
@@ -951,6 +964,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
951964
zend_ast *new = (zend_ast*)buf;
952965
new->kind = ast->kind;
953966
new->attr = ast->attr;
967+
new->lineno = ast->lineno;
954968
buf = (void*)((char*)buf + zend_ast_size(children));
955969
for (i = 0; i < children; i++) {
956970
if (ast->child[i]) {

Zend/zend_execute_API.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ void init_executor(void) /* {{{ */
192192
EG(num_errors) = 0;
193193
EG(errors) = NULL;
194194

195+
EG(filename_override) = NULL;
196+
EG(lineno_override) = -1;
197+
195198
zend_fiber_init();
196199
zend_weakrefs_init();
197200

@@ -462,6 +465,8 @@ void shutdown_executor(void) /* {{{ */
462465
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
463466
efree(EG(ht_iterators));
464467
}
468+
469+
ZEND_ASSERT(EG(filename_override) == NULL);
465470
}
466471

467472
#if ZEND_DEBUG
@@ -591,21 +596,18 @@ ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t a
591596

592597
ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
593598
{
594-
zend_execute_data *ex = EG(current_execute_data);
595-
596-
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
597-
ex = ex->prev_execute_data;
598-
}
599-
if (ex) {
600-
return ZSTR_VAL(ex->func->op_array.filename);
601-
} else {
602-
return "[no active file]";
603-
}
599+
zend_string *filename = zend_get_executed_filename_ex();
600+
return filename != NULL ? ZSTR_VAL(filename) : "[no active file]";
604601
}
605602
/* }}} */
606603

607604
ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
608605
{
606+
zend_string *filename_override = EG(filename_override);
607+
if (filename_override != NULL) {
608+
return filename_override;
609+
}
610+
609611
zend_execute_data *ex = EG(current_execute_data);
610612

611613
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
@@ -621,6 +623,11 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
621623

622624
ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
623625
{
626+
zend_long lineno_override = EG(lineno_override);
627+
if (lineno_override != -1) {
628+
return lineno_override;
629+
}
630+
624631
zend_execute_data *ex = EG(current_execute_data);
625632

626633
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {

Zend/zend_globals.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ struct _zend_executor_globals {
266266
uint32_t num_errors;
267267
zend_error_info **errors;
268268

269+
/* Override filename or line number of thrown errors and exceptions */
270+
zend_string *filename_override;
271+
zend_long lineno_override;
272+
269273
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
270274
};
271275

0 commit comments

Comments
 (0)