bug #1662 Fix leaks (jpauli)

This PR was merged into the 1.x branch.

Discussion
----------

Fix leaks

Commits
-------

c41d305 Cleanup API - make the compiler happy
8bb7cbb Fixed memory leaks
This commit is contained in:
Fabien Potencier
2015-03-26 13:32:49 +01:00
2 changed files with 62 additions and 96 deletions
+4
View File
@@ -21,11 +21,15 @@
extern zend_module_entry twig_module_entry;
#define phpext_twig_ptr &twig_module_entry
#ifndef PHP_WIN32
zend_module_entry *get_module(void);
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
PHP_FUNCTION(twig_template_get_attributes);
PHP_RSHUTDOWN_FUNCTION(twig);
#endif
+58 -96
View File
@@ -54,11 +54,22 @@ ZEND_BEGIN_ARG_INFO_EX(twig_template_get_attribute_args, ZEND_SEND_BY_VAL, ZEND_
ZEND_ARG_INFO(0, isDefinedTest)
ZEND_END_ARG_INFO()
zend_function_entry twig_functions[] = {
#ifndef PHP_FE_END
#define PHP_FE_END { NULL, NULL, NULL, 0, 0 }
#endif
static const zend_function_entry twig_functions[] = {
PHP_FE(twig_template_get_attributes, twig_template_get_attribute_args)
{NULL, NULL, NULL}
PHP_FE_END
};
PHP_RSHUTDOWN_FUNCTION(twig)
{
#if ZEND_DEBUG
CG(unclean_shutdown) = 0; /* get rid of PHPUnit's exit() and report memleaks */
#endif
return SUCCESS;
}
zend_module_entry twig_module_entry = {
STANDARD_MODULE_HEADER,
@@ -67,7 +78,7 @@ zend_module_entry twig_module_entry = {
NULL,
NULL,
NULL,
NULL,
PHP_RSHUTDOWN(twig),
NULL,
PHP_TWIG_VERSION,
STANDARD_MODULE_PROPERTIES
@@ -78,7 +89,7 @@ zend_module_entry twig_module_entry = {
ZEND_GET_MODULE(twig)
#endif
int TWIG_ARRAY_KEY_EXISTS(zval *array, zval *key)
static int TWIG_ARRAY_KEY_EXISTS(zval *array, zval *key)
{
if (Z_TYPE_P(array) != IS_ARRAY) {
return 0;
@@ -100,7 +111,7 @@ int TWIG_ARRAY_KEY_EXISTS(zval *array, zval *key)
}
}
int TWIG_INSTANCE_OF(zval *object, zend_class_entry *interface TSRMLS_DC)
static int TWIG_INSTANCE_OF(zval *object, zend_class_entry *interface TSRMLS_DC)
{
if (Z_TYPE_P(object) != IS_OBJECT) {
return 0;
@@ -108,7 +119,7 @@ int TWIG_INSTANCE_OF(zval *object, zend_class_entry *interface TSRMLS_DC)
return instanceof_function(Z_OBJCE_P(object), interface TSRMLS_CC);
}
int TWIG_INSTANCE_OF_USERLAND(zval *object, char *interface TSRMLS_DC)
static int TWIG_INSTANCE_OF_USERLAND(zval *object, char *interface TSRMLS_DC)
{
zend_class_entry **pce;
if (Z_TYPE_P(object) != IS_OBJECT) {
@@ -120,7 +131,7 @@ int TWIG_INSTANCE_OF_USERLAND(zval *object, char *interface TSRMLS_DC)
return instanceof_function(Z_OBJCE_P(object), *pce TSRMLS_CC);
}
zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
static zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
{
zend_class_entry *ce = Z_OBJCE_P(object);
zval *retval;
@@ -143,7 +154,7 @@ zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
return NULL;
}
int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
static int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
{
zend_class_entry *ce = Z_OBJCE_P(object);
zval *retval;
@@ -166,7 +177,7 @@ int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
return 0;
}
char *TWIG_STRTOLOWER(const char *str, int str_len)
static char *TWIG_STRTOLOWER(const char *str, int str_len)
{
char *item_dup;
@@ -175,7 +186,7 @@ char *TWIG_STRTOLOWER(const char *str, int str_len)
return item_dup;
}
zval *TWIG_CALL_USER_FUNC_ARRAY(zval *object, char *function, zval *arguments TSRMLS_DC)
static zval *TWIG_CALL_USER_FUNC_ARRAY(zval *object, char *function, zval *arguments TSRMLS_DC)
{
zend_fcall_info fci;
zval ***args = NULL;
@@ -227,7 +238,7 @@ zval *TWIG_CALL_USER_FUNC_ARRAY(zval *object, char *function, zval *arguments TS
return retval_ptr;
}
int TWIG_CALL_BOOLEAN(zval *object, char *functionName TSRMLS_DC)
static int TWIG_CALL_BOOLEAN(zval *object, char *functionName TSRMLS_DC)
{
zval *ret;
int res;
@@ -238,7 +249,7 @@ int TWIG_CALL_BOOLEAN(zval *object, char *functionName TSRMLS_DC)
return res;
}
zval *TWIG_GET_STATIC_PROPERTY(zval *class, char *prop_name TSRMLS_DC)
static zval *TWIG_GET_STATIC_PROPERTY(zval *class, char *prop_name TSRMLS_DC)
{
zval **tmp_zval;
zend_class_entry *ce;
@@ -256,7 +267,7 @@ zval *TWIG_GET_STATIC_PROPERTY(zval *class, char *prop_name TSRMLS_DC)
return *tmp_zval;
}
zval *TWIG_GET_ARRAY_ELEMENT_ZVAL(zval *class, zval *prop_name TSRMLS_DC)
static zval *TWIG_GET_ARRAY_ELEMENT_ZVAL(zval *class, zval *prop_name TSRMLS_DC)
{
zval **tmp_zval;
@@ -288,7 +299,7 @@ zval *TWIG_GET_ARRAY_ELEMENT_ZVAL(zval *class, zval *prop_name TSRMLS_DC)
return NULL;
}
zval *TWIG_GET_ARRAY_ELEMENT(zval *class, char *prop_name, int prop_name_length TSRMLS_DC)
static zval *TWIG_GET_ARRAY_ELEMENT(zval *class, char *prop_name, int prop_name_length TSRMLS_DC)
{
zval **tmp_zval;
@@ -314,7 +325,7 @@ zval *TWIG_GET_ARRAY_ELEMENT(zval *class, char *prop_name, int prop_name_length
return NULL;
}
zval *TWIG_PROPERTY(zval *object, zval *propname TSRMLS_DC)
static zval *TWIG_PROPERTY(zval *object, zval *propname TSRMLS_DC)
{
zval *tmp = NULL;
@@ -331,7 +342,7 @@ zval *TWIG_PROPERTY(zval *object, zval *propname TSRMLS_DC)
return tmp;
}
int TWIG_HAS_PROPERTY(zval *object, zval *propname TSRMLS_DC)
static int TWIG_HAS_PROPERTY(zval *object, zval *propname TSRMLS_DC)
{
if (Z_OBJ_HT_P(object)->has_property) {
#if PHP_VERSION_ID >= 50400
@@ -343,7 +354,7 @@ int TWIG_HAS_PROPERTY(zval *object, zval *propname TSRMLS_DC)
return 0;
}
int TWIG_HAS_DYNAMIC_PROPERTY(zval *object, char *prop, int prop_len TSRMLS_DC)
static int TWIG_HAS_DYNAMIC_PROPERTY(zval *object, char *prop, int prop_len TSRMLS_DC)
{
if (Z_OBJ_HT_P(object)->get_properties) {
return zend_hash_quick_exists(
@@ -356,7 +367,7 @@ int TWIG_HAS_DYNAMIC_PROPERTY(zval *object, char *prop, int prop_len TSRMLS_DC)
return 0;
}
zval *TWIG_PROPERTY_CHAR(zval *object, char *propname TSRMLS_DC)
static zval *TWIG_PROPERTY_CHAR(zval *object, char *propname TSRMLS_DC)
{
zval *tmp_name_zval, *tmp;
@@ -367,12 +378,7 @@ zval *TWIG_PROPERTY_CHAR(zval *object, char *propname TSRMLS_DC)
return tmp;
}
int TWIG_CALL_B_0(zval *object, char *method)
{
return 0;
}
zval *TWIG_CALL_S(zval *object, char *method, char *arg0 TSRMLS_DC)
static zval *TWIG_CALL_S(zval *object, char *method, char *arg0 TSRMLS_DC)
{
zend_fcall_info fci;
zval **args[1];
@@ -410,7 +416,7 @@ zval *TWIG_CALL_S(zval *object, char *method, char *arg0 TSRMLS_DC)
return retval_ptr;
}
int TWIG_CALL_SB(zval *object, char *method, char *arg0 TSRMLS_DC)
static int TWIG_CALL_SB(zval *object, char *method, char *arg0 TSRMLS_DC)
{
zval *retval_ptr;
int success;
@@ -425,51 +431,7 @@ int TWIG_CALL_SB(zval *object, char *method, char *arg0 TSRMLS_DC)
return success;
}
int TWIG_CALL_Z(zval *object, char *method, zval *arg1 TSRMLS_DC)
{
zend_fcall_info fci;
zval **args[1];
zval *zfunction;
zval *retval_ptr;
int success;
args[0] = &arg1;
MAKE_STD_ZVAL(zfunction);
ZVAL_STRING(zfunction, method, 1);
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = zfunction;
fci.symbol_table = NULL;
#if PHP_VERSION_ID >= 50300
fci.object_ptr = object;
#else
fci.object_pp = &object;
#endif
fci.retval_ptr_ptr = &retval_ptr;
fci.param_count = 1;
fci.params = args;
fci.no_separation = 0;
if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
FREE_DTOR(zfunction);
if (retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
return 0;
}
FREE_DTOR(zfunction);
success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr));
if (retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
return success;
}
int TWIG_CALL_ZZ(zval *object, char *method, zval *arg1, zval *arg2 TSRMLS_DC)
static int TWIG_CALL_ZZ(zval *object, char *method, zval *arg1, zval *arg2 TSRMLS_DC)
{
zend_fcall_info fci;
zval **args[2];
@@ -516,7 +478,7 @@ int TWIG_CALL_ZZ(zval *object, char *method, zval *arg1, zval *arg2 TSRMLS_DC)
# define Z_UNSET_ISREF_P(pz) pz->is_ref = 0
#endif
void TWIG_NEW(zval *object, char *class, zval *arg0, zval *arg1 TSRMLS_DC)
static void TWIG_NEW(zval *object, char *class, zval *arg0, zval *arg1 TSRMLS_DC)
{
zend_class_entry **pce;
@@ -561,7 +523,7 @@ static int twig_add_array_key_to_string(void *pDest APPLY_TSRMLS_DC, int num_arg
return 0;
}
char *TWIG_IMPLODE_ARRAY_KEYS(char *joiner, zval *array TSRMLS_DC)
static char *TWIG_IMPLODE_ARRAY_KEYS(char *joiner, zval *array TSRMLS_DC)
{
smart_str collector = { 0, 0, 0 };
@@ -572,24 +534,6 @@ char *TWIG_IMPLODE_ARRAY_KEYS(char *joiner, zval *array TSRMLS_DC)
return collector.c;
}
static void TWIG_THROW_EXCEPTION(char *exception_name TSRMLS_DC, char *message, ...)
{
char *buffer;
va_list args;
zend_class_entry **pce;
if (zend_lookup_class(exception_name, strlen(exception_name), &pce TSRMLS_CC) == FAILURE) {
return;
}
va_start(args, message);
vspprintf(&buffer, 0, message, args);
va_end(args);
zend_throw_exception_ex(*pce, 0 TSRMLS_CC, buffer);
efree(buffer);
}
static void TWIG_RUNTIME_ERROR(zval *template TSRMLS_DC, char *message, ...)
{
char *buffer;
@@ -794,6 +738,7 @@ PHP_FUNCTION(twig_template_get_attributes)
) {
if (isDefinedTest) {
efree(item);
RETURN_TRUE;
}
@@ -806,6 +751,7 @@ PHP_FUNCTION(twig_template_get_attributes)
if (free_ret) {
zval_ptr_dtor(&ret);
}
efree(item);
return;
}
/*
@@ -819,9 +765,11 @@ PHP_FUNCTION(twig_template_get_attributes)
*/
if (strcmp("array", type) == 0 || Z_TYPE_P(object) != IS_OBJECT) {
if (isDefinedTest) {
efree(item);
RETURN_FALSE;
}
if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
efree(item);
return;
}
/*
@@ -852,7 +800,9 @@ PHP_FUNCTION(twig_template_get_attributes)
if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty", item);
} else {
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC));
char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC);
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, array_keys);
efree(array_keys);
}
} else {
char *type_name = zend_zval_type_name(object);
@@ -865,6 +815,7 @@ PHP_FUNCTION(twig_template_get_attributes)
item, type_name, Z_STRVAL_P(object));
zval_ptr_dtor(&object);
}
efree(item);
return;
}
}
@@ -878,6 +829,7 @@ PHP_FUNCTION(twig_template_get_attributes)
if (Z_TYPE_P(object) != IS_OBJECT) {
if (isDefinedTest) {
efree(item);
RETURN_FALSE;
}
/*
@@ -888,6 +840,7 @@ PHP_FUNCTION(twig_template_get_attributes)
}
*/
if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
efree(item);
return;
}
@@ -898,7 +851,7 @@ PHP_FUNCTION(twig_template_get_attributes)
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\")", item, type_name, Z_STRVAL_P(object));
zval_ptr_dtor(&object);
efree(item);
return;
}
/*
@@ -939,16 +892,19 @@ PHP_FUNCTION(twig_template_get_attributes)
if (tmp_item || TWIG_HAS_PROPERTY(object, zitem TSRMLS_CC) || TWIG_HAS_DYNAMIC_PROPERTY(object, item, item_len TSRMLS_CC)) {
if (isDefinedTest) {
efree(item);
RETURN_TRUE;
}
if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "sandbox" TSRMLS_CC)) {
TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "sandbox" TSRMLS_CC), "checkPropertyAllowed", object, zitem TSRMLS_CC);
}
if (EG(exception)) {
efree(item);
return;
}
ret = TWIG_PROPERTY(object, zitem TSRMLS_CC);
efree(item);
RETURN_ZVAL(ret, 1, 0);
}
}
@@ -1021,19 +977,22 @@ PHP_FUNCTION(twig_template_get_attributes)
efree(lcItem);
if (isDefinedTest) {
efree(item);
RETURN_FALSE;
}
if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
efree(item);
return;
}
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Method \"%s\" for object \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
efree(item);
return;
}
if (isDefinedTest) {
efree(tmp_method_name_get);
efree(tmp_method_name_is);
efree(lcItem);
efree(lcItem);efree(item);
RETURN_TRUE;
}
/*
@@ -1046,11 +1005,11 @@ PHP_FUNCTION(twig_template_get_attributes)
if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "sandbox" TSRMLS_CC)) {
TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "sandbox" TSRMLS_CC), "checkMethodAllowed", object, zmethod TSRMLS_CC);
}
zval_ptr_dtor(&zmethod);
if (EG(exception)) {
efree(tmp_method_name_get);
efree(tmp_method_name_is);
efree(lcItem);
zval_ptr_dtor(&zmethod);
efree(lcItem);efree(item);
return;
}
/*
@@ -1068,6 +1027,9 @@ PHP_FUNCTION(twig_template_get_attributes)
ret = TWIG_CALL_USER_FUNC_ARRAY(object, method, arguments TSRMLS_CC);
if (EG(exception) && TWIG_INSTANCE_OF(EG(exception), spl_ce_BadMethodCallException TSRMLS_CC)) {
if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
efree(tmp_method_name_get);
efree(tmp_method_name_is);
efree(lcItem);efree(item);
zend_clear_exception(TSRMLS_C);
return;
}
@@ -1076,7 +1038,6 @@ PHP_FUNCTION(twig_template_get_attributes)
efree(tmp_method_name_get);
efree(tmp_method_name_is);
efree(lcItem);
zval_ptr_dtor(&zmethod);
}
/*
// useful when calling a template method from a template
@@ -1087,6 +1048,7 @@ PHP_FUNCTION(twig_template_get_attributes)
return $ret;
*/
efree(item);
// ret can be null, if e.g. the called method throws an exception
if (ret) {
if (TWIG_INSTANCE_OF_USERLAND(object, "Twig_TemplateInterface" TSRMLS_CC)) {