1: <?php
2: /**
3: * Smarty plugin
4: *
5: * @package Smarty
6: * @subpackage PluginsModifier
7: */
8: /**
9: * Smarty escape modifier plugin
10: * Type: modifier
11: * Name: escape
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_loaded_1 = false;
28: static $is_loaded_2 = 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(
49: array(
50: '%%%SMARTY_START%%%',
51: '%%%SMARTY_END%%%'
52: ),
53: array(
54: '&',
55: ';'
56: ),
57: $string
58: );
59: return $string;
60: }
61: }
62: // no break
63: case 'htmlall':
64: if (Smarty::$_MBSTRING) {
65: // mb_convert_encoding ignores htmlspecialchars()
66: if ($_double_encode) {
67: // php >=5.3.2 - go native
68: $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
69: } else {
70: if ($double_encode) {
71: // php <5.2.3 - only handle double encoding
72: $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
73: } else {
74: // php <5.2.3 - prevent double encoding
75: $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
76: $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
77: $string =
78: str_replace(
79: array(
80: '%%%SMARTY_START%%%',
81: '%%%SMARTY_END%%%'
82: ),
83: array(
84: '&',
85: ';'
86: ),
87: $string
88: );
89: return $string;
90: }
91: }
92: // htmlentities() won't convert everything, so use mb_convert_encoding
93: return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
94: }
95: // no MBString fallback
96: if ($_double_encode) {
97: return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
98: } else {
99: if ($double_encode) {
100: return htmlentities($string, ENT_QUOTES, $char_set);
101: } else {
102: $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
103: $string = htmlentities($string, ENT_QUOTES, $char_set);
104: $string = str_replace(
105: array(
106: '%%%SMARTY_START%%%',
107: '%%%SMARTY_END%%%'
108: ),
109: array(
110: '&',
111: ';'
112: ),
113: $string
114: );
115: return $string;
116: }
117: }
118: // no break
119: case 'url':
120: return rawurlencode($string);
121: case 'urlpathinfo':
122: return str_replace('%2F', '/', rawurlencode($string));
123: case 'quotes':
124: // escape unescaped single quotes
125: return preg_replace("%(?<!\\\\)'%", "\\'", $string);
126: case 'hex':
127: // escape every byte into hex
128: // Note that the UTF-8 encoded character รค will be represented as %c3%a4
129: $return = '';
130: $_length = strlen($string);
131: for ($x = 0; $x < $_length; $x++) {
132: $return .= '%' . bin2hex($string[ $x ]);
133: }
134: return $return;
135: case 'hexentity':
136: $return = '';
137: if (Smarty::$_MBSTRING) {
138: if (!$is_loaded_1) {
139: if (!is_callable('smarty_mb_to_unicode')) {
140: include_once SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php';
141: }
142: $is_loaded_1 = true;
143: }
144: $return = '';
145: foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
146: $return .= '&#x' . strtoupper(dechex($unicode)) . ';';
147: }
148: return $return;
149: }
150: // no MBString fallback
151: $_length = strlen($string);
152: for ($x = 0; $x < $_length; $x++) {
153: $return .= '&#x' . bin2hex($string[ $x ]) . ';';
154: }
155: return $return;
156: case 'decentity':
157: $return = '';
158: if (Smarty::$_MBSTRING) {
159: if (!$is_loaded_1) {
160: if (!is_callable('smarty_mb_to_unicode')) {
161: include_once SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php';
162: }
163: $is_loaded_1 = true;
164: }
165: $return = '';
166: foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
167: $return .= '&#' . $unicode . ';';
168: }
169: return $return;
170: }
171: // no MBString fallback
172: $_length = strlen($string);
173: for ($x = 0; $x < $_length; $x++) {
174: $return .= '&#' . ord($string[ $x ]) . ';';
175: }
176: return $return;
177: case 'javascript':
178: // escape quotes and backslashes, newlines, etc.
179: return strtr(
180: $string,
181: array(
182: '\\' => '\\\\',
183: "'" => "\\'",
184: '"' => '\\"',
185: "\r" => '\\r',
186: "\n" => '\\n',
187: '</' => '<\/',
188: // see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
189: '<!--' => '<\!--',
190: '<s' => '<\s',
191: '<S' => '<\S',
192: "`" => "\\\\`",
193: "\${" => "\\\\\\$\\{"
194: )
195: );
196: case 'mail':
197: if (Smarty::$_MBSTRING) {
198: if (!$is_loaded_2) {
199: if (!is_callable('smarty_mb_str_replace')) {
200: include_once SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php';
201: }
202: $is_loaded_2 = true;
203: }
204: return smarty_mb_str_replace(
205: array(
206: '@',
207: '.'
208: ),
209: array(
210: ' [AT] ',
211: ' [DOT] '
212: ),
213: $string
214: );
215: }
216: // no MBString fallback
217: return str_replace(
218: array(
219: '@',
220: '.'
221: ),
222: array(
223: ' [AT] ',
224: ' [DOT] '
225: ),
226: $string
227: );
228: case 'nonstd':
229: // escape non-standard chars, such as ms document quotes
230: $return = '';
231: if (Smarty::$_MBSTRING) {
232: if (!$is_loaded_1) {
233: if (!is_callable('smarty_mb_to_unicode')) {
234: include_once SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php';
235: }
236: $is_loaded_1 = true;
237: }
238: foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
239: if ($unicode >= 126) {
240: $return .= '&#' . $unicode . ';';
241: } else {
242: $return .= chr($unicode);
243: }
244: }
245: return $return;
246: }
247: $_length = strlen($string);
248: for ($_i = 0; $_i < $_length; $_i++) {
249: $_ord = ord(substr($string, $_i, 1));
250: // non-standard char, escape it
251: if ($_ord >= 126) {
252: $return .= '&#' . $_ord . ';';
253: } else {
254: $return .= substr($string, $_i, 1);
255: }
256: }
257: return $return;
258: default:
259: trigger_error("escape: unsupported type: $esc_type - returning unmodified string", E_USER_NOTICE);
260: return $string;
261: }
262: }
263: