From 0f1e93ab7de44e580d38660b9658e7b0b9cf6d2b Mon Sep 17 00:00:00 2001 From: Ian Date: Sat, 5 Oct 2013 13:57:12 +0200 Subject: [PATCH] - bugfix loops using modifier capitalize did eat up memory (issue 159) git-svn-id: http://smarty-php.googlecode.com/svn/trunk/distribution/libs@4785 9dce5a81-9a42-0410-99e4-3799d3902e7f We need this, since using the capitalize modifier. --- bundled-libs/Smarty/change_log.txt | 4 ++ .../libs/plugins/modifier.capitalize.php | 38 +++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/bundled-libs/Smarty/change_log.txt b/bundled-libs/Smarty/change_log.txt index bd967b30..313e4610 100644 --- a/bundled-libs/Smarty/change_log.txt +++ b/bundled-libs/Smarty/change_log.txt @@ -1,4 +1,8 @@ ===== trunk ===== + +03.10.2013 + - bugfix loops using modifier capitalize did eat up memory (issue 159) + ===== Smarty-3.1.15 ===== 01.10.2013 - use current delimiters in compiler error messages (issue 157) diff --git a/bundled-libs/Smarty/libs/plugins/modifier.capitalize.php b/bundled-libs/Smarty/libs/plugins/modifier.capitalize.php index b3036b86..6b63e122 100644 --- a/bundled-libs/Smarty/libs/plugins/modifier.capitalize.php +++ b/bundled-libs/Smarty/libs/plugins/modifier.capitalize.php @@ -30,18 +30,17 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET ); } else { // uppercase word breaks - $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[2]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '");'), $string); + $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, smarty_mod_cap_mbconvert_cb('$matches'), $string); } // check uc_digits case if (!$uc_digits) { if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { - foreach ($matches[1] as $match) { + foreach($matches[1] as $match) { $upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0])); } } } - $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[3]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '");'), $upper_string); - + $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, smarty_mod_cap_mbconvert2_cb('$matches'), $upper_string); return $upper_string; } @@ -50,16 +49,39 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals $string = strtolower($string); } // uppercase (including hyphenated words) - $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).ucfirst(stripslashes($matches[2]));'), $string); + $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, smarty_mod_cap_ucfirst_cb('$matches'), $string); // check uc_digits case if (!$uc_digits) { if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { - foreach ($matches[1] as $match) { + foreach($matches[1] as $match) { $upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0])); } } } - $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).ucfirst(stripslashes($matches[3]));'), $upper_string); - + $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, smarty_mod_cap_ucfirst2_cb('$matches'), $upper_string); return $upper_string; } + +/** + * + * Bug: create_function() use exhausts memory when used in long loops + * Fix: use declared functions for callbacks instead of using create_function() + * Note: This can be fixed using anonymous functions instead, but that requires PHP >= 5.3 + * + * @author Kyle Renfrow + */ +function smarty_mod_cap_mbconvert_cb($matches){ + return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[2]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '"); +} + +function smarty_mod_cap_mbconvert2_cb($matches){ + return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[3]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '"); +} + +function smarty_mod_cap_ucfirst_cb($matches){ + return stripslashes($matches[1]).ucfirst(stripslashes($matches[2])); +} + +function smarty_mod_cap_ucfirst2_cb($matches){ + return stripslashes($matches[1]).ucfirst(stripslashes($matches[3])); +}