mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
Fixed bug #74949 (null pointer dereference in _function_string)
This commit is contained in:
parent
c7aa8ba0ee
commit
e36c04ef48
3
NEWS
3
NEWS
@ -28,6 +28,9 @@ PHP NEWS
|
|||||||
. Fixed bug #74991 (include_path has a 4096 char limit in some cases).
|
. Fixed bug #74991 (include_path has a 4096 char limit in some cases).
|
||||||
(bwbroersma)
|
(bwbroersma)
|
||||||
|
|
||||||
|
- Reflection:
|
||||||
|
. Fixed bug #74949 (null pointer dereference in _function_string). (Laruence)
|
||||||
|
|
||||||
- Session:
|
- Session:
|
||||||
. Fixed bug #74833 (SID constant created with wrong module number). (Anatol)
|
. Fixed bug #74833 (SID constant created with wrong module number). (Anatol)
|
||||||
|
|
||||||
|
@ -291,6 +291,15 @@ static zend_function *_copy_function(zend_function *fptr) /* {{{ */
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static void _fix_closure_prototype(zend_function *fptr) /* {{{ */
|
||||||
|
{
|
||||||
|
/* Actually we are setting proxy function's prototype to null
|
||||||
|
* as for it, the prototype is an object not a function
|
||||||
|
* which could cause serias problems, see #74949 */
|
||||||
|
fptr->common.prototype = NULL;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
static void _free_function(zend_function *fptr) /* {{{ */
|
static void _free_function(zend_function *fptr) /* {{{ */
|
||||||
{
|
{
|
||||||
if (fptr
|
if (fptr
|
||||||
@ -598,6 +607,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
|
|||||||
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
||||||
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
|
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
|
||||||
{
|
{
|
||||||
|
_fix_closure_prototype(closure);
|
||||||
mptr = closure;
|
mptr = closure;
|
||||||
} else {
|
} else {
|
||||||
closure = NULL;
|
closure = NULL;
|
||||||
@ -2322,7 +2332,6 @@ ZEND_METHOD(reflection_generator, getExecutingGenerator)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
|
/* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
|
||||||
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
|
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
|
||||||
ZEND_METHOD(reflection_parameter, export)
|
ZEND_METHOD(reflection_parameter, export)
|
||||||
@ -2407,6 +2416,7 @@ ZEND_METHOD(reflection_parameter, __construct)
|
|||||||
{
|
{
|
||||||
/* nothing to do. don't set is_closure since is the invoke handler,
|
/* nothing to do. don't set is_closure since is the invoke handler,
|
||||||
not the closure itself */
|
not the closure itself */
|
||||||
|
_fix_closure_prototype(fptr);
|
||||||
} else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) {
|
} else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) {
|
||||||
efree(lcname);
|
efree(lcname);
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
||||||
@ -3092,6 +3102,7 @@ ZEND_METHOD(reflection_method, __construct)
|
|||||||
&& (mptr = zend_get_closure_invoke_method(Z_OBJ_P(orig_obj))) != NULL)
|
&& (mptr = zend_get_closure_invoke_method(Z_OBJ_P(orig_obj))) != NULL)
|
||||||
{
|
{
|
||||||
/* do nothing, mptr already set */
|
/* do nothing, mptr already set */
|
||||||
|
_fix_closure_prototype(mptr);
|
||||||
} else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, name_len)) == NULL) {
|
} else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, name_len)) == NULL) {
|
||||||
efree(lcname);
|
efree(lcname);
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
||||||
@ -4096,6 +4107,7 @@ ZEND_METHOD(reflection_class, getMethod)
|
|||||||
{
|
{
|
||||||
/* don't assign closure_object since we only reflect the invoke handler
|
/* don't assign closure_object since we only reflect the invoke handler
|
||||||
method and not the closure definition itself */
|
method and not the closure definition itself */
|
||||||
|
_fix_closure_prototype(mptr);
|
||||||
reflection_method_factory(ce, mptr, NULL, return_value);
|
reflection_method_factory(ce, mptr, NULL, return_value);
|
||||||
efree(lc_name);
|
efree(lc_name);
|
||||||
} else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
|
} else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
|
||||||
@ -4103,6 +4115,7 @@ ZEND_METHOD(reflection_class, getMethod)
|
|||||||
&& object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) {
|
&& object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) {
|
||||||
/* don't assign closure_object since we only reflect the invoke handler
|
/* don't assign closure_object since we only reflect the invoke handler
|
||||||
method and not the closure definition itself */
|
method and not the closure definition itself */
|
||||||
|
_fix_closure_prototype(mptr);
|
||||||
reflection_method_factory(ce, mptr, NULL, return_value);
|
reflection_method_factory(ce, mptr, NULL, return_value);
|
||||||
zval_dtor(&obj_tmp);
|
zval_dtor(&obj_tmp);
|
||||||
efree(lc_name);
|
efree(lc_name);
|
||||||
@ -4129,6 +4142,7 @@ static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval,
|
|||||||
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
||||||
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
|
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
|
||||||
{
|
{
|
||||||
|
_fix_closure_prototype(closure);
|
||||||
mptr = closure;
|
mptr = closure;
|
||||||
}
|
}
|
||||||
/* don't assign closure_object since we only reflect the invoke handler
|
/* don't assign closure_object since we only reflect the invoke handler
|
||||||
@ -4180,6 +4194,7 @@ ZEND_METHOD(reflection_class, getMethods)
|
|||||||
if (Z_TYPE(intern->obj) != IS_UNDEF && instanceof_function(ce, zend_ce_closure)) {
|
if (Z_TYPE(intern->obj) != IS_UNDEF && instanceof_function(ce, zend_ce_closure)) {
|
||||||
zend_function *closure = zend_get_closure_invoke_method(Z_OBJ(intern->obj));
|
zend_function *closure = zend_get_closure_invoke_method(Z_OBJ(intern->obj));
|
||||||
if (closure) {
|
if (closure) {
|
||||||
|
_fix_closure_prototype(closure);
|
||||||
_addmethod(closure, ce, return_value, filter, &intern->obj);
|
_addmethod(closure, ce, return_value, filter, &intern->obj);
|
||||||
_free_function(closure);
|
_free_function(closure);
|
||||||
}
|
}
|
||||||
|
24
ext/reflection/tests/bug74949.phpt
Normal file
24
ext/reflection/tests/bug74949.phpt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
--TEST--
|
||||||
|
Bug #74949 (null pointer dereference in _function_string)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$f = function () {};
|
||||||
|
|
||||||
|
$r = new ReflectionMethod($f, "__invoke");
|
||||||
|
|
||||||
|
unset($f);
|
||||||
|
|
||||||
|
echo $r, "\n";
|
||||||
|
|
||||||
|
try {
|
||||||
|
echo $r->getPrototype();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Method [ <internal> public method __invoke ] {
|
||||||
|
}
|
||||||
|
|
||||||
|
Method Closure::__invoke does not have a prototype
|
Loading…
Reference in New Issue
Block a user