diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | Zend/zend_reflection_api.c | 30 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 30 | ||||
-rwxr-xr-x | ext/reflection/tests/bug33312.phpt | 20 |
4 files changed, 72 insertions, 12 deletions
@@ -1,5 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +?? ??? 2005, PHP 5.1 +- Fixed bug #33312 (ReflectionParameter methods do not work correctly). + (Dmitry) + 11 Jun 2005, PHP 5.1 Beta 2 - Fixed PDO shutdown problem (possible inifite loop running rollback on shutdown). (Wez) diff --git a/Zend/zend_reflection_api.c b/Zend/zend_reflection_api.c index 450081b24e..e1f61687f9 100644 --- a/Zend/zend_reflection_api.c +++ b/Zend/zend_reflection_api.c @@ -508,6 +508,24 @@ static void _const_string(string *str, char *name, zval *value, char *indent TSR } /* }}} */ +/* {{{ _get_recv_opcode */ +static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset) +{ + zend_op *op = op_array->opcodes; + zend_op *end = op + op_array->last; + + ++offset; + while (op < end) { + if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) && + op->op1.u.constant.value.lval == offset) { + return op; + } + ++op; + } + return NULL; +} +/* }}} */ + /* {{{ _parameter_string */ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, char* indent TSRMLS_DC) { @@ -537,8 +555,8 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg string_printf(str, "$param%d", offset); } if (fptr->type == ZEND_USER_FUNCTION && offset >= required) { - zend_op *precv = &((zend_op_array*)fptr)->opcodes[offset*2 + 1]; - if (precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) { + zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset); + if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) { zval *zv, zv_copy; int use_copy; string_write(str, " = ", sizeof(" = ")-1); @@ -1798,8 +1816,8 @@ ZEND_METHOD(reflection_parameter, isDefaultValueAvailable) if (param->offset < param->required) { RETURN_FALSE; } - precv = &((zend_op_array*)param->fptr)->opcodes[param->offset*2 + 1]; - if (precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { + precv = _get_recv_op((zend_op_array*)param->fptr, param->offset); + if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { RETURN_FALSE; } RETURN_TRUE; @@ -1827,8 +1845,8 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional"); return; } - precv = &((zend_op_array*)param->fptr)->opcodes[param->offset*2 + 1]; - if (precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { + precv = _get_recv_op((zend_op_array*)param->fptr, param->offset); + if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error"); return; } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 450081b24e..e1f61687f9 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -508,6 +508,24 @@ static void _const_string(string *str, char *name, zval *value, char *indent TSR } /* }}} */ +/* {{{ _get_recv_opcode */ +static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset) +{ + zend_op *op = op_array->opcodes; + zend_op *end = op + op_array->last; + + ++offset; + while (op < end) { + if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) && + op->op1.u.constant.value.lval == offset) { + return op; + } + ++op; + } + return NULL; +} +/* }}} */ + /* {{{ _parameter_string */ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, char* indent TSRMLS_DC) { @@ -537,8 +555,8 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg string_printf(str, "$param%d", offset); } if (fptr->type == ZEND_USER_FUNCTION && offset >= required) { - zend_op *precv = &((zend_op_array*)fptr)->opcodes[offset*2 + 1]; - if (precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) { + zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset); + if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) { zval *zv, zv_copy; int use_copy; string_write(str, " = ", sizeof(" = ")-1); @@ -1798,8 +1816,8 @@ ZEND_METHOD(reflection_parameter, isDefaultValueAvailable) if (param->offset < param->required) { RETURN_FALSE; } - precv = &((zend_op_array*)param->fptr)->opcodes[param->offset*2 + 1]; - if (precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { + precv = _get_recv_op((zend_op_array*)param->fptr, param->offset); + if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { RETURN_FALSE; } RETURN_TRUE; @@ -1827,8 +1845,8 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional"); return; } - precv = &((zend_op_array*)param->fptr)->opcodes[param->offset*2 + 1]; - if (precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { + precv = _get_recv_op((zend_op_array*)param->fptr, param->offset); + if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error"); return; } diff --git a/ext/reflection/tests/bug33312.phpt b/ext/reflection/tests/bug33312.phpt new file mode 100755 index 0000000000..0c38304094 --- /dev/null +++ b/ext/reflection/tests/bug33312.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #33312 (ReflectionParameter methods do not work correctly) +--FILE-- +<?php +class Foo { + public function bar(Foo $foo, $bar = 'bar') { + } +} + +$class = new ReflectionClass('Foo'); +$method = $class->getMethod('bar'); + +foreach ($method->getParameters() as $parameter) { + if ($parameter->isDefaultValueAvailable()) { + print $parameter->getDefaultValue()."\n"; + } +} +?> +--EXPECT-- +bar |