Skip to content

Instantly share code, notes, and snippets.

@stesie
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stesie/40d9ab136bea473a16ac to your computer and use it in GitHub Desktop.
Save stesie/40d9ab136bea473a16ac to your computer and use it in GitHub Desktop.
PHP get_method/call_method leak?
PHP_ARG_ENABLE(hello, whether to enable Hello
World support,
[ --enable-hello Enable Hello World support])
if test "$PHP_HELLO" = "yes"; then
AC_DEFINE(HAVE_HELLO, 1, [Whether you have Hello World])
PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)
fi
<?php
$foo = new Hello();
var_dump($foo);
echo "--- direct method call ---\n";
var_dump($foo->blar());
var_dump($foo->blar());
var_dump($foo->blar());
echo "--- call_user_func calls ---\n";
var_dump(call_user_func([ $foo, 'blar' ]));
var_dump(call_user_func([ $foo, 'blar' ]));
var_dump(call_user_func([ $foo, 'blar' ]));
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_hello.h"
zend_class_entry *php_ce_hello;
static zend_object_handlers hello_object_handlers;
static void php_hello_free_storage(void *object, zend_object_handle handle TSRMLS_DC)
{
zend_object *c = (zend_object *) object;
zend_object_std_dtor(c TSRMLS_CC);
efree(c);
}
static zend_object_value php_hello_new(zend_class_entry *ce TSRMLS_DC)
{
zend_object_value retval;
zend_object *c;
c = (zend_object *) ecalloc(1, sizeof(*c));
zend_object_std_init(c, ce TSRMLS_CC);
retval.handle = zend_objects_store_put(c, NULL, (zend_objects_free_object_storage_t) php_hello_free_storage, NULL TSRMLS_CC);
retval.handlers = &hello_object_handlers;
return retval;
}
static zend_function *php_hello_get_method(zval **object_ptr, char *method, int method_len, const zend_literal *key TSRMLS_DC)
{
zend_function *f;
f = (zend_function *) ecalloc(1, sizeof(*f));
f->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY;
f->common.function_name = estrndup(method, method_len);
return f;
}
static int php_hello_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS)
{
RETURN_LONG(this_ptr->refcount__gc);
}
static PHP_MINIT_FUNCTION(hello)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "Hello", NULL);
php_ce_hello = zend_register_internal_class(&ce TSRMLS_CC);
php_ce_hello->create_object = php_hello_new;
memcpy(&hello_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
hello_object_handlers.get_method = php_hello_get_method;
hello_object_handlers.call_method = php_hello_call_method;
}
zend_module_entry hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_HELLO_WORLD_EXTNAME,
NULL,
PHP_MINIT(hello),
NULL, // MSHUTDOWN
NULL, // RINIT
NULL, // RSHUTDOWN
NULL, // MINFO
#if ZEND_MODULE_API_NO >= 20010901
PHP_HELLO_WORLD_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif
#ifndef PHP_HELLO_H
#define PHP_HELLO_H 1
#define PHP_HELLO_WORLD_VERSION "1.0"
#define PHP_HELLO_WORLD_EXTNAME "hello"
PHP_FUNCTION(hello_world);
extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment