modifier.escape.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * Smarty plugin
  4. *
  5. * @package Smarty
  6. * @subpackage PluginsModifier
  7. */
  8. /**
  9. * Smarty escape modifier plugin
  10. * Type: modifier<br>
  11. * Name: escape<br>
  12. * Purpose: escape string for output
  13. *
  14. * @link http://www.smarty.net/docs/en/language.modifier.escape
  15. * @author Monte Ohrt <monte at ohrt dot com>
  16. *
  17. * @param string $string input string
  18. * @param string $esc_type escape type
  19. * @param string $char_set character set, used for htmlspecialchars() or htmlentities()
  20. * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
  21. *
  22. * @return string escaped input string
  23. */
  24. function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
  25. {
  26. static $_double_encode = null;
  27. static $is_loaded1 = false;
  28. static $is_loaded2 = false;
  29. if ($_double_encode === null) {
  30. $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
  31. }
  32. if (!$char_set) {
  33. $char_set = Smarty::$_CHARSET;
  34. }
  35. switch ($esc_type) {
  36. case 'html':
  37. if ($_double_encode) {
  38. // php >=5.3.2 - go native
  39. return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
  40. } else {
  41. if ($double_encode) {
  42. // php <5.2.3 - only handle double encoding
  43. return htmlspecialchars($string, ENT_QUOTES, $char_set);
  44. } else {
  45. // php <5.2.3 - prevent double encoding
  46. $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
  47. $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
  48. $string = str_replace(array('%%%SMARTY_START%%%',
  49. '%%%SMARTY_END%%%'), array('&',
  50. ';'), $string);
  51. return $string;
  52. }
  53. }
  54. case 'htmlall':
  55. if (Smarty::$_MBSTRING) {
  56. // mb_convert_encoding ignores htmlspecialchars()
  57. if ($_double_encode) {
  58. // php >=5.3.2 - go native
  59. $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
  60. } else {
  61. if ($double_encode) {
  62. // php <5.2.3 - only handle double encoding
  63. $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
  64. } else {
  65. // php <5.2.3 - prevent double encoding
  66. $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
  67. $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
  68. $string =
  69. str_replace(array('%%%SMARTY_START%%%',
  70. '%%%SMARTY_END%%%'), array('&',
  71. ';'), $string);
  72. return $string;
  73. }
  74. }
  75. // htmlentities() won't convert everything, so use mb_convert_encoding
  76. return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
  77. }
  78. // no MBString fallback
  79. if ($_double_encode) {
  80. return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
  81. } else {
  82. if ($double_encode) {
  83. return htmlentities($string, ENT_QUOTES, $char_set);
  84. } else {
  85. $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
  86. $string = htmlentities($string, ENT_QUOTES, $char_set);
  87. $string = str_replace(array('%%%SMARTY_START%%%',
  88. '%%%SMARTY_END%%%'), array('&',
  89. ';'), $string);
  90. return $string;
  91. }
  92. }
  93. case 'url':
  94. return rawurlencode($string);
  95. case 'urlpathinfo':
  96. return str_replace('%2F', '/', rawurlencode($string));
  97. case 'quotes':
  98. // escape unescaped single quotes
  99. return preg_replace("%(?<!\\\\)'%", "\\'", $string);
  100. case 'hex':
  101. // escape every byte into hex
  102. // Note that the UTF-8 encoded character ä will be represented as %c3%a4
  103. $return = '';
  104. $_length = strlen($string);
  105. for ($x = 0; $x < $_length; $x ++) {
  106. $return .= '%' . bin2hex($string[ $x ]);
  107. }
  108. return $return;
  109. case 'hexentity':
  110. $return = '';
  111. if (Smarty::$_MBSTRING) {
  112. if (!$is_loaded1) {
  113. if (!is_callable('smarty_mb_to_unicode')) {
  114. require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
  115. $is_loaded1 = true;
  116. }
  117. }
  118. $return = '';
  119. foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
  120. $return .= '&#x' . strtoupper(dechex($unicode)) . ';';
  121. }
  122. return $return;
  123. }
  124. // no MBString fallback
  125. $_length = strlen($string);
  126. for ($x = 0; $x < $_length; $x ++) {
  127. $return .= '&#x' . bin2hex($string[ $x ]) . ';';
  128. }
  129. return $return;
  130. case 'decentity':
  131. $return = '';
  132. if (Smarty::$_MBSTRING) {
  133. if (!$is_loaded1) {
  134. if (!is_callable('smarty_mb_to_unicode')) {
  135. require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
  136. }
  137. $is_loaded1 = true;
  138. }
  139. $return = '';
  140. foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
  141. $return .= '&#' . $unicode . ';';
  142. }
  143. return $return;
  144. }
  145. // no MBString fallback
  146. $_length = strlen($string);
  147. for ($x = 0; $x < $_length; $x ++) {
  148. $return .= '&#' . ord($string[ $x ]) . ';';
  149. }
  150. return $return;
  151. case 'javascript':
  152. // escape quotes and backslashes, newlines, etc.
  153. return strtr($string, array('\\' => '\\\\',
  154. "'" => "\\'",
  155. '"' => '\\"',
  156. "\r" => '\\r',
  157. "\n" => '\\n',
  158. '</' => '<\/'));
  159. case 'mail':
  160. if (Smarty::$_MBSTRING) {
  161. if (!is_callable('smarty_mb_str_replace')) {
  162. require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
  163. }
  164. return smarty_mb_str_replace(array('@',
  165. '.'), array(' [AT] ',
  166. ' [DOT] '), $string);
  167. }
  168. // no MBString fallback
  169. return str_replace(array('@',
  170. '.'), array(' [AT] ',
  171. ' [DOT] '), $string);
  172. case 'nonstd':
  173. // escape non-standard chars, such as ms document quotes
  174. $return = '';
  175. if (Smarty::$_MBSTRING) {
  176. if (!$is_loaded1) {
  177. if (!is_callable('smarty_mb_to_unicode')) {
  178. require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
  179. }
  180. $is_loaded1 = true;
  181. }
  182. foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
  183. if ($unicode >= 126) {
  184. $return .= '&#' . $unicode . ';';
  185. } else {
  186. $return .= chr($unicode);
  187. }
  188. }
  189. return $return;
  190. }
  191. $_length = strlen($string);
  192. for ($_i = 0; $_i < $_length; $_i ++) {
  193. $_ord = ord(substr($string, $_i, 1));
  194. // non-standard char, escape it
  195. if ($_ord >= 126) {
  196. $return .= '&#' . $_ord . ';';
  197. } else {
  198. $return .= substr($string, $_i, 1);
  199. }
  200. }
  201. return $return;
  202. default:
  203. return $string;
  204. }
  205. }