Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Zend/tests/anon/anon_class_name_in_abstract_info.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
--TEST--
Anonymous class name is not truncated in the abstract method list
--FILE--
<?php
new class { abstract public $p { get; } };
?>
--EXPECTF--
Fatal error: Class class@anonymous%0%s must implement 1 abstract method (class@anonymous%0%s::$p::get) in %s on line %d
60 changes: 60 additions & 0 deletions Zend/tests/anon/anon_class_name_in_errors.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
--TEST--
Anonymous class names are not truncated in runtime error messages
--FILE--
<?php

class A {
public private(set) int $p = 0;
private function f() {}
}

class B {
private function __destruct() {}
}

$o = new class {
public function __construct(public readonly int $ro = 1) {}
private function priv() {}
public function ret(): int { return "x"; }
public function args($a) {}
public function byRef(&$a) {}
public function callPriv() { (new A)->f(); }
public function setPrivateSet() { $a = new A; $a->p = 1; }
public function destroy() { new B; }
};

$v = new class extends ArrayObject {
public int $virtual { get => 1; }
};

foreach ([
fn() => $o->priv(),
fn() => $o->callPriv(),
fn() => $o->setPrivateSet(),
fn() => $o->destroy(),
fn() => $o->ro = 2,
fn() => $o->ret(),
fn() => $o->args(),
fn() => $v->__unserialize([0, [], ['virtual' => 2]]),
] as $fn) {
try {
$fn();
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
}

$o->byRef(...new ArrayIterator([1]));

?>
--EXPECTF--
Error: Call to private method class@anonymous%0%s::priv() from global scope
Error: Call to private method A::f() from scope class@anonymous%0%s
Error: Cannot modify private(set) property A::$p from scope class@anonymous%0%s
Error: Call to private B::__destruct() from scope class@anonymous%0%s
Error: Cannot modify readonly property class@anonymous%0%s::$ro
TypeError: class@anonymous%0%s::ret(): Return value must be of type int, string returned
ArgumentCountError: Too few arguments to function class@anonymous%0%s::args(), 0 passed in %s on line %d and exactly 1 expected
Error: Cannot unserialize value for virtual property ArrayObject@anonymous%0%s::$virtual

Warning: Cannot pass by-reference argument 1 of class@anonymous%0%s::byRef() by unpacking a Traversable, passing by-value instead in %s on line %d
9 changes: 9 additions & 0 deletions Zend/tests/anon/anon_class_name_in_inheritance_error.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
--TEST--
Anonymous class name is not truncated in method inheritance errors
--FILE--
<?php
class A { public function f() {} }
new class extends A { private function f() {} };
?>
--EXPECTF--
Fatal error: Access level to A@anonymous%0%s::f() must be public (as in class A) in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/attributes/override/020.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ echo "Done";

?>
--EXPECTF--
Fatal error: I@anonymous::c() has #[\Override] attribute, but no matching parent method exists in %s on line %d
Fatal error: I@anonymous%0%s::c() has #[\Override] attribute, but no matching parent method exists in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/object_types/return_type_in_class.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $three = new class extends Two {
$three->a();
?>
--EXPECTF--
Fatal error: Uncaught TypeError: Two@anonymous::a(): Return value must be of type object, int returned in %s:%d
Fatal error: Uncaught TypeError: Two@anonymous%0%s::a(): Return value must be of type object, int returned in %s:%d
Stack trace:
#0 %s(%d): Two@anonymous->a()
#1 {main}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $three = new class extends Two {
$three->a();
?>
--EXPECTF--
Fatal error: Uncaught TypeError: Two@anonymous::a(): Return value must be of type object, int returned in %s:%d
Fatal error: Uncaught TypeError: Two@anonymous%0%s::a(): Return value must be of type object, int returned in %s:%d
Stack trace:
#0 %s(%d): Two@anonymous->a()
#1 {main}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $three = new class implements Two {
$three->a();
?>
--EXPECTF--
Fatal error: Uncaught TypeError: Two@anonymous::a(): Return value must be of type object, int returned in %s:%d
Fatal error: Uncaught TypeError: Two@anonymous%0%s::a(): Return value must be of type object, int returned in %s:%d
Stack trace:
#0 %s(%d): Two@anonymous->a()
#1 {main}
Expand Down
4 changes: 2 additions & 2 deletions Zend/tests/readonly_classes/gh10377.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ try {
var_dump($anon->field);

?>
--EXPECT--
--EXPECTF--
int(2)
Error: Cannot modify readonly property class@anonymous::$field
Error: Cannot modify readonly property class@anonymous%0%s::$field
int(2)
int(2)
int(123)
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ try {
?>
--EXPECTF--
TypeError: class@anonymous%0%s::testParam(): Argument #1 ($a) must be of type class@anonymous|string, null given, called in %s on line %d
TypeError: class@anonymous::test(): Return value must be of type class@anonymous|string, stdClass returned
TypeError: class@anonymous%0%s::test(): Return value must be of type class@anonymous|string, stdClass returned
2 changes: 1 addition & 1 deletion Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -1786,7 +1786,7 @@ ZEND_API void object_properties_load(zend_object *object, const HashTable *prope

/* Mimick unserialize behaviour for virtual properties. */
if (UNEXPECTED(property_info->flags & ZEND_ACC_VIRTUAL)) {
zend_throw_error(NULL, "Cannot unserialize value for virtual property %s::$%s", ZSTR_VAL(object->ce->name), zend_get_unmangled_property_name(property_info->name));
zend_throw_error(NULL, "Cannot unserialize value for virtual property %pS::$%s", object->ce->name, zend_get_unmangled_property_name(property_info->name));
return;
}

Expand Down
65 changes: 22 additions & 43 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,18 +707,8 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_erro

static zend_never_inline ZEND_COLD void zend_verify_type_error_common(
const zend_function *zf, const zend_arg_info *arg_info, const zval *value,
const char **fname, const char **fsep, const char **fclass,
zend_string **need_msg, const char **given_kind)
{
*fname = ZSTR_VAL(zf->common.function_name);
if (zf->common.scope) {
*fsep = "::";
*fclass = ZSTR_VAL(zf->common.scope->name);
} else {
*fsep = "";
*fclass = "";
}

*need_msg = zend_type_to_string_resolved(arg_info->type, zf->common.scope);

if (value) {
Expand All @@ -732,12 +722,10 @@ ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error(
const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value)
{
const zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
const char *fname, *fsep, *fclass;
zend_string *need_msg;
const char *given_msg;

zend_verify_type_error_common(
zf, arg_info, value, &fname, &fsep, &fclass, &need_msg, &given_msg);
zend_verify_type_error_common(zf, arg_info, value, &need_msg, &given_msg);

ZEND_ASSERT(zf->common.type == ZEND_USER_FUNCTION
&& "Arginfo verification is not performed for internal functions");
Expand Down Expand Up @@ -930,8 +918,8 @@ zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value)

ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(
const zend_property_info *info) {
zend_readonly_property_modification_error_ex(
ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name));
zend_throw_error(NULL, "Cannot modify readonly property %pS::$%s",
info->ce->name, zend_get_unmangled_property_name(info->name));
}

ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(
Expand Down Expand Up @@ -978,12 +966,12 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibili
}
}

zend_throw_error(NULL, "Cannot %s %s property %pS::$%pS from %s%s",
zend_throw_error(NULL, "Cannot %s %s property %pS::$%pS from %s%pS",
operation,
visibility,
prop_info->ce->name,
prop_info->name,
scope ? "scope " : "global scope", scope ? ZSTR_VAL(scope->name) : "");
scope ? "scope " : "global scope", scope ? scope->name : ZSTR_EMPTY_ALLOC());
}

static const zend_class_entry *resolve_single_class_type(zend_string *name, const zend_class_entry *self_ce) {
Expand Down Expand Up @@ -1431,8 +1419,8 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(c
const zend_execute_data *ptr = EX(prev_execute_data);

if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%pS(), %d passed in %pS on line %d and %s %d expected",
EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "",
zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %pS%s%pS(), %d passed in %pS on line %d and %s %d expected",
EX(func)->common.scope ? EX(func)->common.scope->name : ZSTR_EMPTY_ALLOC(),
EX(func)->common.scope ? "::" : "",
EX(func)->common.function_name,
EX_NUM_ARGS(),
Expand All @@ -1441,8 +1429,8 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(c
EX(func)->common.required_num_args == EX(func)->common.num_args ? "exactly" : "at least",
EX(func)->common.required_num_args);
} else {
zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%pS(), %d passed and %s %d expected",
EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "",
zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %pS%s%pS(), %d passed and %s %d expected",
EX(func)->common.scope ? EX(func)->common.scope->name : ZSTR_EMPTY_ALLOC(),
EX(func)->common.scope ? "::" : "",
EX(func)->common.function_name,
EX_NUM_ARGS(),
Expand All @@ -1454,17 +1442,17 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(c
ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value)
{
const zend_arg_info *arg_info = &zf->common.arg_info[-1];
const char *fname, *fsep, *fclass;
zend_string *func_name = get_function_or_method_name(zf);
zend_string *need_msg;
const char *given_msg;

zend_verify_type_error_common(
zf, arg_info, value, &fname, &fsep, &fclass, &need_msg, &given_msg);
zend_verify_type_error_common(zf, arg_info, value, &need_msg, &given_msg);

zend_type_error("%s%s%s(): Return value must be of type %pS, %s returned",
fclass, fsep, fname, need_msg, given_msg);
zend_type_error("%pS(): Return value must be of type %pS, %s returned",
func_name, need_msg, given_msg);

zend_string_release(need_msg);
zend_string_release(func_name);
}

ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error(const zend_function *zf)
Expand All @@ -1481,33 +1469,24 @@ ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error(const zend_fun
static zend_never_inline ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value)
{
const zend_arg_info *arg_info = &zf->common.arg_info[-1];
const char *fname, *fsep, *fclass;
zend_string *func_name = get_function_or_method_name(zf);
zend_string *need_msg;
const char *given_msg;

zend_verify_type_error_common(
zf, arg_info, value, &fname, &fsep, &fclass, &need_msg, &given_msg);
zend_verify_type_error_common(zf, arg_info, value, &need_msg, &given_msg);

zend_error_noreturn(E_CORE_ERROR, "%s%s%s(): Return value must be of type %pS, %s returned",
fclass, fsep, fname, need_msg, given_msg);
zend_error_noreturn(E_CORE_ERROR, "%pS(): Return value must be of type %pS, %s returned",
func_name, need_msg, given_msg);
}

static zend_never_inline ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind)
{
const char *fname = ZSTR_VAL(zf->common.function_name);
const char *fsep;
const char *fclass;
zend_string *func_name = get_function_or_method_name(zf);

if (zf->common.scope) {
fsep = "::";
fclass = ZSTR_VAL(zf->common.scope->name);
} else {
fsep = "";
fclass = "";
}
zend_type_error("%pS() must not return a value, %s%s returned",
func_name, returned_msg, returned_kind);

zend_type_error("%s%s%s() must not return a value, %s%s returned",
fclass, fsep, fname, returned_msg, returned_kind);
zend_string_release(func_name);
}

ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret)
Expand Down
32 changes: 16 additions & 16 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -1153,8 +1153,8 @@ static inheritance_status do_inheritance_check_on_method(
return INHERITANCE_ERROR;
}
zend_error_at_noreturn(E_COMPILE_ERROR, func_filename(child), func_lineno(child),
"Cannot override final method %s::%pS()",
ZEND_FN_SCOPE_NAME(parent), child->common.function_name);
"Cannot override final method %pS::%pS()",
parent->common.scope->name, child->common.function_name);
}

child_flags = child->common.fn_flags;
Expand All @@ -1167,12 +1167,12 @@ static inheritance_status do_inheritance_check_on_method(
}
if (child_flags & ZEND_ACC_STATIC) {
zend_error_at_noreturn(E_COMPILE_ERROR, func_filename(child), func_lineno(child),
"Cannot make non static method %s::%pS() static in class %s",
ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
"Cannot make non static method %pS::%pS() static in class %pS",
parent->common.scope->name, child->common.function_name, child->common.scope->name);
} else {
zend_error_at_noreturn(E_COMPILE_ERROR, func_filename(child), func_lineno(child),
"Cannot make static method %s::%pS() non static in class %s",
ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
"Cannot make static method %pS::%pS() non static in class %pS",
parent->common.scope->name, child->common.function_name, child->common.scope->name);
}
}

Expand All @@ -1183,8 +1183,8 @@ static inheritance_status do_inheritance_check_on_method(
return INHERITANCE_ERROR;
}
zend_error_at_noreturn(E_COMPILE_ERROR, func_filename(child), func_lineno(child),
"Cannot make non abstract method %s::%pS() abstract in class %s",
ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
"Cannot make non abstract method %pS::%pS() abstract in class %pS",
parent->common.scope->name, child->common.function_name, child->common.scope->name);
}

if ((flags & ZEND_INHERITANCE_SET_CHILD_CHANGED)
Expand Down Expand Up @@ -1218,8 +1218,8 @@ static inheritance_status do_inheritance_check_on_method(
return INHERITANCE_ERROR;
}
zend_error_at_noreturn(E_COMPILE_ERROR, func_filename(child), func_lineno(child),
"Access level to %s::%pS() must be %s (as in class %s)%s",
ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
"Access level to %pS::%pS() must be %s (as in class %pS)%s",
child->common.scope->name, child->common.function_name, zend_visibility_string(parent_flags), parent->common.scope->name, (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
}

if (flags & ZEND_INHERITANCE_CHECK_PROTO) {
Expand Down Expand Up @@ -2318,8 +2318,8 @@ void zend_inheritance_check_override(const zend_class_entry *ce)

zend_error_at_noreturn(
E_COMPILE_ERROR, f->op_array.filename, f->op_array.line_start,
"%s::%pS() has #[\\Override] attribute, but no matching parent method exists",
ZEND_FN_SCOPE_NAME(f), f->common.function_name);
"%pS::%pS() has #[\\Override] attribute, but no matching parent method exists",
f->common.scope->name, f->common.function_name);
}
} ZEND_HASH_FOREACH_END();

Expand Down Expand Up @@ -2348,8 +2348,8 @@ void zend_inheritance_check_override(const zend_class_entry *ce)

zend_error_at_noreturn(
E_COMPILE_ERROR, f->op_array.filename, f->op_array.line_start,
"%s::%pS() has #[\\Override] attribute, but no matching parent method exists",
ZEND_FN_SCOPE_NAME(f), f->common.function_name);
"%pS::%pS() has #[\\Override] attribute, but no matching parent method exists",
f->common.scope->name, f->common.function_name);
}
}
}
Expand Down Expand Up @@ -3064,9 +3064,9 @@ ZEND_API void zend_class_use_internal_traits(zend_class_entry *class_entry, int
}

#define MAX_ABSTRACT_INFO_CNT 3
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
#define MAX_ABSTRACT_INFO_FMT "%pS%s%s%s"
#define DISPLAY_ABSTRACT_FN(idx) \
ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
ai.afn[idx] ? ai.afn[idx]->common.scope->name : ZSTR_EMPTY_ALLOC(), \
ai.afn[idx] ? "::" : "", \
ai.afn[idx] ? ZSTR_VAL(ai.afn[idx]->common.function_name) : "", \
ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1959,10 +1959,10 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(

ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(const zend_function *fbc, const zend_string *method_name, const zend_class_entry *scope) /* {{{ */
{
zend_throw_error(NULL, "Call to %s method %s::%pS() from %s%s",
zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name,
zend_throw_error(NULL, "Call to %s method %pS::%pS() from %s%pS",
zend_visibility_string(fbc->common.fn_flags), fbc->common.scope->name, method_name,
scope ? "scope " : "global scope",
scope ? ZSTR_VAL(scope->name) : ""
scope ? scope->name : ZSTR_EMPTY_ALLOC()
);
}
/* }}} */
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
ZEND_ASSERT(!(destructor->common.fn_flags & ZEND_ACC_PUBLIC));
if (!zend_check_method_accessible(destructor, scope)) {
zend_throw_error(NULL,
"Call to %s %pS::__destruct() from %s%s",
"Call to %s %pS::__destruct() from %s%pS",
zend_visibility_string(destructor->common.fn_flags), object->ce->name,
scope ? "scope " : "global scope",
scope ? ZSTR_VAL(scope->name) : ""
scope ? scope->name : ZSTR_EMPTY_ALLOC()
);
return;
}
Expand Down
Loading
Loading