mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +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:
|
- Core:
|
||||||
. Fixed bug #81380 (Observer may not be initialized properly). (krakjoe)
|
. Fixed bug #81380 (Observer may not be initialized properly). (krakjoe)
|
||||||
|
. Fixed bug GH-7771 (Fix filename/lineno of constant expressions). (ilutov)
|
||||||
|
|
||||||
- Intl:
|
- Intl:
|
||||||
. Update all grandfathered language tags with preferred values
|
. 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
|
Fatal error: Uncaught Error: Undefined constant self::B in %s:%d
|
||||||
Stack trace:
|
Stack trace:
|
||||||
#0 {main}
|
#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 *class_name = zend_ast_get_str(ast->child[0]);
|
||||||
zend_string *const_name = zend_ast_get_str(ast->child[1]);
|
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);
|
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)) {
|
if (UNEXPECTED(zv == NULL)) {
|
||||||
ZVAL_UNDEF(result);
|
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;
|
zend_ast *new = (zend_ast*)buf;
|
||||||
new->kind = ast->kind;
|
new->kind = ast->kind;
|
||||||
new->attr = ast->attr;
|
new->attr = ast->attr;
|
||||||
|
new->lineno = ast->lineno;
|
||||||
buf = (void*)((char*)buf + zend_ast_size(children));
|
buf = (void*)((char*)buf + zend_ast_size(children));
|
||||||
for (i = 0; i < children; i++) {
|
for (i = 0; i < children; i++) {
|
||||||
if (ast->child[i]) {
|
if (ast->child[i]) {
|
||||||
|
@ -192,6 +192,9 @@ void init_executor(void) /* {{{ */
|
|||||||
EG(num_errors) = 0;
|
EG(num_errors) = 0;
|
||||||
EG(errors) = NULL;
|
EG(errors) = NULL;
|
||||||
|
|
||||||
|
EG(filename_override) = NULL;
|
||||||
|
EG(lineno_override) = -1;
|
||||||
|
|
||||||
zend_fiber_init();
|
zend_fiber_init();
|
||||||
zend_weakrefs_init();
|
zend_weakrefs_init();
|
||||||
|
|
||||||
@ -462,6 +465,8 @@ void shutdown_executor(void) /* {{{ */
|
|||||||
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
|
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
|
||||||
efree(EG(ht_iterators));
|
efree(EG(ht_iterators));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZEND_ASSERT(EG(filename_override) == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ZEND_DEBUG
|
#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_API const char *zend_get_executed_filename(void) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_execute_data *ex = EG(current_execute_data);
|
zend_string *filename = zend_get_executed_filename_ex();
|
||||||
|
return filename != NULL ? ZSTR_VAL(filename) : "[no active file]";
|
||||||
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_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
|
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);
|
zend_execute_data *ex = EG(current_execute_data);
|
||||||
|
|
||||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
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_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);
|
zend_execute_data *ex = EG(current_execute_data);
|
||||||
|
|
||||||
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
||||||
|
@ -266,6 +266,10 @@ struct _zend_executor_globals {
|
|||||||
uint32_t num_errors;
|
uint32_t num_errors;
|
||||||
zend_error_info **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];
|
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user