mirror of
https://github.com/php/php-src.git
synced 2024-12-11 19:04:38 +08:00
- Fix #38465 (ReflectionParameter fails if default value is an access to self::
This commit is contained in:
parent
1b8cf37abd
commit
0e58baae93
@ -585,7 +585,7 @@ ZEND_FUNCTION(defined)
|
||||
}
|
||||
|
||||
convert_to_text_ex(var);
|
||||
if (zend_u_get_constant(Z_TYPE_PP(var), Z_UNIVAL_PP(var), Z_UNILEN_PP(var), &c TSRMLS_CC)) {
|
||||
if (zend_u_get_constant(Z_TYPE_PP(var), Z_UNIVAL_PP(var), Z_UNILEN_PP(var), &c, NULL TSRMLS_CC)) {
|
||||
zval_dtor(&c);
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
|
@ -231,7 +231,7 @@ ZEND_API void zend_register_string_constant(char *name, uint name_len, char *str
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result TSRMLS_DC)
|
||||
ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC)
|
||||
{
|
||||
zend_constant *c;
|
||||
int retval = 1;
|
||||
@ -241,7 +241,7 @@ ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval
|
||||
if ((UG(unicode) && (colon.u = u_memchr(name.u, ':', name_len)) && colon.u[1] == ':') ||
|
||||
(!UG(unicode) && (colon.s = memchr(name.s, ':', name_len)) && colon.s[1] == ':')) {
|
||||
/* class constant */
|
||||
zend_class_entry **ce = NULL, *scope;
|
||||
zend_class_entry **ce = NULL;
|
||||
int class_name_len = UG(unicode)?colon.u-name.u:colon.s-name.s;
|
||||
int const_name_len = name_len - class_name_len - 2;
|
||||
zstr constant_name, class_name;
|
||||
@ -253,11 +253,13 @@ ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval
|
||||
constant_name.s = colon.s + 2;
|
||||
}
|
||||
|
||||
if (!scope) {
|
||||
if (EG(in_execution)) {
|
||||
scope = EG(scope);
|
||||
} else {
|
||||
scope = CG(active_class_entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (UG(unicode)) {
|
||||
class_name.u = eustrndup(name.u, class_name_len);
|
||||
@ -333,7 +335,7 @@ ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval
|
||||
|
||||
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC)
|
||||
{
|
||||
return zend_u_get_constant(IS_STRING, ZSTR(name), name_len, result TSRMLS_CC);
|
||||
return zend_u_get_constant(IS_STRING, ZSTR(name), name_len, result, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API int zend_u_register_constant(zend_uchar type, zend_constant *c TSRMLS_DC)
|
||||
|
@ -56,7 +56,7 @@ int zend_shutdown_constants(TSRMLS_D);
|
||||
void zend_register_standard_constants(TSRMLS_D);
|
||||
void clean_non_persistent_constants(TSRMLS_D);
|
||||
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC);
|
||||
ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result TSRMLS_DC);
|
||||
ZEND_API int zend_u_get_constant(zend_uchar type, zstr name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC);
|
||||
|
@ -143,6 +143,7 @@ static inline int i_zend_is_true(zval *op)
|
||||
}
|
||||
|
||||
ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC);
|
||||
|
||||
/* dedicated Zend executor functions - do not use! */
|
||||
static inline void zend_ptr_stack_clear_multiple(TSRMLS_D)
|
||||
|
@ -469,7 +469,7 @@ ZEND_API int zend_is_true(zval *op)
|
||||
|
||||
#include "../TSRM/tsrm_strtok_r.h"
|
||||
|
||||
ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC)
|
||||
{
|
||||
zval *p = *pp;
|
||||
zend_bool inline_change = (zend_bool) (unsigned long) arg;
|
||||
@ -485,7 +485,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
refcount = p->refcount;
|
||||
is_ref = p->is_ref;
|
||||
|
||||
if (!zend_u_get_constant(UG(unicode)?IS_UNICODE:IS_STRING, Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value TSRMLS_CC)) {
|
||||
if (!zend_u_get_constant(ZEND_STR_TYPE, Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value, scope TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'",
|
||||
Z_UNIVAL_P(p),
|
||||
Z_UNIVAL_P(p));
|
||||
@ -524,7 +524,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
}
|
||||
if (!zend_u_get_constant(UG(unicode)?IS_UNICODE:IS_STRING, str_index, str_index_len-1, &const_value TSRMLS_CC)) {
|
||||
if (!zend_u_get_constant(ZEND_STR_TYPE, str_index, str_index_len-1, &const_value, scope TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'", str_index, str_index);
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
@ -586,6 +586,10 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
{
|
||||
zval_update_constant_ex(pp, arg, NULL TSRMLS_CC);
|
||||
}
|
||||
|
||||
int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC)
|
||||
{
|
||||
|
@ -2617,7 +2617,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, CONST|UNUSED, CONST)
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
|
||||
if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'",
|
||||
Z_TYPE(opline->op2.u.constant),
|
||||
Z_UNIVAL(opline->op2.u.constant),
|
||||
|
@ -2670,7 +2670,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
|
||||
if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'",
|
||||
Z_TYPE(opline->op2.u.constant),
|
||||
Z_UNIVAL(opline->op2.u.constant),
|
||||
@ -15807,7 +15807,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
|
||||
if (!zend_u_get_constant(Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'",
|
||||
Z_TYPE(opline->op2.u.constant),
|
||||
Z_UNIVAL(opline->op2.u.constant),
|
||||
|
@ -2144,7 +2144,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
|
||||
|
||||
zv_copy = precv->op2.u.constant;
|
||||
zv = &zv_copy;
|
||||
zval_update_constant(&zv, (void*)0 TSRMLS_CC);
|
||||
zval_update_constant_ex(&zv, (void*)0, param->fptr->common.scope TSRMLS_CC);
|
||||
RETURN_ZVAL(zv, 1, 1);
|
||||
}
|
||||
/* }}} */
|
||||
@ -3961,7 +3961,7 @@ ZEND_METHOD(reflection_property, getDefaultValue)
|
||||
*zv = **zdef;
|
||||
zval_copy_ctor(zv);
|
||||
INIT_PZVAL(zv);
|
||||
zval_update_constant(&zv, (void*)1 TSRMLS_CC);
|
||||
zval_update_constant_ex(&zv, (void*)1, ref->ce TSRMLS_CC);
|
||||
RETURN_ZVAL(zv, 1, 1);
|
||||
}
|
||||
}
|
||||
|
86
ext/reflection/tests/bug38465.phpt
Normal file
86
ext/reflection/tests/bug38465.phpt
Normal file
@ -0,0 +1,86 @@
|
||||
--TEST--
|
||||
Reflection Bug #38465 (ReflectionParameter fails on access to self::)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class Baz {
|
||||
const B = 3;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
const X = 1;
|
||||
private $propA = self::X;
|
||||
private $propB = Baz::B;
|
||||
private $propC = 99;
|
||||
public function x($a = self::X, $b = Baz::B, $c = 99) {}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
const Y = 2;
|
||||
private $propA = self::X;
|
||||
private $propB = Baz::B;
|
||||
private $propC = 99;
|
||||
public function y($a = self::Y, $b = Baz::B, $c = 99) {}
|
||||
}
|
||||
|
||||
|
||||
echo "From global scope:\n";
|
||||
|
||||
$clazz = new ReflectionClass('Bar');
|
||||
foreach ($clazz->getProperties() as $property) {
|
||||
echo $property->getDeclaringClass()->getName(), '::$', $property->getName(), ' = ', $property->getDefaultValue(), "\n";
|
||||
}
|
||||
|
||||
foreach ($clazz->getMethods() as $method) {
|
||||
foreach ($method->getParameters() as $param) {
|
||||
if ($param->isDefaultValueAvailable()) {
|
||||
echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\nFrom class context:\n";
|
||||
|
||||
class Test {
|
||||
function __construct() {
|
||||
$clazz = new ReflectionClass('Bar');
|
||||
foreach ($clazz->getProperties() as $property) {
|
||||
echo $property->getDeclaringClass()->getName(), '::$', $property->getName(), ' = ', $property->getDefaultValue(), "\n";
|
||||
}
|
||||
|
||||
foreach ($clazz->getMethods() as $method) {
|
||||
foreach ($method->getParameters() as $param) {
|
||||
if ($param->isDefaultValueAvailable()) {
|
||||
echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new Test();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
From global scope:
|
||||
Bar::$propA = 1
|
||||
Bar::$propB = 3
|
||||
Bar::$propC = 99
|
||||
Bar::y($a = 2)
|
||||
Bar::y($b = 3)
|
||||
Bar::y($c = 99)
|
||||
Foo::x($a = 1)
|
||||
Foo::x($b = 3)
|
||||
Foo::x($c = 99)
|
||||
|
||||
From class context:
|
||||
Bar::$propA = 1
|
||||
Bar::$propB = 3
|
||||
Bar::$propC = 99
|
||||
Bar::y($a = 2)
|
||||
Bar::y($b = 3)
|
||||
Bar::y($c = 99)
|
||||
Foo::x($a = 1)
|
||||
Foo::x($b = 3)
|
||||
Foo::x($c = 99)
|
@ -4216,7 +4216,7 @@ PHP_FUNCTION(constant)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!zend_u_get_constant(const_type, const_name, const_name_len, return_value TSRMLS_CC)) {
|
||||
if (!zend_u_get_constant(const_type, const_name, const_name_len, return_value, NULL TSRMLS_CC)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find constant %R", const_type, const_name);
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user