42 * @since 2.0.0 |
49 * @since 2.0.0 |
43 */ |
50 */ |
44 $allowedposttags = array( |
51 $allowedposttags = array( |
45 'address' => array(), |
52 'address' => array(), |
46 'a' => array( |
53 'a' => array( |
47 'class' => array (), |
54 'class' => true, |
48 'href' => array (), |
55 'href' => true, |
49 'id' => array (), |
56 'id' => true, |
50 'title' => array (), |
57 'title' => true, |
51 'rel' => array (), |
58 'rel' => true, |
52 'rev' => array (), |
59 'rev' => true, |
53 'name' => array (), |
60 'name' => true, |
54 'target' => array()), |
61 'target' => true, |
|
62 ), |
55 'abbr' => array( |
63 'abbr' => array( |
56 'class' => array (), |
64 'class' => true, |
57 'title' => array ()), |
65 'title' => true, |
|
66 ), |
58 'acronym' => array( |
67 'acronym' => array( |
59 'title' => array ()), |
68 'title' => true, |
|
69 ), |
|
70 'article' => array( |
|
71 'align' => true, |
|
72 'class' => true, |
|
73 'dir' => true, |
|
74 'lang' => true, |
|
75 'style' => true, |
|
76 'xml:lang' => true, |
|
77 ), |
|
78 'aside' => array( |
|
79 'align' => true, |
|
80 'class' => true, |
|
81 'dir' => true, |
|
82 'lang' => true, |
|
83 'style' => true, |
|
84 'xml:lang' => true, |
|
85 ), |
60 'b' => array(), |
86 'b' => array(), |
61 'big' => array(), |
87 'big' => array(), |
62 'blockquote' => array( |
88 'blockquote' => array( |
63 'id' => array (), |
89 'id' => true, |
64 'cite' => array (), |
90 'cite' => true, |
65 'class' => array(), |
91 'class' => true, |
66 'lang' => array(), |
92 'lang' => true, |
67 'xml:lang' => array()), |
93 'xml:lang' => true, |
|
94 ), |
68 'br' => array ( |
95 'br' => array ( |
69 'class' => array ()), |
96 'class' => true, |
|
97 ), |
70 'button' => array( |
98 'button' => array( |
71 'disabled' => array (), |
99 'disabled' => true, |
72 'name' => array (), |
100 'name' => true, |
73 'type' => array (), |
101 'type' => true, |
74 'value' => array ()), |
102 'value' => true, |
|
103 ), |
75 'caption' => array( |
104 'caption' => array( |
76 'align' => array (), |
105 'align' => true, |
77 'class' => array ()), |
106 'class' => true, |
|
107 ), |
78 'cite' => array ( |
108 'cite' => array ( |
79 'class' => array(), |
109 'class' => true, |
80 'dir' => array(), |
110 'dir' => true, |
81 'lang' => array(), |
111 'lang' => true, |
82 'title' => array ()), |
112 'title' => true, |
|
113 ), |
83 'code' => array ( |
114 'code' => array ( |
84 'style' => array()), |
115 'style' => true, |
|
116 ), |
85 'col' => array( |
117 'col' => array( |
86 'align' => array (), |
118 'align' => true, |
87 'char' => array (), |
119 'char' => true, |
88 'charoff' => array (), |
120 'charoff' => true, |
89 'span' => array (), |
121 'span' => true, |
90 'dir' => array(), |
122 'dir' => true, |
91 'style' => array (), |
123 'style' => true, |
92 'valign' => array (), |
124 'valign' => true, |
93 'width' => array ()), |
125 'width' => true, |
|
126 ), |
94 'del' => array( |
127 'del' => array( |
95 'datetime' => array ()), |
128 'datetime' => true, |
|
129 ), |
96 'dd' => array(), |
130 'dd' => array(), |
|
131 'details' => array( |
|
132 'align' => true, |
|
133 'class' => true, |
|
134 'dir' => true, |
|
135 'lang' => true, |
|
136 'open' => true, |
|
137 'style' => true, |
|
138 'xml:lang' => true, |
|
139 ), |
97 'div' => array( |
140 'div' => array( |
98 'align' => array (), |
141 'align' => true, |
99 'class' => array (), |
142 'class' => true, |
100 'dir' => array (), |
143 'dir' => true, |
101 'lang' => array(), |
144 'lang' => true, |
102 'style' => array (), |
145 'style' => true, |
103 'xml:lang' => array()), |
146 'xml:lang' => true, |
|
147 ), |
104 'dl' => array(), |
148 'dl' => array(), |
105 'dt' => array(), |
149 'dt' => array(), |
106 'em' => array(), |
150 'em' => array(), |
107 'fieldset' => array(), |
151 'fieldset' => array(), |
|
152 'figure' => array( |
|
153 'align' => true, |
|
154 'class' => true, |
|
155 'dir' => true, |
|
156 'lang' => true, |
|
157 'style' => true, |
|
158 'xml:lang' => true, |
|
159 ), |
|
160 'figcaption' => array( |
|
161 'align' => true, |
|
162 'class' => true, |
|
163 'dir' => true, |
|
164 'lang' => true, |
|
165 'style' => true, |
|
166 'xml:lang' => true, |
|
167 ), |
108 'font' => array( |
168 'font' => array( |
109 'color' => array (), |
169 'color' => true, |
110 'face' => array (), |
170 'face' => true, |
111 'size' => array ()), |
171 'size' => true, |
|
172 ), |
|
173 'footer' => array( |
|
174 'align' => true, |
|
175 'class' => true, |
|
176 'dir' => true, |
|
177 'lang' => true, |
|
178 'style' => true, |
|
179 'xml:lang' => true, |
|
180 ), |
112 'form' => array( |
181 'form' => array( |
113 'action' => array (), |
182 'action' => true, |
114 'accept' => array (), |
183 'accept' => true, |
115 'accept-charset' => array (), |
184 'accept-charset' => true, |
116 'enctype' => array (), |
185 'enctype' => true, |
117 'method' => array (), |
186 'method' => true, |
118 'name' => array (), |
187 'name' => true, |
119 'target' => array ()), |
188 'target' => true, |
|
189 ), |
120 'h1' => array( |
190 'h1' => array( |
121 'align' => array (), |
191 'align' => true, |
122 'class' => array (), |
192 'class' => true, |
123 'id' => array (), |
193 'id' => true, |
124 'style' => array ()), |
194 'style' => true, |
|
195 ), |
125 'h2' => array ( |
196 'h2' => array ( |
126 'align' => array (), |
197 'align' => true, |
127 'class' => array (), |
198 'class' => true, |
128 'id' => array (), |
199 'id' => true, |
129 'style' => array ()), |
200 'style' => true, |
|
201 ), |
130 'h3' => array ( |
202 'h3' => array ( |
131 'align' => array (), |
203 'align' => true, |
132 'class' => array (), |
204 'class' => true, |
133 'id' => array (), |
205 'id' => true, |
134 'style' => array ()), |
206 'style' => true, |
|
207 ), |
135 'h4' => array ( |
208 'h4' => array ( |
136 'align' => array (), |
209 'align' => true, |
137 'class' => array (), |
210 'class' => true, |
138 'id' => array (), |
211 'id' => true, |
139 'style' => array ()), |
212 'style' => true, |
|
213 ), |
140 'h5' => array ( |
214 'h5' => array ( |
141 'align' => array (), |
215 'align' => true, |
142 'class' => array (), |
216 'class' => true, |
143 'id' => array (), |
217 'id' => true, |
144 'style' => array ()), |
218 'style' => true, |
|
219 ), |
145 'h6' => array ( |
220 'h6' => array ( |
146 'align' => array (), |
221 'align' => true, |
147 'class' => array (), |
222 'class' => true, |
148 'id' => array (), |
223 'id' => true, |
149 'style' => array ()), |
224 'style' => true, |
|
225 ), |
|
226 'header' => array( |
|
227 'align' => true, |
|
228 'class' => true, |
|
229 'dir' => true, |
|
230 'lang' => true, |
|
231 'style' => true, |
|
232 'xml:lang' => true, |
|
233 ), |
|
234 'hgroup' => array( |
|
235 'align' => true, |
|
236 'class' => true, |
|
237 'dir' => true, |
|
238 'lang' => true, |
|
239 'style' => true, |
|
240 'xml:lang' => true, |
|
241 ), |
150 'hr' => array ( |
242 'hr' => array ( |
151 'align' => array (), |
243 'align' => true, |
152 'class' => array (), |
244 'class' => true, |
153 'noshade' => array (), |
245 'noshade' => true, |
154 'size' => array (), |
246 'size' => true, |
155 'width' => array ()), |
247 'width' => true, |
|
248 ), |
156 'i' => array(), |
249 'i' => array(), |
157 'img' => array( |
250 'img' => array( |
158 'alt' => array (), |
251 'alt' => true, |
159 'align' => array (), |
252 'align' => true, |
160 'border' => array (), |
253 'border' => true, |
161 'class' => array (), |
254 'class' => true, |
162 'height' => array (), |
255 'height' => true, |
163 'hspace' => array (), |
256 'hspace' => true, |
164 'longdesc' => array (), |
257 'longdesc' => true, |
165 'vspace' => array (), |
258 'vspace' => true, |
166 'src' => array (), |
259 'src' => true, |
167 'style' => array (), |
260 'style' => true, |
168 'width' => array ()), |
261 'width' => true, |
|
262 ), |
169 'ins' => array( |
263 'ins' => array( |
170 'datetime' => array (), |
264 'datetime' => true, |
171 'cite' => array ()), |
265 'cite' => true, |
|
266 ), |
172 'kbd' => array(), |
267 'kbd' => array(), |
173 'label' => array( |
268 'label' => array( |
174 'for' => array ()), |
269 'for' => true, |
|
270 ), |
175 'legend' => array( |
271 'legend' => array( |
176 'align' => array ()), |
272 'align' => true, |
|
273 ), |
177 'li' => array ( |
274 'li' => array ( |
178 'align' => array (), |
275 'align' => true, |
179 'class' => array ()), |
276 'class' => true, |
|
277 ), |
|
278 'menu' => array ( |
|
279 'class' => true, |
|
280 'style' => true, |
|
281 'type' => true, |
|
282 ), |
|
283 'nav' => array( |
|
284 'align' => true, |
|
285 'class' => true, |
|
286 'dir' => true, |
|
287 'lang' => true, |
|
288 'style' => true, |
|
289 'xml:lang' => true, |
|
290 ), |
180 'p' => array( |
291 'p' => array( |
181 'class' => array (), |
292 'class' => true, |
182 'align' => array (), |
293 'align' => true, |
183 'dir' => array(), |
294 'dir' => true, |
184 'lang' => array(), |
295 'lang' => true, |
185 'style' => array (), |
296 'style' => true, |
186 'xml:lang' => array()), |
297 'xml:lang' => true, |
|
298 ), |
187 'pre' => array( |
299 'pre' => array( |
188 'style' => array(), |
300 'style' => true, |
189 'width' => array ()), |
301 'width' => true, |
|
302 ), |
190 'q' => array( |
303 'q' => array( |
191 'cite' => array ()), |
304 'cite' => true, |
|
305 ), |
192 's' => array(), |
306 's' => array(), |
193 'span' => array ( |
307 'span' => array ( |
194 'class' => array (), |
308 'class' => true, |
195 'dir' => array (), |
309 'dir' => true, |
196 'align' => array (), |
310 'align' => true, |
197 'lang' => array (), |
311 'lang' => true, |
198 'style' => array (), |
312 'style' => true, |
199 'title' => array (), |
313 'title' => true, |
200 'xml:lang' => array()), |
314 'xml:lang' => true, |
|
315 ), |
|
316 'section' => array( |
|
317 'align' => true, |
|
318 'class' => true, |
|
319 'dir' => true, |
|
320 'lang' => true, |
|
321 'style' => true, |
|
322 'xml:lang' => true, |
|
323 ), |
201 'strike' => array(), |
324 'strike' => array(), |
202 'strong' => array(), |
325 'strong' => array(), |
203 'sub' => array(), |
326 'sub' => array(), |
|
327 'summary' => array( |
|
328 'align' => true, |
|
329 'class' => true, |
|
330 'dir' => true, |
|
331 'lang' => true, |
|
332 'style' => true, |
|
333 'xml:lang' => true, |
|
334 ), |
204 'sup' => array(), |
335 'sup' => array(), |
205 'table' => array( |
336 'table' => array( |
206 'align' => array (), |
337 'align' => true, |
207 'bgcolor' => array (), |
338 'bgcolor' => true, |
208 'border' => array (), |
339 'border' => true, |
209 'cellpadding' => array (), |
340 'cellpadding' => true, |
210 'cellspacing' => array (), |
341 'cellspacing' => true, |
211 'class' => array (), |
342 'class' => true, |
212 'dir' => array(), |
343 'dir' => true, |
213 'id' => array(), |
344 'id' => true, |
214 'rules' => array (), |
345 'rules' => true, |
215 'style' => array (), |
346 'style' => true, |
216 'summary' => array (), |
347 'summary' => true, |
217 'width' => array ()), |
348 'width' => true, |
|
349 ), |
218 'tbody' => array( |
350 'tbody' => array( |
219 'align' => array (), |
351 'align' => true, |
220 'char' => array (), |
352 'char' => true, |
221 'charoff' => array (), |
353 'charoff' => true, |
222 'valign' => array ()), |
354 'valign' => true, |
|
355 ), |
223 'td' => array( |
356 'td' => array( |
224 'abbr' => array (), |
357 'abbr' => true, |
225 'align' => array (), |
358 'align' => true, |
226 'axis' => array (), |
359 'axis' => true, |
227 'bgcolor' => array (), |
360 'bgcolor' => true, |
228 'char' => array (), |
361 'char' => true, |
229 'charoff' => array (), |
362 'charoff' => true, |
230 'class' => array (), |
363 'class' => true, |
231 'colspan' => array (), |
364 'colspan' => true, |
232 'dir' => array(), |
365 'dir' => true, |
233 'headers' => array (), |
366 'headers' => true, |
234 'height' => array (), |
367 'height' => true, |
235 'nowrap' => array (), |
368 'nowrap' => true, |
236 'rowspan' => array (), |
369 'rowspan' => true, |
237 'scope' => array (), |
370 'scope' => true, |
238 'style' => array (), |
371 'style' => true, |
239 'valign' => array (), |
372 'valign' => true, |
240 'width' => array ()), |
373 'width' => true, |
|
374 ), |
241 'textarea' => array( |
375 'textarea' => array( |
242 'cols' => array (), |
376 'cols' => true, |
243 'rows' => array (), |
377 'rows' => true, |
244 'disabled' => array (), |
378 'disabled' => true, |
245 'name' => array (), |
379 'name' => true, |
246 'readonly' => array ()), |
380 'readonly' => true, |
|
381 ), |
247 'tfoot' => array( |
382 'tfoot' => array( |
248 'align' => array (), |
383 'align' => true, |
249 'char' => array (), |
384 'char' => true, |
250 'class' => array (), |
385 'class' => true, |
251 'charoff' => array (), |
386 'charoff' => true, |
252 'valign' => array ()), |
387 'valign' => true, |
|
388 ), |
253 'th' => array( |
389 'th' => array( |
254 'abbr' => array (), |
390 'abbr' => true, |
255 'align' => array (), |
391 'align' => true, |
256 'axis' => array (), |
392 'axis' => true, |
257 'bgcolor' => array (), |
393 'bgcolor' => true, |
258 'char' => array (), |
394 'char' => true, |
259 'charoff' => array (), |
395 'charoff' => true, |
260 'class' => array (), |
396 'class' => true, |
261 'colspan' => array (), |
397 'colspan' => true, |
262 'headers' => array (), |
398 'headers' => true, |
263 'height' => array (), |
399 'height' => true, |
264 'nowrap' => array (), |
400 'nowrap' => true, |
265 'rowspan' => array (), |
401 'rowspan' => true, |
266 'scope' => array (), |
402 'scope' => true, |
267 'valign' => array (), |
403 'valign' => true, |
268 'width' => array ()), |
404 'width' => true, |
|
405 ), |
269 'thead' => array( |
406 'thead' => array( |
270 'align' => array (), |
407 'align' => true, |
271 'char' => array (), |
408 'char' => true, |
272 'charoff' => array (), |
409 'charoff' => true, |
273 'class' => array (), |
410 'class' => true, |
274 'valign' => array ()), |
411 'valign' => true, |
|
412 ), |
275 'title' => array(), |
413 'title' => array(), |
276 'tr' => array( |
414 'tr' => array( |
277 'align' => array (), |
415 'align' => true, |
278 'bgcolor' => array (), |
416 'bgcolor' => true, |
279 'char' => array (), |
417 'char' => true, |
280 'charoff' => array (), |
418 'charoff' => true, |
281 'class' => array (), |
419 'class' => true, |
282 'style' => array (), |
420 'style' => true, |
283 'valign' => array ()), |
421 'valign' => true, |
|
422 ), |
284 'tt' => array(), |
423 'tt' => array(), |
285 'u' => array(), |
424 'u' => array(), |
286 'ul' => array ( |
425 'ul' => array ( |
287 'class' => array (), |
426 'class' => true, |
288 'style' => array (), |
427 'style' => true, |
289 'type' => array ()), |
428 'type' => true, |
|
429 ), |
290 'ol' => array ( |
430 'ol' => array ( |
291 'class' => array (), |
431 'class' => true, |
292 'start' => array (), |
432 'start' => true, |
293 'style' => array (), |
433 'style' => true, |
294 'type' => array ()), |
434 'type' => true, |
295 'var' => array ()); |
435 ), |
|
436 'var' => array(), |
|
437 ); |
296 |
438 |
297 /** |
439 /** |
298 * Kses allowed HTML elements. |
440 * Kses allowed HTML elements. |
299 * |
441 * |
300 * @global array $allowedtags |
442 * @global array $allowedtags |
301 * @since 1.0.0 |
443 * @since 1.0.0 |
302 */ |
444 */ |
303 $allowedtags = array( |
445 $allowedtags = array( |
304 'a' => array( |
446 'a' => array( |
305 'href' => array (), |
447 'href' => true, |
306 'title' => array ()), |
448 'title' => true, |
|
449 ), |
307 'abbr' => array( |
450 'abbr' => array( |
308 'title' => array ()), |
451 'title' => true, |
|
452 ), |
309 'acronym' => array( |
453 'acronym' => array( |
310 'title' => array ()), |
454 'title' => true, |
|
455 ), |
311 'b' => array(), |
456 'b' => array(), |
312 'blockquote' => array( |
457 'blockquote' => array( |
313 'cite' => array ()), |
458 'cite' => true, |
|
459 ), |
314 // 'br' => array(), |
460 // 'br' => array(), |
315 'cite' => array (), |
461 'cite' => array(), |
316 'code' => array(), |
462 'code' => array(), |
317 'del' => array( |
463 'del' => array( |
318 'datetime' => array ()), |
464 'datetime' => true, |
|
465 ), |
319 // 'dd' => array(), |
466 // 'dd' => array(), |
320 // 'dl' => array(), |
467 // 'dl' => array(), |
321 // 'dt' => array(), |
468 // 'dt' => array(), |
322 'em' => array (), 'i' => array (), |
469 'em' => array (), 'i' => array (), |
323 // 'ins' => array('datetime' => array(), 'cite' => array()), |
470 // 'ins' => array('datetime' => array(), 'cite' => array()), |
324 // 'li' => array(), |
471 // 'li' => array(), |
325 // 'ol' => array(), |
472 // 'ol' => array(), |
326 // 'p' => array(), |
473 // 'p' => array(), |
327 'q' => array( |
474 'q' => array( |
328 'cite' => array ()), |
475 'cite' => true, |
|
476 ), |
329 'strike' => array(), |
477 'strike' => array(), |
330 'strong' => array(), |
478 'strong' => array(), |
331 // 'sub' => array(), |
479 // 'sub' => array(), |
332 // 'sup' => array(), |
480 // 'sup' => array(), |
333 // 'u' => array(), |
481 // 'u' => array(), |
334 // 'ul' => array(), |
482 // 'ul' => array(), |
335 ); |
483 ); |
|
484 |
|
485 $allowedentitynames = array( |
|
486 'nbsp', 'iexcl', 'cent', 'pound', 'curren', 'yen', |
|
487 'brvbar', 'sect', 'uml', 'copy', 'ordf', 'laquo', |
|
488 'not', 'shy', 'reg', 'macr', 'deg', 'plusmn', |
|
489 'acute', 'micro', 'para', 'middot', 'cedil', 'ordm', |
|
490 'raquo', 'iquest', 'Agrave', 'Aacute', 'Acirc', 'Atilde', |
|
491 'Auml', 'Aring', 'AElig', 'Ccedil', 'Egrave', 'Eacute', |
|
492 'Ecirc', 'Euml', 'Igrave', 'Iacute', 'Icirc', 'Iuml', |
|
493 'ETH', 'Ntilde', 'Ograve', 'Oacute', 'Ocirc', 'Otilde', |
|
494 'Ouml', 'times', 'Oslash', 'Ugrave', 'Uacute', 'Ucirc', |
|
495 'Uuml', 'Yacute', 'THORN', 'szlig', 'agrave', 'aacute', |
|
496 'acirc', 'atilde', 'auml', 'aring', 'aelig', 'ccedil', |
|
497 'egrave', 'eacute', 'ecirc', 'euml', 'igrave', 'iacute', |
|
498 'icirc', 'iuml', 'eth', 'ntilde', 'ograve', 'oacute', |
|
499 'ocirc', 'otilde', 'ouml', 'divide', 'oslash', 'ugrave', |
|
500 'uacute', 'ucirc', 'uuml', 'yacute', 'thorn', 'yuml', |
|
501 'quot', 'amp', 'lt', 'gt', 'apos', 'OElig', |
|
502 'oelig', 'Scaron', 'scaron', 'Yuml', 'circ', 'tilde', |
|
503 'ensp', 'emsp', 'thinsp', 'zwnj', 'zwj', 'lrm', |
|
504 'rlm', 'ndash', 'mdash', 'lsquo', 'rsquo', 'sbquo', |
|
505 'ldquo', 'rdquo', 'bdquo', 'dagger', 'Dagger', 'permil', |
|
506 'lsaquo', 'rsaquo', 'euro', 'fnof', 'Alpha', 'Beta', |
|
507 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', |
|
508 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', |
|
509 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon', |
|
510 'Phi', 'Chi', 'Psi', 'Omega', 'alpha', 'beta', |
|
511 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', |
|
512 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', |
|
513 'omicron', 'pi', 'rho', 'sigmaf', 'sigma', 'tau', |
|
514 'upsilon', 'phi', 'chi', 'psi', 'omega', 'thetasym', |
|
515 'upsih', 'piv', 'bull', 'hellip', 'prime', 'Prime', |
|
516 'oline', 'frasl', 'weierp', 'image', 'real', 'trade', |
|
517 'alefsym', 'larr', 'uarr', 'rarr', 'darr', 'harr', |
|
518 'crarr', 'lArr', 'uArr', 'rArr', 'dArr', 'hArr', |
|
519 'forall', 'part', 'exist', 'empty', 'nabla', 'isin', |
|
520 'notin', 'ni', 'prod', 'sum', 'minus', 'lowast', |
|
521 'radic', 'prop', 'infin', 'ang', 'and', 'or', |
|
522 'cap', 'cup', 'int', 'sim', 'cong', 'asymp', |
|
523 'ne', 'equiv', 'le', 'ge', 'sub', 'sup', |
|
524 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp', |
|
525 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang', |
|
526 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams', |
|
527 ); |
336 } |
528 } |
337 |
529 |
338 /** |
530 /** |
339 * Filters content and keeps only allowable HTML elements. |
531 * Filters content and keeps only allowable HTML elements. |
340 * |
532 * |
342 * names and attribute values plus only sane HTML entities will occur in |
534 * names and attribute values plus only sane HTML entities will occur in |
343 * $string. You have to remove any slashes from PHP's magic quotes before you |
535 * $string. You have to remove any slashes from PHP's magic quotes before you |
344 * call this function. |
536 * call this function. |
345 * |
537 * |
346 * The default allowed protocols are 'http', 'https', 'ftp', 'mailto', 'news', |
538 * The default allowed protocols are 'http', 'https', 'ftp', 'mailto', 'news', |
347 * 'irc', 'gopher', 'nntp', 'feed', and finally 'telnet. This covers all common |
539 * 'irc', 'gopher', 'nntp', 'feed', 'telnet, 'mms', 'rtsp' and 'svn'. This |
348 * link protocols, except for 'javascript' which should not be allowed for |
540 * covers all common link protocols, except for 'javascript' which should not |
349 * untrusted users. |
541 * be allowed for untrusted users. |
350 * |
542 * |
351 * @since 1.0.0 |
543 * @since 1.0.0 |
352 * |
544 * |
353 * @param string $string Content to filter through kses |
545 * @param string $string Content to filter through kses |
354 * @param array $allowed_html List of allowed HTML elements |
546 * @param array $allowed_html List of allowed HTML elements |
355 * @param array $allowed_protocols Optional. Allowed protocol in links. |
547 * @param array $allowed_protocols Optional. Allowed protocol in links. |
356 * @return string Filtered content with only allowed HTML elements |
548 * @return string Filtered content with only allowed HTML elements |
357 */ |
549 */ |
358 function wp_kses($string, $allowed_html, $allowed_protocols = array ('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet')) { |
550 function wp_kses($string, $allowed_html, $allowed_protocols = array ()) { |
|
551 if ( empty( $allowed_protocols ) ) |
|
552 $allowed_protocols = wp_allowed_protocols(); |
359 $string = wp_kses_no_null($string); |
553 $string = wp_kses_no_null($string); |
360 $string = wp_kses_js_entities($string); |
554 $string = wp_kses_js_entities($string); |
361 $string = wp_kses_normalize_entities($string); |
555 $string = wp_kses_normalize_entities($string); |
362 $allowed_html_fixed = wp_kses_array_lc($allowed_html); |
556 $allowed_html_fixed = wp_kses_array_lc($allowed_html); |
363 $string = wp_kses_hook($string, $allowed_html_fixed, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook |
557 $string = wp_kses_hook($string, $allowed_html_fixed, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook |
493 */ |
697 */ |
494 function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { |
698 function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { |
495 # Is there a closing XHTML slash at the end of the attributes? |
699 # Is there a closing XHTML slash at the end of the attributes? |
496 |
700 |
497 $xhtml_slash = ''; |
701 $xhtml_slash = ''; |
498 if (preg_match('%\s/\s*$%', $attr)) |
702 if (preg_match('%\s*/\s*$%', $attr)) |
499 $xhtml_slash = ' /'; |
703 $xhtml_slash = ' /'; |
500 |
704 |
501 # Are any attributes allowed at all for this element? |
705 # Are any attributes allowed at all for this element? |
502 |
706 if ( ! isset($allowed_html[strtolower($element)]) || count($allowed_html[strtolower($element)]) == 0 ) |
503 if (@ count($allowed_html[strtolower($element)]) == 0) |
|
504 return "<$element$xhtml_slash>"; |
707 return "<$element$xhtml_slash>"; |
505 |
708 |
506 # Split it |
709 # Split it |
507 |
|
508 $attrarr = wp_kses_hair($attr, $allowed_protocols); |
710 $attrarr = wp_kses_hair($attr, $allowed_protocols); |
509 |
711 |
510 # Go through $attrarr, and save the allowed attributes for this element |
712 # Go through $attrarr, and save the allowed attributes for this element |
511 # in $attr2 |
713 # in $attr2 |
512 |
|
513 $attr2 = ''; |
714 $attr2 = ''; |
514 |
715 |
|
716 $allowed_attr = $allowed_html[strtolower($element)]; |
515 foreach ($attrarr as $arreach) { |
717 foreach ($attrarr as $arreach) { |
516 if (!@ isset ($allowed_html[strtolower($element)][strtolower($arreach['name'])])) |
718 if ( ! isset( $allowed_attr[strtolower($arreach['name'])] ) ) |
517 continue; # the attribute is not allowed |
719 continue; # the attribute is not allowed |
518 |
720 |
519 $current = $allowed_html[strtolower($element)][strtolower($arreach['name'])]; |
721 $current = $allowed_attr[strtolower($arreach['name'])]; |
520 if ($current == '') |
722 if ( $current == '' ) |
521 continue; # the attribute is not allowed |
723 continue; # the attribute is not allowed |
522 |
724 |
523 if (!is_array($current)) |
725 if ( strtolower( $arreach['name'] ) == 'style' ) { |
|
726 $orig_value = $arreach['value']; |
|
727 $value = safecss_filter_attr( $orig_value ); |
|
728 |
|
729 if ( empty( $value ) ) |
|
730 continue; |
|
731 |
|
732 $arreach['value'] = $value; |
|
733 $arreach['whole'] = str_replace( $orig_value, $value, $arreach['whole'] ); |
|
734 } |
|
735 |
|
736 if ( ! is_array($current) ) { |
524 $attr2 .= ' '.$arreach['whole']; |
737 $attr2 .= ' '.$arreach['whole']; |
525 # there are no checks |
738 # there are no checks |
526 |
739 |
527 else { |
740 } else { |
528 # there are some checks |
741 # there are some checks |
529 $ok = true; |
742 $ok = true; |
530 foreach ($current as $currkey => $currval) |
743 foreach ($current as $currkey => $currval) { |
531 if (!wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval)) { |
744 if ( ! wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval) ) { |
532 $ok = false; |
745 $ok = false; |
533 break; |
746 break; |
534 } |
747 } |
535 |
|
536 if ( $arreach['name'] == 'style' ) { |
|
537 $orig_value = $arreach['value']; |
|
538 |
|
539 $value = safecss_filter_attr($orig_value); |
|
540 |
|
541 if ( empty($value) ) |
|
542 continue; |
|
543 |
|
544 $arreach['value'] = $value; |
|
545 |
|
546 $arreach['whole'] = str_replace($orig_value, $value, $arreach['whole']); |
|
547 } |
748 } |
548 |
749 |
549 if ($ok) |
750 if ( $ok ) |
550 $attr2 .= ' '.$arreach['whole']; # it passed them |
751 $attr2 .= ' '.$arreach['whole']; # it passed them |
551 } # if !is_array($current) |
752 } # if !is_array($current) |
552 } # foreach |
753 } # foreach |
553 |
754 |
554 # Remove any "<" or ">" characters |
755 # Remove any "<" or ">" characters |
555 |
|
556 $attr2 = preg_replace('/[<>]/', '', $attr2); |
756 $attr2 = preg_replace('/[<>]/', '', $attr2); |
557 |
757 |
558 return "<$element$attr2$xhtml_slash>"; |
758 return "<$element$attr2$xhtml_slash>"; |
559 } |
759 } |
560 |
760 |
609 |
809 |
610 if (preg_match('/^\s+/', $attr)) # valueless |
810 if (preg_match('/^\s+/', $attr)) # valueless |
611 { |
811 { |
612 $working = 1; |
812 $working = 1; |
613 $mode = 0; |
813 $mode = 0; |
614 if(FALSE === array_key_exists($attrname, $attrarr)) { |
814 if(false === array_key_exists($attrname, $attrarr)) { |
615 $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); |
815 $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); |
616 } |
816 } |
617 $attr = preg_replace('/^\s+/', '', $attr); |
817 $attr = preg_replace('/^\s+/', '', $attr); |
618 } |
818 } |
619 |
819 |
620 break; |
820 break; |
621 |
821 |
622 case 2 : # attribute value, a URL after href= for instance |
822 case 2 : # attribute value, a URL after href= for instance |
623 |
823 |
624 if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) |
824 if (preg_match('%^"([^"]*)"(\s+|/?$)%', $attr, $match)) |
625 # "value" |
825 # "value" |
626 { |
826 { |
627 $thisval = $match[1]; |
827 $thisval = $match[1]; |
628 if ( in_array($attrname, $uris) ) |
828 if ( in_array(strtolower($attrname), $uris) ) |
629 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); |
829 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); |
630 |
830 |
631 if(FALSE === array_key_exists($attrname, $attrarr)) { |
831 if(false === array_key_exists($attrname, $attrarr)) { |
632 $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); |
832 $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); |
633 } |
833 } |
634 $working = 1; |
834 $working = 1; |
635 $mode = 0; |
835 $mode = 0; |
636 $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); |
836 $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); |
637 break; |
837 break; |
638 } |
838 } |
639 |
839 |
640 if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) |
840 if (preg_match("%^'([^']*)'(\s+|/?$)%", $attr, $match)) |
641 # 'value' |
841 # 'value' |
642 { |
842 { |
643 $thisval = $match[1]; |
843 $thisval = $match[1]; |
644 if ( in_array($attrname, $uris) ) |
844 if ( in_array(strtolower($attrname), $uris) ) |
645 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); |
845 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); |
646 |
846 |
647 if(FALSE === array_key_exists($attrname, $attrarr)) { |
847 if(false === array_key_exists($attrname, $attrarr)) { |
648 $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n'); |
848 $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n'); |
649 } |
849 } |
650 $working = 1; |
850 $working = 1; |
651 $mode = 0; |
851 $mode = 0; |
652 $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); |
852 $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); |
653 break; |
853 break; |
654 } |
854 } |
655 |
855 |
656 if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) |
856 if (preg_match("%^([^\s\"']+)(\s+|/?$)%", $attr, $match)) |
657 # value |
857 # value |
658 { |
858 { |
659 $thisval = $match[1]; |
859 $thisval = $match[1]; |
660 if ( in_array($attrname, $uris) ) |
860 if ( in_array(strtolower($attrname), $uris) ) |
661 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); |
861 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); |
662 |
862 |
663 if(FALSE === array_key_exists($attrname, $attrarr)) { |
863 if(false === array_key_exists($attrname, $attrarr)) { |
664 $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); |
864 $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); |
665 } |
865 } |
666 # We add quotes to conform to W3C's HTML spec. |
866 # We add quotes to conform to W3C's HTML spec. |
667 $working = 1; |
867 $working = 1; |
668 $mode = 0; |
868 $mode = 0; |
877 * |
1080 * |
878 * @param string $string Content to check for bad protocols |
1081 * @param string $string Content to check for bad protocols |
879 * @param string $allowed_protocols Allowed protocols |
1082 * @param string $allowed_protocols Allowed protocols |
880 * @return string Sanitized content |
1083 * @return string Sanitized content |
881 */ |
1084 */ |
882 function wp_kses_bad_protocol_once($string, $allowed_protocols) { |
1085 function wp_kses_bad_protocol_once($string, $allowed_protocols, $count = 1 ) { |
883 global $_kses_allowed_protocols; |
1086 $string2 = preg_split( '/:|�*58;|�*3a;/i', $string, 2 ); |
884 $_kses_allowed_protocols = $allowed_protocols; |
1087 if ( isset($string2[1]) && ! preg_match('%/\?%', $string2[0]) ) { |
885 |
1088 $string = trim( $string2[1] ); |
886 $string2 = preg_split('/:|:|:/i', $string, 2); |
1089 $protocol = wp_kses_bad_protocol_once2( $string2[0], $allowed_protocols ); |
887 if ( isset($string2[1]) && !preg_match('%/\?%', $string2[0]) ) |
1090 if ( 'feed:' == $protocol ) { |
888 $string = wp_kses_bad_protocol_once2($string2[0]) . trim($string2[1]); |
1091 if ( $count > 2 ) |
889 else |
1092 return ''; |
890 $string = preg_replace_callback('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|:|&#[Xx]3[Aa];)\s*/', 'wp_kses_bad_protocol_once2', $string); |
1093 $string = wp_kses_bad_protocol_once( $string, $allowed_protocols, ++$count ); |
|
1094 if ( empty( $string ) ) |
|
1095 return $string; |
|
1096 } |
|
1097 $string = $protocol . $string; |
|
1098 } |
891 |
1099 |
892 return $string; |
1100 return $string; |
893 } |
1101 } |
894 |
1102 |
895 /** |
1103 /** |
896 * Callback for wp_kses_bad_protocol_once() regular expression. |
1104 * Callback for wp_kses_bad_protocol_once() regular expression. |
897 * |
1105 * |
898 * This function processes URL protocols, checks to see if they're in the |
1106 * This function processes URL protocols, checks to see if they're in the |
899 * white-list or not, and returns different data depending on the answer. |
1107 * whitelist or not, and returns different data depending on the answer. |
900 * |
1108 * |
901 * @access private |
1109 * @access private |
902 * @since 1.0.0 |
1110 * @since 1.0.0 |
903 * |
1111 * |
904 * @param mixed $matches string or preg_replace_callback() matches array to check for bad protocols |
1112 * @param string $string URI scheme to check against the whitelist |
|
1113 * @param string $allowed_protocols Allowed protocols |
905 * @return string Sanitized content |
1114 * @return string Sanitized content |
906 */ |
1115 */ |
907 function wp_kses_bad_protocol_once2($matches) { |
1116 function wp_kses_bad_protocol_once2( $string, $allowed_protocols ) { |
908 global $_kses_allowed_protocols; |
|
909 |
|
910 if ( is_array($matches) ) { |
|
911 if ( ! isset($matches[1]) || empty($matches[1]) ) |
|
912 return ''; |
|
913 |
|
914 $string = $matches[1]; |
|
915 } else { |
|
916 $string = $matches; |
|
917 } |
|
918 |
|
919 $string2 = wp_kses_decode_entities($string); |
1117 $string2 = wp_kses_decode_entities($string); |
920 $string2 = preg_replace('/\s/', '', $string2); |
1118 $string2 = preg_replace('/\s/', '', $string2); |
921 $string2 = wp_kses_no_null($string2); |
1119 $string2 = wp_kses_no_null($string2); |
922 $string2 = strtolower($string2); |
1120 $string2 = strtolower($string2); |
923 |
1121 |
924 $allowed = false; |
1122 $allowed = false; |
925 foreach ( (array) $_kses_allowed_protocols as $one_protocol) |
1123 foreach ( (array) $allowed_protocols as $one_protocol ) |
926 if (strtolower($one_protocol) == $string2) { |
1124 if ( strtolower($one_protocol) == $string2 ) { |
927 $allowed = true; |
1125 $allowed = true; |
928 break; |
1126 break; |
929 } |
1127 } |
930 |
1128 |
931 if ($allowed) |
1129 if ($allowed) |
950 |
1148 |
951 $string = str_replace('&', '&', $string); |
1149 $string = str_replace('&', '&', $string); |
952 |
1150 |
953 # Change back the allowed entities in our entity whitelist |
1151 # Change back the allowed entities in our entity whitelist |
954 |
1152 |
955 $string = preg_replace('/&([A-Za-z][A-Za-z0-9]{0,19});/', '&\\1;', $string); |
1153 $string = preg_replace_callback('/&([A-Za-z]{2,8});/', 'wp_kses_named_entities', $string); |
956 $string = preg_replace_callback('/&#0*([0-9]{1,5});/', 'wp_kses_normalize_entities2', $string); |
1154 $string = preg_replace_callback('/&#(0*[0-9]{1,7});/', 'wp_kses_normalize_entities2', $string); |
957 $string = preg_replace_callback('/&#([Xx])0*(([0-9A-Fa-f]{2}){1,2});/', 'wp_kses_normalize_entities3', $string); |
1155 $string = preg_replace_callback('/&#[Xx](0*[0-9A-Fa-f]{1,6});/', 'wp_kses_normalize_entities3', $string); |
958 |
1156 |
959 return $string; |
1157 return $string; |
960 } |
1158 } |
961 |
1159 |
962 /** |
1160 /** |
963 * Callback for wp_kses_normalize_entities() regular expression. |
1161 * Callback for wp_kses_normalize_entities() regular expression. |
964 * |
1162 * |
965 * This function helps wp_kses_normalize_entities() to only accept 16 bit values |
1163 * This function only accepts valid named entity references, which are finite, |
966 * and nothing more for &#number; entities. |
1164 * case-sensitive, and highly scrutinized by HTML and XML validators. |
967 * |
1165 * |
968 * @access private |
1166 * @since 3.0.0 |
969 * @since 1.0.0 |
|
970 * |
1167 * |
971 * @param array $matches preg_replace_callback() matches array |
1168 * @param array $matches preg_replace_callback() matches array |
972 * @return string Correctly encoded entity |
1169 * @return string Correctly encoded entity |
973 */ |
1170 */ |
|
1171 function wp_kses_named_entities($matches) { |
|
1172 global $allowedentitynames; |
|
1173 |
|
1174 if ( empty($matches[1]) ) |
|
1175 return ''; |
|
1176 |
|
1177 $i = $matches[1]; |
|
1178 return ( ( ! in_array($i, $allowedentitynames) ) ? "&$i;" : "&$i;" ); |
|
1179 } |
|
1180 |
|
1181 /** |
|
1182 * Callback for wp_kses_normalize_entities() regular expression. |
|
1183 * |
|
1184 * This function helps wp_kses_normalize_entities() to only accept 16-bit values |
|
1185 * and nothing more for &#number; entities. |
|
1186 * |
|
1187 * @access private |
|
1188 * @since 1.0.0 |
|
1189 * |
|
1190 * @param array $matches preg_replace_callback() matches array |
|
1191 * @return string Correctly encoded entity |
|
1192 */ |
974 function wp_kses_normalize_entities2($matches) { |
1193 function wp_kses_normalize_entities2($matches) { |
975 if ( ! isset($matches[1]) || empty($matches[1]) ) |
1194 if ( empty($matches[1]) ) |
976 return ''; |
1195 return ''; |
977 |
1196 |
978 $i = $matches[1]; |
1197 $i = $matches[1]; |
979 return ( ( ! valid_unicode($i) ) || ($i > 65535) ? "&#$i;" : "&#$i;" ); |
1198 if (valid_unicode($i)) { |
|
1199 $i = str_pad(ltrim($i,'0'), 3, '0', STR_PAD_LEFT); |
|
1200 $i = "&#$i;"; |
|
1201 } else { |
|
1202 $i = "&#$i;"; |
|
1203 } |
|
1204 |
|
1205 return $i; |
980 } |
1206 } |
981 |
1207 |
982 /** |
1208 /** |
983 * Callback for wp_kses_normalize_entities() for regular expression. |
1209 * Callback for wp_kses_normalize_entities() for regular expression. |
984 * |
1210 * |
1194 } |
1428 } |
1195 |
1429 |
1196 add_action('init', 'kses_init'); |
1430 add_action('init', 'kses_init'); |
1197 add_action('set_current_user', 'kses_init'); |
1431 add_action('set_current_user', 'kses_init'); |
1198 |
1432 |
|
1433 /** |
|
1434 * Inline CSS filter |
|
1435 * |
|
1436 * @since 2.8.1 |
|
1437 */ |
1199 function safecss_filter_attr( $css, $deprecated = '' ) { |
1438 function safecss_filter_attr( $css, $deprecated = '' ) { |
|
1439 if ( !empty( $deprecated ) ) |
|
1440 _deprecated_argument( __FUNCTION__, '2.8.1' ); // Never implemented |
|
1441 |
1200 $css = wp_kses_no_null($css); |
1442 $css = wp_kses_no_null($css); |
1201 $css = str_replace(array("\n","\r","\t"), '', $css); |
1443 $css = str_replace(array("\n","\r","\t"), '', $css); |
1202 |
1444 |
1203 if ( preg_match( '%[\\(&]|/\*%', $css ) ) // remove any inline css containing \ ( & or comments |
1445 if ( preg_match( '%[\\(&=}]|/\*%', $css ) ) // remove any inline css containing \ ( & } = or comments |
1204 return ''; |
1446 return ''; |
1205 |
1447 |
1206 $css_array = split( ';', trim( $css ) ); |
1448 $css_array = explode( ';', trim( $css ) ); |
1207 $allowed_attr = apply_filters( 'safe_style_css', array( 'text-align', 'margin', 'color', 'float', |
1449 $allowed_attr = apply_filters( 'safe_style_css', array( 'text-align', 'margin', 'color', 'float', |
1208 'border', 'background', 'background-color', 'border-bottom', 'border-bottom-color', |
1450 'border', 'background', 'background-color', 'border-bottom', 'border-bottom-color', |
1209 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-left', |
1451 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-left', |
1210 'border-left-color', 'border-left-style', 'border-left-width', 'border-right', 'border-right-color', |
1452 'border-left-color', 'border-left-style', 'border-left-width', 'border-right', 'border-right-color', |
1211 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', |
1453 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', |