From cb732490a3273baee35288e4ba4462e6cfc9839c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 2 Mar 2015 18:29:18 +0100 Subject: [PATCH 01/11] removed an obsolete recipe --- doc/api.rst | 4 +++- doc/recipes.rst | 50 ------------------------------------------------- 2 files changed, 3 insertions(+), 51 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index 3ff5d1a2ac..cdeaffdb04 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -106,7 +106,9 @@ The following options are available: to avoid collision with built-in escaping strategies). As of Twig 1.17, the ``filename`` escaping strategy determines the escaping - strategy to use for a template based on the template filename extension. + strategy to use for a template based on the template filename extension (this + strategy does not incur any overhead at runtime as auto-escaping is done at + compilation time.) * ``optimizations``: A flag that indicates which optimizations to apply (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to diff --git a/doc/recipes.rst b/doc/recipes.rst index 64090d913f..86cede6302 100644 --- a/doc/recipes.rst +++ b/doc/recipes.rst @@ -316,56 +316,6 @@ This can be easily achieved with the following code:: return $node; } -Using the Template name to set the default Escaping Strategy ------------------------------------------------------------- - -.. versionadded:: 1.8 - This recipe requires Twig 1.8 or later. - -The ``autoescape`` option determines the default escaping strategy to use when -no escaping is applied on a variable. When Twig is used to mostly generate -HTML files, you can set it to ``html`` and explicitly change it to ``js`` when -you have some dynamic JavaScript files thanks to the ``autoescape`` tag: - -.. code-block:: jinja - - {% autoescape 'js' %} - ... some JS ... - {% endautoescape %} - -But if you have many HTML and JS files, and if your template names follow some -conventions, you can instead determine the default escaping strategy to use -based on the template name. Let's say that your template names always end -with ``.html`` for HTML files, ``.js`` for JavaScript ones, and ``.css`` for -stylesheets, here is how you can configure Twig:: - - class TwigEscapingGuesser - { - function guess($filename) - { - // get the format - $format = substr($filename, strrpos($filename, '.') + 1); - - switch ($format) { - case 'js': - return 'js'; - case 'css': - return 'css'; - case 'html': - default: - return 'html'; - } - } - } - - $loader = new Twig_Loader_Filesystem('/path/to/templates'); - $twig = new Twig_Environment($loader, array( - 'autoescape' => array(new TwigEscapingGuesser(), 'guess'), - )); - -This dynamic strategy does not incur any overhead at runtime as auto-escaping -is done at compilation time. - Using a Database to store Templates ----------------------------------- From 7ee4aec238949225a25f174318dc84167e5f360d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 17 Mar 2015 18:21:28 +0100 Subject: [PATCH 02/11] tweaked docs about the C extension --- doc/installation.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/installation.rst b/doc/installation.rst index eeaef9a725..afdcf16593 100644 --- a/doc/installation.rst +++ b/doc/installation.rst @@ -50,8 +50,11 @@ Installing the C extension The C extension was added in Twig 1.4. .. note:: - The C extension is **optional** but as it brings some nice performance - improvements, you might want to install it in your production environment. + + The C extension is **optional** but it brings some nice performance + improvements. Note that the extension is not a replacement for the PHP + code; it only implements a small part of the PHP code to improve the + performance at runtime; you must still install the regular PHP code. Twig comes with a C extension that enhances the performance of the Twig runtime engine; install it like any other PHP extensions: From 8bb7cbbd9d7f4a2d4df28a6d57706ae240d687d4 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Wed, 25 Mar 2015 15:50:15 +0100 Subject: [PATCH 03/11] Fixed memory leaks --- ext/twig/twig.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/ext/twig/twig.c b/ext/twig/twig.c index 5c482bedb7..165295ca14 100644 --- a/ext/twig/twig.c +++ b/ext/twig/twig.c @@ -59,6 +59,13 @@ zend_function_entry twig_functions[] = { {NULL, NULL, NULL} }; +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 +74,7 @@ zend_module_entry twig_module_entry = { NULL, NULL, NULL, - NULL, + PHP_RSHUTDOWN(twig), NULL, PHP_TWIG_VERSION, STANDARD_MODULE_PROPERTIES @@ -794,6 +801,7 @@ PHP_FUNCTION(twig_template_get_attributes) ) { if (isDefinedTest) { + efree(item); RETURN_TRUE; } @@ -806,6 +814,7 @@ PHP_FUNCTION(twig_template_get_attributes) if (free_ret) { zval_ptr_dtor(&ret); } + efree(item); return; } /* @@ -819,9 +828,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 +863,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 +878,7 @@ PHP_FUNCTION(twig_template_get_attributes) item, type_name, Z_STRVAL_P(object)); zval_ptr_dtor(&object); } + efree(item); return; } } @@ -878,6 +892,7 @@ PHP_FUNCTION(twig_template_get_attributes) if (Z_TYPE_P(object) != IS_OBJECT) { if (isDefinedTest) { + efree(item); RETURN_FALSE; } /* @@ -888,6 +903,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 +914,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 +955,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 +1040,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 +1068,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 +1090,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 +1101,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 +1111,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)) { From c41d305251e0a88df6889aa9337b06d1101d7ab0 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Wed, 25 Mar 2015 16:03:19 +0100 Subject: [PATCH 04/11] Cleanup API - make the compiler happy --- ext/twig/php_twig.h | 4 ++ ext/twig/twig.c | 115 ++++++++++---------------------------------- 2 files changed, 30 insertions(+), 89 deletions(-) diff --git a/ext/twig/php_twig.h b/ext/twig/php_twig.h index 36b5c7bd7d..9a5975fa3b 100644 --- a/ext/twig/php_twig.h +++ b/ext/twig/php_twig.h @@ -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 diff --git a/ext/twig/twig.c b/ext/twig/twig.c index 165295ca14..ae5b1470ec 100644 --- a/ext/twig/twig.c +++ b/ext/twig/twig.c @@ -54,9 +54,13 @@ 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) @@ -85,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; @@ -107,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; @@ -115,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) { @@ -127,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; @@ -150,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; @@ -173,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; @@ -182,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; @@ -234,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; @@ -245,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; @@ -263,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; @@ -295,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; @@ -321,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; @@ -338,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 @@ -350,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( @@ -363,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; @@ -374,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]; @@ -417,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; @@ -432,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]; @@ -523,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; @@ -568,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 }; @@ -579,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; From 67920147a81d5bd5bcd052b239ff85bae789f5a3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 26 Mar 2015 13:33:23 +0100 Subject: [PATCH 05/11] updated CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 7b59881cff..b8c45b0a06 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 1.18.1 (2015-XX-XX) + * fixed memory leaks in the C extension * deprecated Twig_Loader_String * fixed the slice filter when used with a SimpleXMLElement object * fixed filesystem loader when trying to load non-files (like directories) From 9f70492f44398e276d1b81c1b43adfe6751c7b7f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 19 Apr 2015 10:30:27 +0200 Subject: [PATCH 06/11] prepared the 1.18.1 release --- CHANGELOG | 2 +- ext/twig/php_twig.h | 2 +- lib/Twig/Environment.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b8c45b0a06..edd6757c18 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -* 1.18.1 (2015-XX-XX) +* 1.18.1 (2015-04-19) * fixed memory leaks in the C extension * deprecated Twig_Loader_String diff --git a/ext/twig/php_twig.h b/ext/twig/php_twig.h index 9a5975fa3b..9bf6d1152e 100644 --- a/ext/twig/php_twig.h +++ b/ext/twig/php_twig.h @@ -15,7 +15,7 @@ #ifndef PHP_TWIG_H #define PHP_TWIG_H -#define PHP_TWIG_VERSION "1.18.1-DEV" +#define PHP_TWIG_VERSION "1.18.1" #include "php.h" diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index f72c9e80a6..9acc31a0e7 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -16,7 +16,7 @@ */ class Twig_Environment { - const VERSION = '1.18.1-DEV'; + const VERSION = '1.18.1'; protected $charset; protected $loader; From 7d5fe0fbd442f6bfc526260eb14ed99ea2a561f5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 19 Apr 2015 10:35:41 +0200 Subject: [PATCH 07/11] bumped version to 1.18.2-DEV --- CHANGELOG | 4 ++++ ext/twig/php_twig.h | 2 +- lib/Twig/Environment.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index edd6757c18..d069f25a47 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +* 1.18.2 (2015-XX-XX) + + * n/a + * 1.18.1 (2015-04-19) * fixed memory leaks in the C extension diff --git a/ext/twig/php_twig.h b/ext/twig/php_twig.h index 9bf6d1152e..b645bbffd2 100644 --- a/ext/twig/php_twig.h +++ b/ext/twig/php_twig.h @@ -15,7 +15,7 @@ #ifndef PHP_TWIG_H #define PHP_TWIG_H -#define PHP_TWIG_VERSION "1.18.1" +#define PHP_TWIG_VERSION "1.18.2-DEV" #include "php.h" diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 9acc31a0e7..39f7643c77 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -16,7 +16,7 @@ */ class Twig_Environment { - const VERSION = '1.18.1'; + const VERSION = '1.18.2-DEV'; protected $charset; protected $loader; From 2030482e4de86535dc8deeb123094bcac7fbc246 Mon Sep 17 00:00:00 2001 From: Possum Date: Fri, 24 Apr 2015 16:57:11 +0200 Subject: [PATCH 08/11] clean ups --- lib/Twig/Environment.php | 11 +++++----- lib/Twig/ExpressionParser.php | 6 ++++- lib/Twig/Extension/Core.php | 20 +++++++++++------ lib/Twig/Extension/Escaper.php | 2 ++ lib/Twig/LoaderInterface.php | 3 ++- lib/Twig/Node.php | 34 ++++++++++++++--------------- lib/Twig/Node/SandboxedPrint.php | 2 ++ lib/Twig/NodeTraverser.php | 2 ++ lib/Twig/NodeVisitor/Optimizer.php | 4 ++++ lib/Twig/Template.php | 4 +++- lib/Twig/TokenParser.php | 2 +- lib/Twig/TokenParser/Block.php | 2 +- lib/Twig/TokenParser/Macro.php | 2 +- lib/Twig/TokenParser/Set.php | 4 ++-- lib/Twig/TokenParserInterface.php | 2 +- test/Twig/Tests/EnvironmentTest.php | 8 +++---- test/Twig/Tests/LexerTest.php | 2 +- test/Twig/Tests/Node/ModuleTest.php | 2 +- test/Twig/Tests/TemplateTest.php | 2 +- test/Twig/Tests/escapingTest.php | 3 ++- 20 files changed, 70 insertions(+), 47 deletions(-) diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 39f7643c77..a2a68368e7 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -351,8 +351,7 @@ public function loadTemplate($name, $index = null) * * This method should not be used as a generic way to load templates. * - * @param string $name The template name - * @param int $index The index if it is an embedded template + * @param string $template The template name * * @return Twig_Template A template instance representing the given template name * @@ -483,7 +482,7 @@ public function getLexer() /** * Sets the Lexer instance. * - * @param Twig_LexerInterface A Twig_LexerInterface instance + * @param Twig_LexerInterface $lexer A Twig_LexerInterface instance */ public function setLexer(Twig_LexerInterface $lexer) { @@ -522,7 +521,7 @@ public function getParser() /** * Sets the Parser instance. * - * @param Twig_ParserInterface A Twig_ParserInterface instance + * @param Twig_ParserInterface $parser A Twig_ParserInterface instance */ public function setParser(Twig_ParserInterface $parser) { @@ -1271,11 +1270,11 @@ protected function writeCacheFile($file, $content) if (false === @mkdir($dir, 0777, true)) { clearstatcache(false, $dir); if (!is_dir($dir)) { - throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir)); + throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir)); } } } elseif (!is_writable($dir)) { - throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir)); + throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir)); } $tmpFile = tempnam($dir, basename($file)); diff --git a/lib/Twig/ExpressionParser.php b/lib/Twig/ExpressionParser.php index fa9fa35e8e..8fc834613b 100644 --- a/lib/Twig/ExpressionParser.php +++ b/lib/Twig/ExpressionParser.php @@ -315,7 +315,7 @@ public function getFunctionNode($name, $line) { switch ($name) { case 'parent': - $args = $this->parseArguments(); + $this->parseArguments(); if (!count($this->parser->getBlockStack())) { throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename()); } @@ -468,6 +468,10 @@ public function parseFilterExpressionRaw($node, $tag = null) * * @param bool $namedArguments Whether to allow named arguments or not * @param bool $definition Whether we are parsing arguments for a function definition + * + * @return Twig_Node + * + * @throws Twig_Error_Syntax */ public function parseArguments($namedArguments = false, $definition = false) { diff --git a/lib/Twig/Extension/Core.php b/lib/Twig/Extension/Core.php index 346006d328..fd3b11718c 100644 --- a/lib/Twig/Extension/Core.php +++ b/lib/Twig/Extension/Core.php @@ -921,7 +921,9 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false /** * Sorts an array. * - * @param array $array An array + * @param array $array + * + * @return array */ function twig_sort_filter($array) { @@ -952,6 +954,8 @@ function twig_in_filter($value, $compare) * @param string $strategy The escaping strategy * @param string $charset The charset * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) + * + * @return string */ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false) { @@ -1398,15 +1402,17 @@ function twig_test_iterable($value) /** * Renders a template. * - * @param string|array $template The template to render or an array of templates to try consecutively - * @param array $variables The variables to pass to the template - * @param bool $with_context Whether to pass the current context variables or not - * @param bool $ignore_missing Whether to ignore missing templates or not - * @param bool $sandboxed Whether to sandbox the template or not + * @param Twig_Environment $env + * @param array $context + * @param string|array $template The template to render or an array of templates to try consecutively + * @param array $variables The variables to pass to the template + * @param bool $withContext + * @param bool $ignoreMissing Whether to ignore missing templates or not + * @param bool $sandboxed Whether to sandbox the template or not * * @return string The rendered template */ -function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) +function twig_include(Twig_Environment $env, array $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) { $alreadySandboxed = false; $sandbox = null; diff --git a/lib/Twig/Extension/Escaper.php b/lib/Twig/Extension/Escaper.php index 0edf563ab6..cf2020eecc 100644 --- a/lib/Twig/Extension/Escaper.php +++ b/lib/Twig/Extension/Escaper.php @@ -104,6 +104,8 @@ public function getName() * Marks a variable as being safe. * * @param string $string A PHP variable + * + * @return string */ function twig_raw_filter($string) { diff --git a/lib/Twig/LoaderInterface.php b/lib/Twig/LoaderInterface.php index b87058e67c..9cd45e2a26 100644 --- a/lib/Twig/LoaderInterface.php +++ b/lib/Twig/LoaderInterface.php @@ -42,7 +42,8 @@ public function getCacheKey($name); * Returns true if the template is still fresh. * * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * @param int $time Timestamp of the last modification time of the + * cached template * * @return bool true if the template is fresh, false otherwise * diff --git a/lib/Twig/Node.php b/lib/Twig/Node.php index 515d81bb58..1c78e7b27c 100644 --- a/lib/Twig/Node.php +++ b/lib/Twig/Node.php @@ -122,7 +122,7 @@ public function getNodeTag() /** * Returns true if the attribute is defined. * - * @param string The attribute name + * @param string $name The attribute name * * @return bool true if the attribute is defined, false otherwise */ @@ -132,11 +132,11 @@ public function hasAttribute($name) } /** - * Gets an attribute. + * Gets an attribute value by name. * - * @param string The attribute name + * @param string $name * - * @return mixed The attribute value + * @return mixed */ public function getAttribute($name) { @@ -148,10 +148,10 @@ public function getAttribute($name) } /** - * Sets an attribute. + * Sets an attribute by name to a value. * - * @param string The attribute name - * @param mixed The attribute value + * @param string $name + * @param mixed $value */ public function setAttribute($name, $value) { @@ -159,9 +159,9 @@ public function setAttribute($name, $value) } /** - * Removes an attribute. + * Removes an attribute by name. * - * @param string The attribute name + * @param string $name */ public function removeAttribute($name) { @@ -169,11 +169,11 @@ public function removeAttribute($name) } /** - * Returns true if the node with the given identifier exists. + * Returns true if the node with the given name exists. * - * @param string The node name + * @param string $name * - * @return bool true if the node with the given name exists, false otherwise + * @return bool */ public function hasNode($name) { @@ -183,9 +183,9 @@ public function hasNode($name) /** * Gets a node by name. * - * @param string The node name + * @param string $name * - * @return Twig_Node A Twig_Node instance + * @return Twig_Node */ public function getNode($name) { @@ -199,8 +199,8 @@ public function getNode($name) /** * Sets a node. * - * @param string The node name - * @param Twig_Node A Twig_Node instance + * @param string $name + * @param Twig_Node $node */ public function setNode($name, $node = null) { @@ -210,7 +210,7 @@ public function setNode($name, $node = null) /** * Removes a node by name. * - * @param string The node name + * @param string $name */ public function removeNode($name) { diff --git a/lib/Twig/Node/SandboxedPrint.php b/lib/Twig/Node/SandboxedPrint.php index 91872ccccd..823e7acc78 100644 --- a/lib/Twig/Node/SandboxedPrint.php +++ b/lib/Twig/Node/SandboxedPrint.php @@ -47,6 +47,8 @@ public function compile(Twig_Compiler $compiler) * This is mostly needed when another visitor adds filters (like the escaper one). * * @param Twig_Node $node A Node + * + * @return Twig_Node */ protected function removeNodeFilter($node) { diff --git a/lib/Twig/NodeTraverser.php b/lib/Twig/NodeTraverser.php index 8178a55c0d..6024e65d02 100644 --- a/lib/Twig/NodeTraverser.php +++ b/lib/Twig/NodeTraverser.php @@ -54,6 +54,8 @@ public function addVisitor(Twig_NodeVisitorInterface $visitor) * Traverses a node and calls the registered visitors. * * @param Twig_NodeInterface $node A Twig_NodeInterface instance + * + * @return Twig_NodeInterface */ public function traverse(Twig_NodeInterface $node) { diff --git a/lib/Twig/NodeVisitor/Optimizer.php b/lib/Twig/NodeVisitor/Optimizer.php index b9f9a5bfa6..b206e9ad39 100644 --- a/lib/Twig/NodeVisitor/Optimizer.php +++ b/lib/Twig/NodeVisitor/Optimizer.php @@ -129,6 +129,8 @@ protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment * * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment + * + * @return Twig_NodeInterface */ protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env) { @@ -153,6 +155,8 @@ protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment * * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment + * + * @return Twig_NodeInterface */ protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env) { diff --git a/lib/Twig/Template.php b/lib/Twig/Template.php index caf96428b2..477a7b9fea 100644 --- a/lib/Twig/Template.php +++ b/lib/Twig/Template.php @@ -58,6 +58,8 @@ public function getEnvironment() * This method is for internal use only and should never be called * directly. * + * @param array $context + * * @return Twig_TemplateInterface|false The parent template or false if there is no parent */ public function getParent(array $context) @@ -352,7 +354,7 @@ abstract protected function doDisplay(array $context, array $blocks = array()); * @param string $item The variable to return from the context * @param bool $ignoreStrictCheck Whether to ignore the strict variable check or not * - * @return The content of the context variable + * @return mixed The content of the context variable * * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode */ diff --git a/lib/Twig/TokenParser.php b/lib/Twig/TokenParser.php index decebd5eea..57b1825bda 100644 --- a/lib/Twig/TokenParser.php +++ b/lib/Twig/TokenParser.php @@ -24,7 +24,7 @@ abstract class Twig_TokenParser implements Twig_TokenParserInterface /** * Sets the parser associated with this token parser * - * @param $parser A Twig_Parser instance + * @param Twig_Parser $parser A Twig_Parser instance */ public function setParser(Twig_Parser $parser) { diff --git a/lib/Twig/TokenParser/Block.php b/lib/Twig/TokenParser/Block.php index 81e6b1cffd..0a46200a11 100644 --- a/lib/Twig/TokenParser/Block.php +++ b/lib/Twig/TokenParser/Block.php @@ -47,7 +47,7 @@ public function parse(Twig_Token $token) $value = $token->getValue(); if ($value != $name) { - throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given)', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename()); } } } else { diff --git a/lib/Twig/TokenParser/Macro.php b/lib/Twig/TokenParser/Macro.php index 87a299d821..ad910b537b 100644 --- a/lib/Twig/TokenParser/Macro.php +++ b/lib/Twig/TokenParser/Macro.php @@ -42,7 +42,7 @@ public function parse(Twig_Token $token) $value = $token->getValue(); if ($value != $name) { - throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given)', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename()); } } $this->parser->popLocalScope(); diff --git a/lib/Twig/TokenParser/Set.php b/lib/Twig/TokenParser/Set.php index 84f7e94cb3..0b419095fd 100644 --- a/lib/Twig/TokenParser/Set.php +++ b/lib/Twig/TokenParser/Set.php @@ -48,13 +48,13 @@ public function parse(Twig_Token $token) $stream->expect(Twig_Token::BLOCK_END_TYPE); if (count($names) !== count($values)) { - throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignments.", $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getFilename()); } } else { $capture = true; if (count($names) > 1) { - throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getFilename()); } $stream->expect(Twig_Token::BLOCK_END_TYPE); diff --git a/lib/Twig/TokenParserInterface.php b/lib/Twig/TokenParserInterface.php index 31e8d5d5e3..17e394b2a1 100644 --- a/lib/Twig/TokenParserInterface.php +++ b/lib/Twig/TokenParserInterface.php @@ -19,7 +19,7 @@ interface Twig_TokenParserInterface /** * Sets the parser associated with this token parser * - * @param $parser A Twig_Parser instance + * @param Twig_Parser $parser A Twig_Parser instance */ public function setParser(Twig_Parser $parser); diff --git a/test/Twig/Tests/EnvironmentTest.php b/test/Twig/Tests/EnvironmentTest.php index ee127e01e0..d0ada964e5 100644 --- a/test/Twig/Tests/EnvironmentTest.php +++ b/test/Twig/Tests/EnvironmentTest.php @@ -56,7 +56,7 @@ public function testGlobals() // globals can be modified after runtime init $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface')); $twig->addGlobal('foo', 'foo'); - $globals = $twig->getGlobals(); + $twig->getGlobals(); $twig->initRuntime(); $twig->addGlobal('foo', 'bar'); $globals = $twig->getGlobals(); @@ -91,7 +91,7 @@ public function testGlobals() // globals cannot be added after runtime init $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface')); $twig->addGlobal('foo', 'foo'); - $globals = $twig->getGlobals(); + $twig->getGlobals(); $twig->initRuntime(); try { $twig->addGlobal('bar', 'bar'); @@ -103,7 +103,7 @@ public function testGlobals() // globals cannot be added after extensions init $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface')); $twig->addGlobal('foo', 'foo'); - $globals = $twig->getGlobals(); + $twig->getGlobals(); $twig->getFunctions(); try { $twig->addGlobal('bar', 'bar'); @@ -115,7 +115,7 @@ public function testGlobals() // globals cannot be added after extensions and runtime init $twig = new Twig_Environment($this->getMock('Twig_LoaderInterface')); $twig->addGlobal('foo', 'foo'); - $globals = $twig->getGlobals(); + $twig->getGlobals(); $twig->getFunctions(); $twig->initRuntime(); try { diff --git a/test/Twig/Tests/LexerTest.php b/test/Twig/Tests/LexerTest.php index c4d7083126..4ef58e5d3c 100644 --- a/test/Twig/Tests/LexerTest.php +++ b/test/Twig/Tests/LexerTest.php @@ -144,7 +144,7 @@ public function testBigNumbers() $lexer = new Twig_Lexer(new Twig_Environment()); $stream = $lexer->tokenize($template); - $node = $stream->next(); + $stream->next(); $node = $stream->next(); $this->assertEquals("922337203685477580700", $node->getValue()); } diff --git a/test/Twig/Tests/Node/ModuleTest.php b/test/Twig/Tests/Node/ModuleTest.php index 5facc55a4c..5688af8cc8 100644 --- a/test/Twig/Tests/Node/ModuleTest.php +++ b/test/Twig/Tests/Node/ModuleTest.php @@ -130,7 +130,7 @@ public function getDebugInfo() EOF , $twig); - $set = new Twig_Node_Set(false, new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 4))), new Twig_Node(array(new Twig_Node_Expression_Constant("foo", 4))), 4); + $set = new Twig_Node_Set(false, new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 4))), new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 4))), 4); $body = new Twig_Node(array($set)); $extends = new Twig_Node_Expression_Conditional( new Twig_Node_Expression_Constant(true, 2), diff --git a/test/Twig/Tests/TemplateTest.php b/test/Twig/Tests/TemplateTest.php index 9010f28e10..b66930608f 100644 --- a/test/Twig/Tests/TemplateTest.php +++ b/test/Twig/Tests/TemplateTest.php @@ -509,7 +509,7 @@ class Twig_TemplateMagicPropertyObjectWithException { public function __isset($key) { - throw new Exception("Hey! Don't try to isset me!"); + throw new Exception('Hey! Don\'t try to isset me!'); } } diff --git a/test/Twig/Tests/escapingTest.php b/test/Twig/Tests/escapingTest.php index b28d3cda0a..dfa9d438e9 100644 --- a/test/Twig/Tests/escapingTest.php +++ b/test/Twig/Tests/escapingTest.php @@ -226,7 +226,8 @@ public function testUnicodeCodepointConversionToUtf8() /** * Convert a Unicode Codepoint to a literal UTF-8 character. * - * @param int $codepoint Unicode codepoint in hex notation + * @param int $codepoint Unicode codepoint in hex notation + * * @return string UTF-8 literal string */ protected function codepointToUtf8($codepoint) From 29723092b8795394697102c8c3466081b6812928 Mon Sep 17 00:00:00 2001 From: Tristan Darricau Date: Tue, 28 Apr 2015 19:35:37 +0200 Subject: [PATCH 09/11] Reduce the name of the cache directories to 1 character --- lib/Twig/Environment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 39f7643c77..0a5293c68e 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -250,7 +250,7 @@ public function getCacheFilename($name) $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix)); - return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php'; + return $this->getCache().'/'.$class[0].'/'.$class[1].'/'.$class.'.php'; } /** @@ -1271,11 +1271,11 @@ protected function writeCacheFile($file, $content) if (false === @mkdir($dir, 0777, true)) { clearstatcache(false, $dir); if (!is_dir($dir)) { - throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir)); + throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir)); } } } elseif (!is_writable($dir)) { - throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir)); + throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir)); } $tmpFile = tempnam($dir, basename($file)); From f012ea296af1f4937376621c4f50282fc02415e3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 29 Apr 2015 15:28:48 +0200 Subject: [PATCH 10/11] updated CHANGELOG --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index d069f25a47..6e1bbe9b4b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ * 1.18.2 (2015-XX-XX) - * n/a + * optimized the number of inodes and the size of realpath cache when using the cache * 1.18.1 (2015-04-19) From 9d7163e47d963dc5efce2b630abad7f6e9e79abe Mon Sep 17 00:00:00 2001 From: Johnny Date: Thu, 7 May 2015 13:01:06 +0800 Subject: [PATCH 11/11] Fix two failed unit tests on Windows: 1. fopen() cannot handle directory, replaced by opendir() for getting a testing resource. (also double check a resource is opened) 2. comparing paths by assertEquals() which has mixed '\' and '/' on Windows. --- test/Twig/Tests/Fixtures/tests/in.test | 4 +++- test/Twig/Tests/Loader/FilesystemTest.php | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/Twig/Tests/Fixtures/tests/in.test b/test/Twig/Tests/Fixtures/tests/in.test index d212f5d89b..545f51f81f 100644 --- a/test/Twig/Tests/Fixtures/tests/in.test +++ b/test/Twig/Tests/Fixtures/tests/in.test @@ -50,6 +50,7 @@ TRUE {{ [] in [true, ''] ? 'TRUE' : 'FALSE' }} {{ [] in [true, []] ? 'TRUE' : 'FALSE' }} +{{ resource ? 'TRUE' : 'FALSE' }} {{ resource in 'foo'~resource ? 'TRUE' : 'FALSE' }} {{ object in 'stdClass' ? 'TRUE' : 'FALSE' }} {{ [] in 'Array' ? 'TRUE' : 'FALSE' }} @@ -73,7 +74,7 @@ TRUE {{ 5.5 in '125.5' ? 'TRUE' : 'FALSE' }} {{ '5.5' in 125.5 ? 'TRUE' : 'FALSE' }} --DATA-- -return array('bar' => 'bar', 'foo' => array('bar' => 'bar'), 'dir_object' => new SplFileInfo(dirname(__FILE__)), 'object' => new stdClass(), 'resource' => fopen(dirname(__FILE__), 'r')) +return array('bar' => 'bar', 'foo' => array('bar' => 'bar'), 'dir_object' => new SplFileInfo(dirname(__FILE__)), 'object' => new stdClass(), 'resource' => opendir(dirname(__FILE__))) --EXPECT-- TRUE TRUE @@ -102,6 +103,7 @@ TRUE FALSE TRUE +TRUE FALSE FALSE FALSE diff --git a/test/Twig/Tests/Loader/FilesystemTest.php b/test/Twig/Tests/Loader/FilesystemTest.php index 03c1eb9f17..e07f374a3e 100644 --- a/test/Twig/Tests/Loader/FilesystemTest.php +++ b/test/Twig/Tests/Loader/FilesystemTest.php @@ -78,8 +78,8 @@ public function testPaths() ), $loader->getPaths('named')); $this->assertEquals( - $basePath.'/named_quater/named_absolute.html', - $loader->getCacheKey('@named/named_absolute.html') + realpath($basePath.'/named_quater/named_absolute.html'), + realpath($loader->getCacheKey('@named/named_absolute.html')) ); $this->assertEquals("path (final)\n", $loader->getSource('index.html')); $this->assertEquals("path (final)\n", $loader->getSource('@__main__/index.html'));