From 655a2d9301f4336613ef227a30734bd0bb4d6a88 Mon Sep 17 00:00:00 2001 From: "Uwe.Tews@googlemail.com" Date: Thu, 3 Oct 2013 09:16:27 +0000 Subject: [PATCH] - bugfix loops using modifier capitalize did eat up memory (issue 159) --- change_log.txt | 3 ++ libs/plugins/modifier.capitalize.php | 44 +++++++++++++++++++++------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/change_log.txt b/change_log.txt index 5c067595..0200a394 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,7 @@ ===== 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/libs/plugins/modifier.capitalize.php b/libs/plugins/modifier.capitalize.php index b3036b86..985c54b4 100644 --- a/libs/plugins/modifier.capitalize.php +++ b/libs/plugins/modifier.capitalize.php @@ -30,36 +30,58 @@ 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; } - + // lowercase first if ($lc_rest) { $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])); }