Skip to content

Commit 82ab84a

Browse files
committed
Adjust filename/lineno for constant expressions
Closes GH-7771
1 parent 706398f commit 82ab84a

File tree

6 files changed

+42
-0
lines changed

6 files changed

+42
-0
lines changed

Zend/tests/gh7771.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_definition.inc';
7+
8+
new Foo();
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Uncaught Error: Class "NonExistent" not found in %s/Zend/tests/gh7771_definition.inc:4
13+
Stack trace:
14+
#0 {main}
15+
thrown in %s/Zend/tests/gh7771_definition.inc on line 4

Zend/tests/gh7771_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/zend_ast.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,12 @@ 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+
EG(exception_filename) = scope->info.user.filename;
794+
EG(exception_lineno) = zend_ast_get_lineno(ast);
792795
zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr);
796+
EG(exception_filename) = NULL;
797+
EG(exception_lineno) = -1;
793798

794799
if (UNEXPECTED(zv == NULL)) {
795800
ZVAL_UNDEF(result);

Zend/zend_exceptions.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,14 @@ static zend_object *zend_throw_exception_zstr(zend_class_entry *exception_ce, ze
821821
ZVAL_LONG(&tmp, code);
822822
zend_update_property_ex(exception_ce, Z_OBJ(ex), ZSTR_KNOWN(ZEND_STR_CODE), &tmp);
823823
}
824+
if (EG(exception_filename) != NULL) {
825+
ZVAL_STR(&tmp, EG(exception_filename));
826+
zend_update_property_ex(exception_ce, Z_OBJ(ex), ZSTR_KNOWN(ZEND_STR_FILE), &tmp);
827+
}
828+
if (EG(exception_lineno) != -1) {
829+
ZVAL_LONG(&tmp, EG(exception_lineno));
830+
zend_update_property_ex(exception_ce, Z_OBJ(ex), ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
831+
}
824832

825833
zend_throw_exception_internal(Z_OBJ(ex));
826834

Zend/zend_execute_API.c

Lines changed: 5 additions & 0 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(exception_filename) = NULL;
196+
EG(exception_lineno) = -1;
197+
195198
zend_fiber_init();
196199
zend_weakrefs_init();
197200

@@ -450,6 +453,8 @@ void shutdown_executor(void) /* {{{ */
450453
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
451454
efree(EG(ht_iterators));
452455
}
456+
457+
ZEND_ASSERT(EG(exception_filename) == NULL);
453458
}
454459

455460
#if ZEND_DEBUG

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+
/* Overwrite filename or line number of thrown exceptions */
270+
zend_string *exception_filename;
271+
zend_long exception_lineno;
272+
269273
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
270274
};
271275

0 commit comments

Comments
 (0)