htmlawed_function.php
1 <?php
2
/**
3  * htmLawed 1.1.9.5, 6 July 2011
4  *
5  * www.bioinformatics.org/phplabware/internal_utilities/htmLawed
6  * htmLawed PHP5 OOP is ~2% slower and uses ~2% more memory than the non-OOP version of htmLawed
7  * 
8  * htmLawed does not check or correct the character encoding of the input it receives
9  * 
10  * @param    string    the input text to be processed
11  * @param    array    instructs htmLawed on how to tackle certain tasks, when not specified, or not set as an array (e.g., $config = 1), default actions
12  * @param    string    the $S argument can be used to disallow an otherwise legal attribute for an element, or to restrict the attribute's values
13  * @return  string  the output of htmLawed is a text string containing the processed input. 
14  */
15
function htmlawed_function($t, array $C NULL$S NULL) {
16     if ( ! empty(
$C['valid_xhtml'])) {
17         
$C['elements'] = empty($C['elements']) ? '*-center-dir-font-isindex-menu-s-strike-u' $C['elements'];
18         
$C['make_tag_strict'] = isset($C['make_tag_strict']) ? $C['make_tag_strict'] : 2;
19         
$C['xml:lang'] = isset($C['xml:lang']) ? $C['xml:lang'] : 2;
20     }
21     
// config eles
22     // 86/deprecated+embed+ruby
23     
$e = array('a'=>1'abbr'=>1'acronym'=>1'address'=>1'applet'=>1'area'=>1'b'=>1'bdo'=>1'big'=>1'blockquote'=>1'br'=>1'button'=>1'caption'=>1'center'=>1'cite'=>1'code'=>1'col'=>1'colgroup'=>1'dd'=>1'del'=>1'dfn'=>1'dir'=>1'div'=>1'dl'=>1'dt'=>1'em'=>1'embed'=>1'fieldset'=>1'font'=>1'form'=>1'h1'=>1'h2'=>1'h3'=>1'h4'=>1'h5'=>1'h6'=>1'hr'=>1'i'=>1'iframe'=>1'img'=>1'input'=>1'ins'=>1'isindex'=>1'kbd'=>1'label'=>1'legend'=>1'li'=>1'map'=>1'menu'=>1'noscript'=>1'object'=>1'ol'=>1'optgroup'=>1'option'=>1'p'=>1'param'=>1'pre'=>1'q'=>1'rb'=>1'rbc'=>1'rp'=>1'rt'=>1'rtc'=>1'ruby'=>1's'=>1'samp'=>1'script'=>1'select'=>1'small'=>1'span'=>1'strike'=>1'strong'=>1'sub'=>1'sup'=>1'table'=>1'tbody'=>1'td'=>1'textarea'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1'tt'=>1'u'=>1'ul'=>1'var'=>1); 
24     
// With $C['safe'] = 1, the default set will exclude applet, embed, iframe, object and script
25     
if ( ! empty($C['safe'])) {
26         unset(
$e['applet'], $e['embed'], $e['iframe'], $e['object'], $e['script']);
27     }
28     
$x = ! empty($C['elements']) ? str_replace(array("\n""\r""\t"' '), ''$C['elements']) : '*';
29     if (
$x == '-*') {
30         
$e = array();
31     } elseif (
strpos($x'*') === FALSE) {
32         
$e array_flip(explode(','$x));
33     } else {
34         if (isset(
$x[1])) {
35             
preg_match_all('`(?:^|-|\+)[^\-+]+?(?=-|\+|$)`'$x$mPREG_SET_ORDER);
36             for (
$i count($m); --$i >= 0;) {
37                 
$m[$i] = $m[$i][0];
38             }
39             foreach (
$m as $v) {
40                 if (
$v[0] == '+') {
41                     
$e[substr($v1)] = 1;
42                 }
43                 if (
$v[0] == '-' && isset($e[($v substr($v1))]) && ! in_array('+'$v$m)) {
44                     unset(
$e[$v]);
45                 }
46             }
47         }
48     }
49     
$C['elements'] =& $e;
50     
// config attrs
51     
$x = ! empty($C['deny_attribute']) ? str_replace(array("\n""\r""\t"' '), ''$C['deny_attribute']) : '';
52     
$x array_flip((isset($x[0]) && $x[0] == '*') ? explode('-'$x) : explode(','$x. ( ! empty($C['safe']) ? ',on*' '')));
53     if (isset(
$x['on*'])) {
54         unset(
$x['on*']);
55         
$x += array('onblur'=>1'onchange'=>1'onclick'=>1'ondblclick'=>1'onfocus'=>1'onkeydown'=>1'onkeypress'=>1'onkeyup'=>1'onmousedown'=>1'onmousemove'=>1'onmouseout'=>1'onmouseover'=>1'onmouseup'=>1'onreset'=>1'onselect'=>1'onsubmit'=>1);
56     }
57     
$C['deny_attribute'] = $x;
58     
// config URL
59     
$x = (isset($C['schemes'][2]) && strpos($C['schemes'], ':')) ? strtolower($C['schemes']) : 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https';
60     
$C['schemes'] = array();
61     foreach (
explode(';'str_replace(array(' '"\t""\r""\n"), ''$x)) as $v) {
62         
$x $x2 NULL
63         list(
$x$x2) = explode(':'$v2);
64         if (
$x2) {
65             
$C['schemes'][$x] = array_flip(explode(','$x2));
66         }
67     }
68     if ( ! isset(
$C['schemes']['*'])) {
69         
$C['schemes']['*'] = array('file'=>1'http'=>1'https'=>1,);
70     }
71     if ( ! empty(
$C['safe']) && empty($C['schemes']['style'])) {
72         
$C['schemes']['style'] = array('!'=>1);
73     }
74     
$C['abs_url'] = isset($C['abs_url']) ? $C['abs_url'] : 0;
75     if ( ! isset(
$C['base_url']) or ! preg_match('`^[a-zA-Z\d.+\-]+://[^/]+/(.+?/)?$`'$C['base_url'])) {
76         
$C['base_url'] = $C['abs_url'] = 0;
77     }
78     
// config rest
79     
$C['and_mark'] = empty($C['and_mark']) ? 1;
80     
$C['anti_link_spam'] = (isset($C['anti_link_spam']) && is_array($C['anti_link_spam']) && count($C['anti_link_spam']) == && (empty($C['anti_link_spam'][0]) or hl_regex($C['anti_link_spam'][0])) && (empty($C['anti_link_spam'][1]) or hl_regex($C['anti_link_spam'][1]))) ? $C['anti_link_spam'] : 0;
81     
$C['anti_mail_spam'] = isset($C['anti_mail_spam']) ? $C['anti_mail_spam'] : 0;
82     
$C['balance'] = isset($C['balance']) ? (bool)$C['balance'] : 1;
83     
$C['cdata'] = isset($C['cdata']) ? $C['cdata'] : (empty($C['safe']) ? 0);
84     
$C['clean_ms_char'] = empty($C['clean_ms_char']) ? $C['clean_ms_char'];
85     
$C['comment'] = isset($C['comment']) ? $C['comment'] : (empty($C['safe']) ? 0);
86     
$C['css_expression'] = empty($C['css_expression']) ? 1;
87     
$C['hexdec_entity'] = isset($C['hexdec_entity']) ? $C['hexdec_entity'] : 1;
88     
$C['hook'] = ( ! empty($C['hook']) && function_exists($C['hook'])) ? $C['hook'] : 0;
89     
$C['hook_tag'] = ( ! empty($C['hook_tag']) && function_exists($C['hook_tag'])) ? $C['hook_tag'] : 0;
90     
$C['keep_bad'] = isset($C['keep_bad']) ? $C['keep_bad'] : 6;
91     
$C['lc_std_val'] = isset($C['lc_std_val']) ? (bool)$C['lc_std_val'] : 1;
92     
$C['make_tag_strict'] = isset($C['make_tag_strict']) ? $C['make_tag_strict'] : 1;
93     
$C['named_entity'] = isset($C['named_entity']) ? (bool)$C['named_entity'] : 1;
94     
$C['no_deprecated_attr'] = isset($C['no_deprecated_attr']) ? $C['no_deprecated_attr'] : 1;
95     
$C['parent'] = isset($C['parent'][0]) ? strtolower($C['parent']) : 'body';
96     
$C['show_setting'] = ! empty($C['show_setting']) ? $C['show_setting'] : 0;
97     
$C['style_pass'] = empty($C['style_pass']) ? 1;
98     
$C['tidy'] = empty($C['tidy']) ? $C['tidy'];
99     
$C['unique_ids'] = isset($C['unique_ids']) ? $C['unique_ids'] : 1;
100     
$C['xml:lang'] = isset($C['xml:lang']) ? $C['xml:lang'] : 0;
101
102     if (isset(
$GLOBALS['C'])) {
103         
$reC $GLOBALS['C'];
104     }
105     
$GLOBALS['C'] = $C;
106     
$S is_array($S) ? $S hl_spec($S);
107     if (isset(
$GLOBALS['S'])) {
108         
$reS $GLOBALS['S'];
109     }
110     
$GLOBALS['S'] = $S;
111
112     
$t preg_replace('`[\x00-\x08\x0b-\x0c\x0e-\x1f]`'''$t);
113     if (
$C['clean_ms_char']) {
114         
$x = array("\x7f"=>''"\x80"=>'&#8364;'"\x81"=>''"\x83"=>'&#402;'"\x85"=>'&#8230;'"\x86"=>'&#8224;'"\x87"=>'&#8225;'"\x88"=>'&#710;'"\x89"=>'&#8240;'"\x8a"=>'&#352;'"\x8b"=>'&#8249;'"\x8c"=>'&#338;'"\x8d"=>''"\x8e"=>'&#381;'"\x8f"=>''"\x90"=>''"\x95"=>'&#8226;'"\x96"=>'&#8211;'"\x97"=>'&#8212;'"\x98"=>'&#732;'"\x99"=>'&#8482;'"\x9a"=>'&#353;'"\x9b"=>'&#8250;'"\x9c"=>'&#339;'"\x9d"=>''"\x9e"=>'&#382;'"\x9f"=>'&#376;');
115         
$x $x + ($C['clean_ms_char'] == ? array("\x82"=>'&#8218;'"\x84"=>'&#8222;'"\x91"=>'&#8216;'"\x92"=>'&#8217;'"\x93"=>'&#8220;'"\x94"=>'&#8221;') : array("\x82"=>'\''"\x84"=>'"'"\x91"=>'\''"\x92"=>'\''"\x93"=>'"'"\x94"=>'"'));
116         
$t strtr($t$x);
117     }
118     if (
$C['cdata'] or $C['comment']) {
119         
$t preg_replace_callback('`<!(?:(?:--.*?--)|(?:\[CDATA\[.*?\]\]))>`sm''hl_cmtcd'$t);
120     }
121     
$t preg_replace_callback('`&amp;([A-Za-z][A-Za-z0-9]{1,30}|#(?:[0-9]{1,8}|[Xx][0-9A-Fa-f]{1,7}));`''hl_ent'str_replace('&''&amp;'$t));
122     if (
$C['unique_ids'] && ! isset($GLOBALS['hl_Ids'])) {
123         
$GLOBALS['hl_Ids'] = array();
124     }
125     if (
$C['hook']) {
126         
$t $C['hook']($t$C$S);
127     }
128     if (
$C['show_setting'] && preg_match('`^[a-z][a-z0-9_]*$`i'$C['show_setting'])) {
129         
$GLOBALS[$C['show_setting']] = array('config'=>$C'spec'=>$S'time'=>microtime());
130     }
131     
// main
132     
$t preg_replace_callback('`<(?:(?:\s|$)|(?:[^>]*(?:>|$)))|>`m''hl_tag'$t);
133     
$t $C['balance'] ? hl_bal($t$C['keep_bad'], $C['parent']) : $t;
134     
$t = (($C['cdata'] or $C['comment']) && strpos($t"\x01") !== FALSE) ? str_replace(array("\x01""\x02""\x03""\x04""\x05"), array('''''&''<''>'), $t) : $t;
135     unset(
$C$e);
136     if (isset(
$reC)) {
137         
$GLOBALS['C'] = $reC;
138     }
139     if (isset(
$reS)) {
140         
$GLOBALS['S'] = $reS;
141     }
142     return 
$t;
143 }
144
145
/**
146  * Checking attribute values against $S
147  */
148
function hl_attrval($t$p) {
149     
// check attr val against $S
150     
$o 1
151     
$l strlen($t);
152     foreach (
$p as $k => $v) {
153         switch (
$k) {
154             case 
'maxlen':
155                 if (
$l $v) {
156                     
$o 0;
157                 }
158                 break; 
159             
160             case 
'minlen'
161                 if (
$l $v) {
162                     
$o 0;
163                 }
164                 break; 
165             
166             case 
'maxval'
167                 if ((float)(
$t) > $v) {
168                     
$o 0;
169                 }
170                 break; 
171             
172             case 
'minval'
173                 if ((float)(
$t) < $v) {
174                     
$o 0;
175                 }
176                 break; 
177             
178             case 
'match'
179                 if ( ! 
preg_match($v$t)) {
180                     
$o 0;
181                 }
182                 break; 
183             
184             case 
'nomatch'
185                 if (
preg_match($v$t)) {
186                     
$o 0;
187                 }
188                 break; 
189             
190             case 
'oneof':
191                 
$m 0;
192                 foreach (
explode('|'$v) as $n) {
193                     if (
$t == $n) {
194                         
$m 1
195                         break;
196                     }
197                 }
198                 
$o $m;
199                 break; 
200             
201             case 
'noneof':
202                 
$m 1;
203                 foreach (
explode('|'$v) as $n) {
204                     if (
$t == $n) {
205                         
$m 0
206                         break;
207                     }
208                 }
209                 
$o $m;
210                 break; 
211             
212             default:
213                 break;
214         }
215         if ( ! 
$o) {
216             break;
217         }
218     }
219     return (
$o $t : (isset($p['default']) ? $p['default'] : 0));
220 }
221
222
/**
223  * Tag balancing
224  */
225
function hl_bal($t$do 1$in 'div') {
226     
// balance tags
227     // by content
228     
$cB = array('blockquote'=>1'form'=>1'map'=>1'noscript'=>1); // Block
229     
$cE = array('area'=>1'br'=>1'col'=>1'embed'=>1'hr'=>1'img'=>1'input'=>1'isindex'=>1'param'=>1); // Empty
230     
$cF = array('button'=>1'del'=>1'div'=>1'dd'=>1'fieldset'=>1'iframe'=>1'ins'=>1'li'=>1'noscript'=>1'object'=>1'td'=>1'th'=>1); // Flow; later context-wise dynamic move of ins & del to $cI
231     
$cI = array('a'=>1'abbr'=>1'acronym'=>1'address'=>1'b'=>1'bdo'=>1'big'=>1'caption'=>1'cite'=>1'code'=>1'dfn'=>1'dt'=>1'em'=>1'font'=>1'h1'=>1'h2'=>1'h3'=>1'h4'=>1'h5'=>1'h6'=>1'i'=>1'kbd'=>1'label'=>1'legend'=>1'p'=>1'pre'=>1'q'=>1'rb'=>1'rt'=>1's'=>1'samp'=>1'small'=>1'span'=>1'strike'=>1'strong'=>1'sub'=>1'sup'=>1'tt'=>1'u'=>1'var'=>1); // Inline
232     
$cN = array('a'=>array('a'=>1), 'button'=>array('a'=>1'button'=>1'fieldset'=>1'form'=>1'iframe'=>1'input'=>1'label'=>1'select'=>1'textarea'=>1), 'fieldset'=>array('fieldset'=>1), 'form'=>array('form'=>1), 'label'=>array('label'=>1), 'noscript'=>array('script'=>1), 'pre'=>array('big'=>1'font'=>1'img'=>1'object'=>1'script'=>1'small'=>1'sub'=>1'sup'=>1), 'rb'=>array('ruby'=>1), 'rt'=>array('ruby'=>1)); // Illegal
233     
$cN2 array_keys($cN);
234     
$cR = array('blockquote'=>1'dir'=>1'dl'=>1'form'=>1'map'=>1'menu'=>1'noscript'=>1'ol'=>1'optgroup'=>1'rbc'=>1'rtc'=>1'ruby'=>1'select'=>1'table'=>1'tbody'=>1'tfoot'=>1'thead'=>1'tr'=>1'ul'=>1);
235     
$cS = array('colgroup'=>array('col'=>1), 'dir'=>array('li'=>1), 'dl'=>array('dd'=>1'dt'=>1), 'menu'=>array('li'=>1), 'ol'=>array('li'=>1), 'optgroup'=>array('option'=>1), 'option'=>array('#pcdata'=>1), 'rbc'=>array('rb'=>1), 'rp'=>array('#pcdata'=>1), 'rtc'=>array('rt'=>1), 'ruby'=>array('rb'=>1'rbc'=>1'rp'=>1'rt'=>1'rtc'=>1), 'select'=>array('optgroup'=>1'option'=>1), 'script'=>array('#pcdata'=>1), 'table'=>array('caption'=>1'col'=>1'colgroup'=>1'tfoot'=>1'tbody'=>1'tr'=>1'thead'=>1), 'tbody'=>array('tr'=>1), 'tfoot'=>array('tr'=>1), 'textarea'=>array('#pcdata'=>1), 'thead'=>array('tr'=>1), 'tr'=>array('td'=>1'th'=>1), 'ul'=>array('li'=>1)); // Specific - immediate parent-child
236     
$cO = array('address'=>array('p'=>1), 'applet'=>array('param'=>1), 'blockquote'=>array('script'=>1), 'fieldset'=>array('legend'=>1'#pcdata'=>1), 'form'=>array('script'=>1), 'map'=>array('area'=>1), 'object'=>array('param'=>1'embed'=>1)); // Other
237     
$cT = array('colgroup'=>1'dd'=>1'dt'=>1'li'=>1'option'=>1'p'=>1'td'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1); // Omitable closing
238     // block/inline type; ins & del both type; #pcdata: text
239     
$eB = array('address'=>1'blockquote'=>1'center'=>1'del'=>1'dir'=>1'dl'=>1'div'=>1'fieldset'=>1'form'=>1'ins'=>1'h1'=>1'h2'=>1'h3'=>1'h4'=>1'h5'=>1'h6'=>1'hr'=>1'isindex'=>1'menu'=>1'noscript'=>1'ol'=>1'p'=>1'pre'=>1'table'=>1'ul'=>1);
240     
$eI = array('#pcdata'=>1'a'=>1'abbr'=>1'acronym'=>1'applet'=>1'b'=>1'bdo'=>1'big'=>1'br'=>1'button'=>1'cite'=>1'code'=>1'del'=>1'dfn'=>1'em'=>1'embed'=>1'font'=>1'i'=>1'iframe'=>1'img'=>1'input'=>1'ins'=>1'kbd'=>1'label'=>1'map'=>1'object'=>1'q'=>1'ruby'=>1's'=>1'samp'=>1'select'=>1'script'=>1'small'=>1'span'=>1'strike'=>1'strong'=>1'sub'=>1'sup'=>1'textarea'=>1'tt'=>1'u'=>1'var'=>1);
241     
$eN = array('a'=>1'big'=>1'button'=>1'fieldset'=>1'font'=>1'form'=>1'iframe'=>1'img'=>1'input'=>1'label'=>1'object'=>1'ruby'=>1'script'=>1'select'=>1'small'=>1'sub'=>1'sup'=>1'textarea'=>1); // Exclude from specific ele; $cN values
242     
$eO = array('area'=>1'caption'=>1'col'=>1'colgroup'=>1'dd'=>1'dt'=>1'legend'=>1'li'=>1'optgroup'=>1'option'=>1'param'=>1'rb'=>1'rbc'=>1'rp'=>1'rt'=>1'rtc'=>1'script'=>1'tbody'=>1'td'=>1'tfoot'=>1'thead'=>1'th'=>1'tr'=>1); // Missing in $eB & $eI
243     
$eF $eB $eI;
244
245     
// $in sets allowed child
246     
$in = ((isset($eF[$in]) && $in != '#pcdata') or isset($eO[$in])) ? $in 'div';
247     if (isset(
$cE[$in])) {
248         return ( ! 
$do '' str_replace(array('<''>'), array('&lt;''&gt;'), $t));
249     }
250     if (isset(
$cS[$in])) {
251         
$inOk $cS[$in];
252     } elseif (isset(
$cI[$in])) {
253         
$inOk $eI
254         
$cI['del'] = 1
255         
$cI['ins'] = 1;
256     } elseif (isset(
$cF[$in])) {
257         
$inOk $eF
258         unset(
$cI['del'], $cI['ins']);
259     } elseif (isset(
$cB[$in])) {
260         
$inOk $eB
261         unset(
$cI['del'], $cI['ins']);
262     }
263     if (isset(
$cO[$in])) {
264         
$inOk $inOk $cO[$in];
265     }
266     if (isset(
$cN[$in])) {
267         
$inOk array_diff_assoc($inOk$cN[$in]);
268     }
269
270     
$t explode('<'$t);
271     
$ok $q = array(); // $q seq list of open non-empty ele
272     
ob_start();
273
274     for (
$i = -1$ci count($t); ++$i $ci;) {
275         
// allowed $ok in parent $p
276         
if ($ql count($q)) {
277             
$p array_pop($q);
278             
$q[] = $p;
279             if (isset(
$cS[$p])) {
280                 
$ok $cS[$p];
281             } elseif (isset(
$cI[$p])) {
282                 
$ok $eI
283                 
$cI['del'] = 1
284                 
$cI['ins'] = 1;
285             } elseif (isset(
$cF[$p])) {
286                 
$ok $eF
287                 unset(
$cI['del'], $cI['ins']);
288             } elseif (isset(
$cB[$p])) {
289                 
$ok $eB
290                 unset(
$cI['del'], $cI['ins']);
291             }
292             if (isset(
$cO[$p])) {
293                 
$ok $ok $cO[$p];
294             }
295             if (isset(
$cN[$p])) {
296                 
$ok array_diff_assoc($ok$cN[$p]);
297             }
298         } else {
299             
$ok $inOk
300             unset(
$cI['del'], $cI['ins']);
301         }
302         
// bad tags, & ele content
303         
if (isset($e) && ($do == or (isset($ok['#pcdata']) && ($do == or $do == 5)))) {
304             echo 
'&lt;'$s$e$a'&gt;';
305         }
306         if (isset(
$x[0])) {
307             if (
$do or isset($ok['#pcdata'])) {
308                 echo 
$x;
309             } elseif (
strpos($x"\x02\x04")) {
310                 foreach (
preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`'$x, -1PREG_SPLIT_DELIM_CAPTURE PREG_SPLIT_NO_EMPTY) as $v) {
311                     echo (
substr($v02) == "\x01\x02" $v : ($do preg_replace('`\S`'''$v) : ''));
312                 }
313             } elseif (
$do 4) {
314                 echo 
preg_replace('`\S`'''$x);
315             }
316         }
317         
// get markup
318         
if ( ! preg_match('`^(/?)([a-zA-Z1-6]+)([^>]*)>(.*)`sm'$t[$i], $r)) {
319             
$x $t[$i]; 
320             continue;
321         }
322         
$s NULL
323         
$e NULL
324         
$a NULL
325         
$x NULL
326         list(
$all$s$e$a$x) = $r;
327         
// close tag
328         
if ($s) {
329             if (isset(
$cE[$e]) or ! in_array($e$q)) {
330                 continue;
331             } 
// Empty/unopen
332             
if ($p == $e) {
333                 
array_pop($q); 
334                 echo 
'</'$e'>'
335                 unset(
$e); 
336                 continue;
337             } 
// Last open
338             
$add ''// Nesting - close open tags that need to be
339             
for ($j = -1$cj count($q); ++$j $cj;) {  
340                 if ((
$d array_pop($q)) == $e) {
341                     break;
342                 } else {
343                     
$add .= "</{$d}>";
344                 }
345             }
346             echo 
$add'</'$e'>'
347             unset(
$e); 
348             continue;
349         }
350         
// open tag
351         // $cB ele needs $eB ele as child
352         
if (isset($cB[$e]) && strlen(trim($x))) {
353             
$t[$i] = "{$e}{$a}>";
354             
array_splice($t$i+10'div>'$x); 
355             unset(
$e$x); 
356             ++
$ci
357             --
$i
358             continue;
359         }
360         if (((
$ql && isset($cB[$p])) or (isset($cB[$in]) && ! $ql)) && ! isset($eB[$e]) && ! isset($ok[$e])) {
361             
array_splice($t$i0'div>'); 
362             unset(
$e$x); 
363             ++
$ci
364             --
$i
365             continue;
366         }
367         
// if no open ele, $in = parent; mostly immediate parent-child relation should hold
368         
if ( ! $ql or ! isset($eN[$e]) or ! array_intersect($q$cN2)) {
369             if ( ! isset(
$ok[$e])) {
370                 if (
$ql && isset($cT[$p])) {
371                     echo 
'</'array_pop($q), '>'
372                     unset(
$e$x); 
373                     --
$i;
374                 }
375                 continue;
376             }
377             if( ! isset(
$cE[$e])) {
378                 
$q[] = $e;
379             }
380             echo 
'<'$e$a'>'
381             unset(
$e); 
382             continue;
383         }
384         
// specific parent-child
385         
if (isset($cS[$p][$e])) {
386             if ( ! isset(
$cE[$e])) {
387                 
$q[] = $e;
388             }
389             echo 
'<'$e$a'>'
390             unset(
$e); 
391             continue;
392         }
393         
// nesting
394         
$add '';
395         
$q2 = array();
396         for (
$k = -1$kc count($q); ++$k $kc;) {
397             
$d $q[$k];
398             
$ok2 = array();
399             if (isset(
$cS[$d])) {
400                 
$q2[] = $d
401                 continue;
402             }
403             
$ok2 = isset($cI[$d]) ? $eI $eF;
404             if (isset(
$cO[$d])) {
405                 
$ok2 $ok2 $cO[$d];
406             }
407             if (isset(
$cN[$d])) {
408                 
$ok2 array_diff_assoc($ok2$cN[$d]);
409             }
410             if ( ! isset(
$ok2[$e])) {
411                 if ( ! 
$k && ! isset($inOk[$e])) {
412                     continue 
2;
413                 }
414                 
$add "</{$d}>";
415                 for (;++
$k<$kc;) {
416                     
$add "</{$q[$k]}>{$add}";
417                 }
418                 break;
419             } else {
420                 
$q2[] = $d;
421             }
422         }
423         
$q $q2;
424         if ( ! isset(
$cE[$e])) {
425             
$q[] = $e;
426         }
427         echo 
$add'<'$e$a'>'
428         unset(
$e); 
429         continue;
430     }
431
432     
// end
433     
if ($ql count($q)) {
434         
$p array_pop($q);
435         
$q[] = $p;
436         if (isset(
$cS[$p])) {
437             
$ok $cS[$p];
438         } elseif (isset(
$cI[$p])) {
439             
$ok $eI
440             
$cI['del'] = 1
441             
$cI['ins'] = 1;
442         } elseif (isset(
$cF[$p])) {
443             
$ok $eF
444             unset(
$cI['del'], $cI['ins']);
445         } elseif (isset(
$cB[$p])) {
446             
$ok $eB
447             unset(
$cI['del'], $cI['ins']);
448         }
449         if (isset(
$cO[$p])) {
450             
$ok $ok $cO[$p];
451         }
452         if (isset(
$cN[$p])) {
453             
$ok array_diff_assoc($ok$cN[$p]);
454         }
455     } else {
456         
$ok $inOk
457         unset(
$cI['del'], $cI['ins']);
458     }
459     if (isset(
$e) && ($do == or (isset($ok['#pcdata']) && ($do == or $do == 5)))) {
460         echo 
'&lt;'$s$e$a'&gt;';
461     }
462     if (isset(
$x[0])) {
463         if (
strlen(trim($x)) && (($ql && isset($cB[$p])) or (isset($cB[$in]) && ! $ql))) {
464             echo 
'<div>'$x'</div>';
465         } elseif (
$do or isset($ok['#pcdata'])) {
466             echo 
$x;
467         } elseif (
strpos($x"\x02\x04")) {
468             foreach (
preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`'$x, -1PREG_SPLIT_DELIM_CAPTURE PREG_SPLIT_NO_EMPTY) as $v) {
469                 echo (
substr($v02) == "\x01\x02" $v : ($do preg_replace('`\S`'''$v) : ''));
470             }
471         } elseif (
$do 4) {
472             echo 
preg_replace('`\S`'''$x);
473         }
474     }
475     while ( ! empty(
$q) && ($e array_pop($q))) {
476         echo 
'</'$e'>';
477     }
478     
$o ob_get_contents();
479     
ob_end_clean();
480     return 
$o;
481 }
482
483
/**
484  * Handling CDATA sections and HTML comments
485  */
486
function hl_cmtcd($t) {
487     
// comment/CDATA sec handler
488     
$t $t[0];
489     global 
$C;
490     if ( ! (
$v $C[$n $t[3] == '-' 'comment' 'cdata'])) {
491         return 
$t;
492     }
493     if (
$v == 1) {
494         return 
'';
495     }
496     if (
$n == 'comment') {
497         if(
substr(($t preg_replace('`--+`''-'substr($t4, -3))), -1) != ' '){$t .= ' ';}
498     } else {
499         
$t substr($t1, -1);
500     }
501     
$t $v == str_replace(array('&''<''>'), array('&amp;''&lt;''&gt;'), $t) : $t;
502     return 
str_replace(array('&''<''>'), array("\x03""\x04""\x05"), ($n == 'comment' "\x01\x02\x04!--$t--\x05\x02\x01" "\x01\x01\x04$t\x05\x01\x01"));
503 }
504
505
/**
506  * Entity handling
507  */
508
function hl_ent($t){
509     
// entitity handler
510     
global $C;
511     
$t $t[1];
512     static 
$U = array('quot'=>1,'amp'=>1,'lt'=>1,'gt'=>1);
513     static 
$N = array('fnof'=>'402''Alpha'=>'913''Beta'=>'914''Gamma'=>'915''Delta'=>'916''Epsilon'=>'917''Zeta'=>'918''Eta'=>'919''Theta'=>'920''Iota'=>'921''Kappa'=>'922''Lambda'=>'923''Mu'=>'924''Nu'=>'925''Xi'=>'926''Omicron'=>'927''Pi'=>'928''Rho'=>'929''Sigma'=>'931''Tau'=>'932''Upsilon'=>'933''Phi'=>'934''Chi'=>'935''Psi'=>'936''Omega'=>'937''alpha'=>'945''beta'=>'946''gamma'=>'947''delta'=>'948''epsilon'=>'949''zeta'=>'950''eta'=>'951''theta'=>'952''iota'=>'953''kappa'=>'954''lambda'=>'955''mu'=>'956''nu'=>'957''xi'=>'958''omicron'=>'959''pi'=>'960''rho'=>'961''sigmaf'=>'962''sigma'=>'963''tau'=>'964''upsilon'=>'965''phi'=>'966''chi'=>'967''psi'=>'968''omega'=>'969''thetasym'=>'977''upsih'=>'978''piv'=>'982''bull'=>'8226''hellip'=>'8230''prime'=>'8242''Prime'=>'8243''oline'=>'8254''frasl'=>'8260''weierp'=>'8472''image'=>'8465''real'=>'8476''trade'=>'8482''alefsym'=>'8501''larr'=>'8592''uarr'=>'8593''rarr'=>'8594''darr'=>'8595''harr'=>'8596''crarr'=>'8629''lArr'=>'8656''uArr'=>'8657''rArr'=>'8658''dArr'=>'8659''hArr'=>'8660''forall'=>'8704''part'=>'8706''exist'=>'8707''empty'=>'8709''nabla'=>'8711''isin'=>'8712''notin'=>'8713''ni'=>'8715''prod'=>'8719''sum'=>'8721''minus'=>'8722''lowast'=>'8727''radic'=>'8730''prop'=>'8733''infin'=>'8734''ang'=>'8736''and'=>'8743''or'=>'8744''cap'=>'8745''cup'=>'8746''int'=>'8747''there4'=>'8756''sim'=>'8764''cong'=>'8773''asymp'=>'8776''ne'=>'8800''equiv'=>'8801''le'=>'8804''ge'=>'8805''sub'=>'8834''sup'=>'8835''nsub'=>'8836''sube'=>'8838''supe'=>'8839''oplus'=>'8853''otimes'=>'8855''perp'=>'8869''sdot'=>'8901''lceil'=>'8968''rceil'=>'8969''lfloor'=>'8970''rfloor'=>'8971''lang'=>'9001''rang'=>'9002''loz'=>'9674''spades'=>'9824''clubs'=>'9827''hearts'=>'9829''diams'=>'9830''apos'=>'39',  'OElig'=>'338''oelig'=>'339''Scaron'=>'352''scaron'=>'353''Yuml'=>'376''circ'=>'710''tilde'=>'732''ensp'=>'8194''emsp'=>'8195''thinsp'=>'8201''zwnj'=>'8204''zwj'=>'8205''lrm'=>'8206''rlm'=>'8207''ndash'=>'8211''mdash'=>'8212''lsquo'=>'8216''rsquo'=>'8217''sbquo'=>'8218''ldquo'=>'8220''rdquo'=>'8221''bdquo'=>'8222''dagger'=>'8224''Dagger'=>'8225''permil'=>'8240''lsaquo'=>'8249''rsaquo'=>'8250''euro'=>'8364''nbsp'=>'160''iexcl'=>'161''cent'=>'162''pound'=>'163''curren'=>'164''yen'=>'165''brvbar'=>'166''sect'=>'167''uml'=>'168''copy'=>'169''ordf'=>'170''laquo'=>'171''not'=>'172''shy'=>'173''reg'=>'174''macr'=>'175''deg'=>'176''plusmn'=>'177''sup2'=>'178''sup3'=>'179''acute'=>'180''micro'=>'181''para'=>'182''middot'=>'183''cedil'=>'184''sup1'=>'185''ordm'=>'186''raquo'=>'187''frac14'=>'188''frac12'=>'189''frac34'=>'190''iquest'=>'191''Agrave'=>'192''Aacute'=>'193''Acirc'=>'194''Atilde'=>'195''Auml'=>'196''Aring'=>'197''AElig'=>'198''Ccedil'=>'199''Egrave'=>'200''Eacute'=>'201''Ecirc'=>'202''Euml'=>'203''Igrave'=>'204''Iacute'=>'205''Icirc'=>'206''Iuml'=>'207''ETH'=>'208''Ntilde'=>'209''Ograve'=>'210''Oacute'=>'211''Ocirc'=>'212''Otilde'=>'213''Ouml'=>'214''times'=>'215''Oslash'=>'216''Ugrave'=>'217''Uacute'=>'218''Ucirc'=>'219''Uuml'=>'220''Yacute'=>'221''THORN'=>'222''szlig'=>'223''agrave'=>'224''aacute'=>'225''acirc'=>'226''atilde'=>'227''auml'=>'228''aring'=>'229''aelig'=>'230''ccedil'=>'231''egrave'=>'232''eacute'=>'233''ecirc'=>'234''euml'=>'235''igrave'=>'236''iacute'=>'237''icirc'=>'238''iuml'=>'239''eth'=>'240''ntilde'=>'241''ograve'=>'242''oacute'=>'243''ocirc'=>'244''otilde'=>'245''ouml'=>'246''divide'=>'247''oslash'=>'248''ugrave'=>'249''uacute'=>'250''ucirc'=>'251''uuml'=>'252''yacute'=>'253''thorn'=>'254''yuml'=>'255');
514     if (
$t[0] != '#') {
515         return (
$C['and_mark'] ? "\x06" '&'). (isset($U[$t]) ? $t : (isset($N[$t]) ? (!$C['named_entity'] ? '#'. ($C['hexdec_entity'] > 'x'dechex($N[$t]) : $N[$t]) : $t) : 'amp;'$t)). ';';
516     }
517     if ((
$n ctype_digit($t substr($t1)) ? intval($t) : hexdec(substr($t1))) < or ($n 13 && $n 32) or $n == 11 or $n == 12 or ($n 126 && $n 160 && $n != 133) or ($n 55295 && ($n 57344 or ($n 64975 && $n 64992) or $n == 65534 or $n == 65535 or $n 1114111))){
518         return (
$C['and_mark'] ? "\x06" '&'). "amp;#{$t};";
519     }
520     return (
$C['and_mark'] ? "\x06" '&'). '#'. (((ctype_digit($t) && $C['hexdec_entity'] < 2) or ! $C['hexdec_entity']) ? $n 'x'dechex($n)). ';';
521 }
522
523
/**
524  * Checking a URL scheme/protocol
525  */
526
function hl_prot($p$c NULL) {
527     
// check URL scheme
528     
global $C;
529     
$b $a '';
530     if (
$c == NULL) {
531         
$c 'style'
532         
$b $p[1]; 
533         
$a $p[3]; 
534         
$p trim($p[2]);
535     }
536     
$c = isset($C['schemes'][$c]) ? $C['schemes'][$c] : $C['schemes']['*'];
537     static 
$d 'denied:';
538     if (isset(
$c['!']) && substr($p07) != $d) {
539         
$p "$d$p";
540     }
541     if (isset(
$c['*']) or ! strcspn($p'#?;') or (substr($p07) == $d)) {
542         return 
"{$b}{$p}{$a}";
543     } 
// All ok, frag, query, param
544     
if (preg_match('`^([a-z\d\-+.&#; ]+?)(:|&#(58|x3a);|%3a|\\\\0{0,4}3a).`i'$p$m) && ! isset($c[strtolower($m[1])])){ // Denied prot
545         
return "{$b}{$d}{$p}{$a}";
546     }
547     if (
$C['abs_url']) {
548         if (
$C['abs_url'] == -&& strpos($p$C['base_url']) === 0){ // Make url rel
549             
$p substr($pstrlen($C['base_url']));
550         } elseif (empty(
$m[1])) { // Make URL abs
551             
if (substr($p02) == '//') {
552                 
$p substr($C['base_url'], 0strpos($C['base_url'], ':')+1). $p;
553             } elseif (
$p[0] == '/') {
554                 
$p preg_replace('`(^.+?://[^/]+)(.*)`''$1'$C['base_url']). $p;
555             } elseif (
strcspn($p'./')) {
556                 
$p $C['base_url']. $p;
557             } else {
558                 
preg_match('`^([a-zA-Z\d\-+.]+://[^/]+)(.*)`'$C['base_url'], $m);
559                 
$p preg_replace('`(?<=/)\./`'''$m[2]. $p);
560                 while (
preg_match('`(?<=/)([^/]{3,}|[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`'$p)) {
561                     
$p preg_replace('`(?<=/)([^/]{3,}|[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`'''$p);
562                 }
563                 
$p $m[1]. $p;
564             }
565         }
566     }
567     return 
"{$b}{$p}{$a}";
568 }
569
570
/**
571  * Checking syntax/well-formedness of regular expression patterns if such expressions are user-supplied through $C
572  */
573
function hl_regex($p){
574     
// ?regex
575     
if (empty($p)) {
576         return 
0;
577     }
578     if (
$t ini_get('track_errors')) {
579         
$o = isset($php_errormsg) ? $php_errormsg NULL;
580     } else {
581         
ini_set('track_errors'1);
582     }
583     unset(
$php_errormsg);
584     if ((
$d ini_get('display_errors'))) {
585         
ini_set('display_errors'0);
586     }
587     
preg_match($p'');
588     if (
$d) {
589         
ini_set('display_errors'1);
590     }
591     
$r = isset($php_errormsg) ? 1;
592     if (
$t) {
593         
$php_errormsg = isset($o) ? $o NULL;
594     } else {
595         
ini_set('track_errors'0);
596     }
597     return 
$r;
598 }
599
600
/**
601  * Converting user-supplied $spec value to one used by htmLawed internally
602  */
603
function hl_spec($t){
604     
// final $spec
605     
$s = array();
606     
$t str_replace(array("\t""\r""\n"' '), ''preg_replace('/"(?>(`.|[^"])*)"/sme''substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", \'`"\'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\""), "$0"), 1, -1)'trim($t))); 
607     for (
$i count(($t explode(';'$t))); --$i >= 0;) {
608         
$w $t[$i];
609         if (empty(
$w) or ($e strpos($w'=')) === FALSE or ! strlen(($a =  substr($w$e+1)))) {
610             continue;
611         }
612         
$y $n = array();
613         foreach (
explode(','$a) as $v) {
614             if ( ! 
preg_match('`^([a-z:\-\*]+)(?:\((.*?)\))?`i'$v$m)) {
615                 continue;
616             }
617             if ((
$x strtolower($m[1])) == '-*') {
618                 
$n['*'] = 1
619                 continue;
620             }
621             if (
$x[0] == '-') {
622                 
$n[substr($x1)] = 1
623                 continue;
624             }
625             if ( ! isset(
$m[2])) {
626                 
$y[$x] = 1
627                 continue;
628             }
629             foreach (
explode('/'$m[2]) as $m) {
630                 if (empty(
$m) or ($p strpos($m'=')) == or $p 5) {
631                     
$y[$x] = 1
632                     continue;
633                 }
634                 
$y[$x][strtolower(substr($m0$p))] = str_replace(array("\x01""\x02""\x03""\x04""\x05""\x06""\x07""\x08"), array(";""|""~"" "",""/""("")"), substr($m$p+1));
635             }
636             if (isset(
$y[$x]['match']) && ! hl_regex($y[$x]['match'])) {
637                 unset(
$y[$x]['match']);
638             }
639             if (isset(
$y[$x]['nomatch']) && ! hl_regex($y[$x]['nomatch'])) {
640                 unset(
$y[$x]['nomatch']);
641             }
642         }
643         if ( ! 
count($y) && ! count($n)) {
644             continue;
645         }
646         foreach (
explode(','substr($w0$e)) as $v) {
647             if ( ! 
strlen(($v strtolower($v)))) {
648                 continue;
649             }
650             if (
count($y)) {
651                 
$s[$v] = $y;
652             }
653             if (
count($n)) {
654                 
$s[$v]['n'] = $n;
655             }
656         }
657     }
658     return 
$s;
659 }
660
661
/**
662  * Handling tags
663  */
664
function hl_tag($t) {
665     
// tag/attribute handler
666     
global $C;
667     
$t $t[0];
668     
// invalid < >
669     
if ($t == '< ') { 
670         return 
'&lt; ';
671     }
672     if (
$t == '>') {
673         return 
'&gt;';
674     }
675     if ( ! 
preg_match('`^<(/?)([a-zA-Z][a-zA-Z1-6]*)([^>]*?)\s?>$`m'$t$m)) {
676         return 
str_replace(array('<''>'), array('&lt;''&gt;'), $t);
677     } elseif ( ! isset(
$C['elements'][($e strtolower($m[2]))])) {
678         return ((
$C['keep_bad']%2) ? str_replace(array('<''>'), array('&lt;''&gt;'), $t) : '');
679     }
680     
// attr string
681     
$a str_replace(array("\n""\r""\t"), ' 'trim($m[3]));
682     
// tag transform
683     
static $eD = array('applet'=>1'center'=>1'dir'=>1'embed'=>1'font'=>1'isindex'=>1'menu'=>1's'=>1'strike'=>1'u'=>1); // Deprecated
684     
if ($C['make_tag_strict'] && isset($eD[$e])) {
685         
$trt hl_tag2($e$a$C['make_tag_strict']);
686         if ( ! 
$e) {
687             return ((
$C['keep_bad']%2) ? str_replace(array('<''>'), array('&lt;''&gt;'), $t) : '');
688         }
689     }
690     
// close tag
691     
static $eE = array('area'=>1'br'=>1'col'=>1'embed'=>1'hr'=>1'img'=>1'input'=>1'isindex'=>1'param'=>1); // Empty ele
692     
if ( ! empty($m[1])) {
693         return ( ! isset(
$eE[$e]) ? "</$e>" : (($C['keep_bad'])%str_replace(array('<''>'), array('&lt;''&gt;'), $t) : ''));
694     }
695
696     
// open tag & attr
697     
static $aN = array('abbr'=>array('td'=>1'th'=>1), 'accept-charset'=>array('form'=>1), 'accept'=>array('form'=>1'input'=>1), 'accesskey'=>array('a'=>1'area'=>1'button'=>1'input'=>1'label'=>1'legend'=>1'textarea'=>1), 'action'=>array('form'=>1), 'align'=>array('caption'=>1'embed'=>1'applet'=>1'iframe'=>1'img'=>1'input'=>1'object'=>1'legend'=>1'table'=>1'hr'=>1'div'=>1'h1'=>1'h2'=>1'h3'=>1'h4'=>1'h5'=>1'h6'=>1'p'=>1'col'=>1'colgroup'=>1'tbody'=>1'td'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1), 'alt'=>array('applet'=>1'area'=>1'img'=>1'input'=>1), 'archive'=>array('applet'=>1'object'=>1), 'axis'=>array('td'=>1'th'=>1), 'bgcolor'=>array('embed'=>1'table'=>1'tr'=>1'td'=>1'th'=>1), 'border'=>array('table'=>1'img'=>1'object'=>1), 'bordercolor'=>array('table'=>1'td'=>1'tr'=>1), 'cellpadding'=>array('table'=>1), 'cellspacing'=>array('table'=>1), 'char'=>array('col'=>1'colgroup'=>1'tbody'=>1'td'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1), 'charoff'=>array('col'=>1'colgroup'=>1'tbody'=>1'td'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1), 'charset'=>array('a'=>1'script'=>1), 'checked'=>array('input'=>1), 'cite'=>array('blockquote'=>1'q'=>1'del'=>1'ins'=>1), 'classid'=>array('object'=>1), 'clear'=>array('br'=>1), 'code'=>array('applet'=>1), 'codebase'=>array('object'=>1'applet'=>1), 'codetype'=>array('object'=>1), 'color'=>array('font'=>1), 'cols'=>array('textarea'=>1), 'colspan'=>array('td'=>1'th'=>1), 'compact'=>array('dir'=>1'dl'=>1'menu'=>1'ol'=>1'ul'=>1), 'coords'=>array('area'=>1'a'=>1), 'data'=>array('object'=>1), 'datetime'=>array('del'=>1'ins'=>1), 'declare'=>array('object'=>1), 'defer'=>array('script'=>1), 'dir'=>array('bdo'=>1), 'disabled'=>array('button'=>1'input'=>1'optgroup'=>1'option'=>1'select'=>1'textarea'=>1), 'enctype'=>array('form'=>1), 'face'=>array('font'=>1), 'flashvars'=>array('embed'=>1), 'for'=>array('label'=>1), 'frame'=>array('table'=>1), 'frameborder'=>array('iframe'=>1), 'headers'=>array('td'=>1'th'=>1), 'height'=>array('embed'=>1'iframe'=>1'td'=>1'th'=>1'img'=>1'object'=>1'applet'=>1), 'href'=>array('a'=>1'area'=>1), 'hreflang'=>array('a'=>1), 'hspace'=>array('applet'=>1'img'=>1'object'=>1), 'ismap'=>array('img'=>1'input'=>1), 'label'=>array('option'=>1'optgroup'=>1), 'language'=>array('script'=>1), 'longdesc'=>array('img'=>1'iframe'=>1), 'marginheight'=>array('iframe'=>1), 'marginwidth'=>array('iframe'=>1), 'maxlength'=>array('input'=>1), 'method'=>array('form'=>1), 'model'=>array('embed'=>1), 'multiple'=>array('select'=>1), 'name'=>array('button'=>1'embed'=>1'textarea'=>1'applet'=>1'select'=>1'form'=>1'iframe'=>1'img'=>1'a'=>1'input'=>1'object'=>1'map'=>1'param'=>1), 'nohref'=>array('area'=>1), 'noshade'=>array('hr'=>1), 'nowrap'=>array('td'=>1'th'=>1), 'object'=>array('applet'=>1), 'onblur'=>array('a'=>1'area'=>1'button'=>1'input'=>1'label'=>1'select'=>1'textarea'=>1), 'onchange'=>array('input'=>1'select'=>1'textarea'=>1), 'onfocus'=>array('a'=>1'area'=>1'button'=>1'input'=>1'label'=>1'select'=>1'textarea'=>1), 'onreset'=>array('form'=>1), 'onselect'=>array('input'=>1'textarea'=>1), 'onsubmit'=>array('form'=>1), 'pluginspage'=>array('embed'=>1), 'pluginurl'=>array('embed'=>1), 'prompt'=>array('isindex'=>1), 'readonly'=>array('textarea'=>1'input'=>1), 'rel'=>array('a'=>1), 'rev'=>array('a'=>1), 'rows'=>array('textarea'=>1), 'rowspan'=>array('td'=>1'th'=>1), 'rules'=>array('table'=>1), 'scope'=>array('td'=>1'th'=>1), 'scrolling'=>array('iframe'=>1), 'selected'=>array('option'=>1), 'shape'=>array('area'=>1'a'=>1), 'size'=>array('hr'=>1'font'=>1'input'=>1'select'=>1), 'span'=>array('col'=>1'colgroup'=>1), 'src'=>array('embed'=>1'script'=>1'input'=>1'iframe'=>1'img'=>1), 'standby'=>array('object'=>1), 'start'=>array('ol'=>1), 'summary'=>array('table'=>1), 'tabindex'=>array('a'=>1'area'=>1'button'=>1'input'=>1'object'=>1'select'=>1'textarea'=>1), 'target'=>array('a'=>1'area'=>1'form'=>1), 'type'=>array('a'=>1'embed'=>1'object'=>1'param'=>1'script'=>1'input'=>1'li'=>1'ol'=>1'ul'=>1'button'=>1), 'usemap'=>array('img'=>1'input'=>1'object'=>1), 'valign'=>array('col'=>1'colgroup'=>1'tbody'=>1'td'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1), 'value'=>array('input'=>1'option'=>1'param'=>1'button'=>1'li'=>1), 'valuetype'=>array('param'=>1), 'vspace'=>array('applet'=>1'img'=>1'object'=>1), 'width'=>array('embed'=>1'hr'=>1'iframe'=>1'img'=>1'object'=>1'table'=>1'td'=>1'th'=>1'applet'=>1'col'=>1'colgroup'=>1'pre'=>1), 'wmode'=>array('embed'=>1), 'xml:space'=>array('pre'=>1'script'=>1'style'=>1)); // Ele-specific
698     
static $aNE = array('checked'=>1'compact'=>1'declare'=>1'defer'=>1'disabled'=>1'ismap'=>1'multiple'=>1'nohref'=>1'noresize'=>1'noshade'=>1'nowrap'=>1'readonly'=>1'selected'=>1); // Empty
699     
static $aNP = array('action'=>1'cite'=>1'classid'=>1'codebase'=>1'data'=>1'href'=>1'longdesc'=>1'model'=>1'pluginspage'=>1'pluginurl'=>1'usemap'=>1); // Need scheme check; excludes style, on* & src
700     
static $aNU = array('class'=>array('param'=>1'script'=>1), 'dir'=>array('applet'=>1'bdo'=>1'br'=>1'iframe'=>1'param'=>1'script'=>1), 'id'=>array('script'=>1), 'lang'=>array('applet'=>1'br'=>1'iframe'=>1'param'=>1'script'=>1), 'xml:lang'=>array('applet'=>1'br'=>1'iframe'=>1'param'=>1'script'=>1), 'onclick'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'ondblclick'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onkeydown'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onkeypress'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onkeyup'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onmousedown'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onmousemove'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onmouseout'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onmouseover'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'onmouseup'=>array('applet'=>1'bdo'=>1'br'=>1'font'=>1'iframe'=>1'isindex'=>1'param'=>1'script'=>1), 'style'=>array('param'=>1'script'=>1), 'title'=>array('param'=>1'script'=>1)); // Univ & exceptions
701
702     
if ($C['lc_std_val']) {
703         
// predef attr vals for $eAL & $aNE ele
704         
static $aNL = array('all'=>1'baseline'=>1'bottom'=>1'button'=>1'center'=>1'char'=>1'checkbox'=>1'circle'=>1'col'=>1'colgroup'=>1'cols'=>1'data'=>1'default'=>1'file'=>1'get'=>1'groups'=>1'hidden'=>1'image'=>1'justify'=>1'left'=>1'ltr'=>1'middle'=>1'none'=>1'object'=>1'password'=>1'poly'=>1'post'=>1'preserve'=>1'radio'=>1'rect'=>1'ref'=>1'reset'=>1'right'=>1'row'=>1'rowgroup'=>1'rows'=>1'rtl'=>1'submit'=>1'text'=>1'top'=>1);
705         static 
$eAL = array('a'=>1'area'=>1'bdo'=>1'button'=>1'col'=>1'form'=>1'img'=>1'input'=>1'object'=>1'optgroup'=>1'option'=>1'param'=>1'script'=>1'select'=>1'table'=>1'td'=>1'tfoot'=>1'th'=>1'thead'=>1'tr'=>1'xml:space'=>1);
706         
$lcase = isset($eAL[$e]) ? 0;
707     }
708
709     
$depTr 0;
710     if (
$C['no_deprecated_attr']) {
711         
// dep attr:applicable ele
712         
static $aND = array('align'=>array('caption'=>1'div'=>1'h1'=>1'h2'=>1'h3'=>1'h4'=>1'h5'=>1'h6'=>1'hr'=>1'img'=>1'input'=>1'legend'=>1'object'=>1'p'=>1'table'=>1), 'bgcolor'=>array('table'=>1'td'=>1'th'=>1'tr'=>1), 'border'=>array('img'=>1'object'=>1), 'bordercolor'=>array('table'=>1'td'=>1'tr'=>1), 'clear'=>array('br'=>1), 'compact'=>array('dl'=>1'ol'=>1'ul'=>1), 'height'=>array('td'=>1'th'=>1), 'hspace'=>array('img'=>1'object'=>1), 'language'=>array('script'=>1), 'name'=>array('a'=>1'form'=>1'iframe'=>1'img'=>1'map'=>1), 'noshade'=>array('hr'=>1), 'nowrap'=>array('td'=>1'th'=>1), 'size'=>array('hr'=>1), 'start'=>array('ol'=>1), 'type'=>array('li'=>1'ol'=>1'ul'=>1), 'value'=>array('li'=>1), 'vspace'=>array('img'=>1'object'=>1), 'width'=>array('hr'=>1'pre'=>1'td'=>1'th'=>1));
713         static 
$eAD = array('a'=>1'br'=>1'caption'=>1'div'=>1'dl'=>1'form'=>1'h1'=>1'h2'=>1'h3'=>1'h4'=>1'h5'=>1'h6'=>1'hr'=>1'iframe'=>1'img'=>1'input'=>1'legend'=>1'li'=>1'map'=>1'object'=>1'ol'=>1'p'=>1'pre'=>1'script'=>1'table'=>1'td'=>1'th'=>1'tr'=>1'ul'=>1);
714         
$depTr = isset($eAD[$e]) ? 0;
715     }
716
717     
// attr name-vals
718     
if (strpos($a"\x01") !== FALSE) {
719         
$a preg_replace('`\x01[^\x01]*\x01`'''$a);
720     } 
// No comment/CDATA sec
721     
$mode 0$a trim($a' /'); $aA = array();
722     while (
strlen($a)) {
723         
$w 0;
724         switch(
$mode){
725             case 
0// Name
726                 
if (preg_match('`^[a-zA-Z][\-a-zA-Z:]+`'$a$m)) {
727                     
$nm strtolower($m[0]);
728                     
$w $mode 1
729                     
$a ltrim(substr_replace($a''0strlen($m[0])));
730                 }
731                 break; 
732         
733             case 
1:
734                 if (
$a[0] == '=') { // =
735                     
$w 1$mode 2
736                     
$a ltrim($a'= ');
737                 } else { 
// No val
738                     
$w 1
739                     
$mode 0
740                     
$a ltrim($a);
741                     
$aA[$nm] = '';
742                 }
743                 break; 
744         
745             case 
2// Val
746                 
if (preg_match('`^"[^"]*"`'$a$m) or preg_match("`^'[^']*'`"$a$m) or preg_match("`^\s*[^\s\"']+`"$a$m)) {
747                     
$m $m[0]; 
748                     
$w 1
749                     
$mode 0
750                     
$a ltrim(substr_replace($a''0strlen($m)));
751                     
$aA[$nm] = trim(($m[0] == '"' or $m[0] == '\'') ? substr($m1, -1) : $m);
752                 }
753                 break;
754         }
755         if (
$w == 0) { // Parse errs, deal with space, " & '
756             
$a preg_replace('`^(?:"[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*`'''$a);
757             
$mode 0;
758         }
759     }
760     if (
$mode == 1) {
761         
$aA[$nm] = '';
762     }
763
764     
// clean attrs
765     
global $S;
766     
$rl = isset($S[$e]) ? $S[$e] : array();
767     
$a = array(); 
768     
$nfr 0;
769     foreach (
$aA as $k => $v) {
770         if (((isset(
$C['deny_attribute']['*']) ? isset($C['deny_attribute'][$k]) : ! isset($C['deny_attribute'][$k])) or isset($rl[$k])) && (( ! isset($rl['n'][$k]) && !isset($rl['n']['*'])) or isset($rl[$k])) && (isset($aN[$k][$e]) or (isset($aNU[$k]) && !isset($aNU[$k][$e])))) {
771             if (isset(
$aNE[$k])) {
772                 
$v $k;
773             } elseif( ! empty(
$lcase) && (($e != 'button' or $e != 'input') or $k == 'type')) { // Rather loose but ?not cause issues
774                 
$v = (isset($aNL[($v2 strtolower($v))])) ? $v2 $v;
775             }
776             if (
$k == 'style' && ! $C['style_pass']) {
777                 if (
FALSE !== strpos($v'&#')) {
778                     static 
$sC = array('&#x20;'=>' ''&#32;'=>' ''&#x45;'=>'e''&#69;'=>'e''&#x65;'=>'e''&#101;'=>'e''&#x58;'=>'x''&#88;'=>'x''&#x78;'=>'x''&#120;'=>'x''&#x50;'=>'p''&#80;'=>'p''&#x70;'=>'p''&#112;'=>'p''&#x53;'=>'s''&#83;'=>'s''&#x73;'=>'s''&#115;'=>'s''&#x49;'=>'i''&#73;'=>'i''&#x69;'=>'i''&#105;'=>'i''&#x4f;'=>'o''&#79;'=>'o''&#x6f;'=>'o''&#111;'=>'o''&#x4e;'=>'n''&#78;'=>'n''&#x6e;'=>'n''&#110;'=>'n''&#x55;'=>'u''&#85;'=>'u''&#x75;'=>'u''&#117;'=>'u''&#x52;'=>'r''&#82;'=>'r''&#x72;'=>'r''&#114;'=>'r''&#x4c;'=>'l''&#76;'=>'l''&#x6c;'=>'l''&#108;'=>'l''&#x28;'=>'(''&#40;'=>'(''&#x29;'=>')''&#41;'=>')''&#x20;'=>':''&#32;'=>':''&#x22;'=>'"''&#34;'=>'"''&#x27;'=>"'"'&#39;'=>"'"'&#x2f;'=>'/''&#47;'=>'/''&#x2a;'=>'*''&#42;'=>'*''&#x5c;'=>'\\''&#92;'=>'\\');
779                     
$v strtr($v$sC);
780                 }
781                 
$v preg_replace_callback('`(url(?:\()(?: )*(?:\'|"|&(?:quot|apos);)?)(.+?)((?:\'|"|&(?:quot|apos);)?(?: )*(?:\)))`iS''hl_prot'$v);
782                 
$v = ! $C['css_expression'] ? preg_replace('`expression`i'' 'preg_replace('`\\\\\S|(/|(%2f))(\*|(%2a))`i'' '$v)) : $v;
783             } elseif (isset(
$aNP[$k]) or strpos($k'src') !== FALSE or $k[0] == 'o') {
784                 
$v str_replace("\xad"' ', (strpos($v'&') !== FALSE str_replace(array('&#xad;''&#173;''&shy;'), ' '$v) : $v));
785                 
$v hl_prot($v$k);
786                 if (
$k == 'href') { // X-spam
787                     
if ($C['anti_mail_spam'] && strpos($v'mailto:') === 0) {
788                         
$v str_replace('@'htmlspecialchars($C['anti_mail_spam']), $v);
789                     } elseif (
$C['anti_link_spam']) {
790                         
$r1 $C['anti_link_spam'][1];
791                         if ( ! empty(
$r1) && preg_match($r1$v)) {
792                             continue;
793                         }
794                         
$r0 $C['anti_link_spam'][0];
795                         if ( ! empty(
$r0) && preg_match($r0$v)) {
796                             if (isset(
$a['rel'])) {
797                                 if ( ! 
preg_match('`\bnofollow\b`i'$a['rel'])) {
798                                     
$a['rel'] .= ' nofollow';
799                                 }
800                             } elseif (isset(
$aA['rel'])) {
801                                 if ( ! 
preg_match('`\bnofollow\b`i'$aA['rel'])) {
802                                     
$nfr 1;
803                                 }
804                             } else {
805                                 
$a['rel'] = 'nofollow';
806                             }
807                         }
808                     }
809                 }
810             }
811              if (isset(
$rl[$k]) && is_array($rl[$k]) && ($v hl_attrval($v$rl[$k])) === 0) {
812                 continue;
813             }
814             
$a[$k] = str_replace('"''&quot;'$v);
815         }
816     }
817     if (
$nfr) {
818         
$a['rel'] = isset($a['rel']) ? $a['rel']. ' nofollow' 'nofollow';
819     }
820
821     
// rqd attr
822     
static $eAR = array('area'=>array('alt'=>'area'), 'bdo'=>array('dir'=>'ltr'), 'form'=>array('action'=>''), 'img'=>array('src'=>'''alt'=>'image'), 'map'=>array('name'=>''), 'optgroup'=>array('label'=>''), 'param'=>array('name'=>''), 'script'=>array('type'=>'text/javascript'), 'textarea'=>array('rows'=>'10''cols'=>'50'));
823     if (isset(
$eAR[$e])) {
824         foreach(
$eAR[$e] as $k => $v){
825             if ( ! isset(
$a[$k])) {
826                 
$a[$k] = isset($v[0]) ? $v $k;
827             }
828         }
829     }
830
831     
// depr attrs
832     
if ($depTr) {
833         
$c = array();
834         foreach (
$a as $k => $v) {
835             if (
$k == 'style' or ! isset($aND[$k][$e])) {
836                 continue;
837             }
838             if (
$k == 'align') {
839                 unset(
$a['align']);
840                 if (
$e == 'img' && ($v == 'left' or $v == 'right')) {
841                     
$c[] = 'float: '$v;
842                 } elseif ((
$e == 'div' or $e == 'table') && $v == 'center') {
843                     
$c[] = 'margin: auto';
844                 } else {
845                     
$c[] = 'text-align: '$v;
846                 }
847             } elseif (
$k == 'bgcolor') {
848                 unset(
$a['bgcolor']);
849                 
$c[] = 'background-color: '$v;
850             } elseif (
$k == 'border') {
851                 unset(
$a['border']); 
852                 
$c[] = "border: {$v}px";
853             } elseif (
$k == 'bordercolor') {
854                 unset(
$a['bordercolor']); 
855                 
$c[] = 'border-color: '$v;
856             } elseif (
$k == 'clear') {
857                 unset(
$a['clear']); 
858                 
$c[] = 'clear: '. ($v != 'all' $v 'both');
859             } elseif (
$k == 'compact') {
860                 unset(
$a['compact']); 
861                 
$c[] = 'font-size: 85%';
862             } elseif (
$k == 'height' or $k == 'width') {
863                 unset(
$a[$k]); 
864                 
$c[] = $k': '. ($v[0] != '*' $v. (ctype_digit($v) ? 'px' '') : 'auto');
865             } elseif (
$k == 'hspace') {
866                 unset(
$a['hspace']); 
867                 
$c[] = "margin-left: {$v}px; margin-right: {$v}px";
868             } elseif (
$k == 'language' && ! isset($a['type'])) {
869                 unset(
$a['language']);
870                
$a['type'] = 'text/'strtolower($v);
871             } elseif (
$k == 'name') {
872                 if (
$C['no_deprecated_attr'] == or ($e != 'a' && $e != 'map')) {
873                     unset(
$a['name']);
874                 }
875                 if( ! isset(
$a['id']) && preg_match('`[a-zA-Z][a-zA-Z\d.:_\-]*`'$v)) {
876                     
$a['id'] = $v;
877                 }
878             } elseif (
$k == 'noshade') {
879                 unset(
$a['noshade']); 
880                 
$c[] = 'border-style: none; border: 0; background-color: gray; color: gray';
881             } elseif (
$k == 'nowrap') {
882                 unset(
$a['nowrap']); $c[] = 'white-space: nowrap';
883             } elseif (
$k == 'size') {
884                 unset(
$a['size']); 
885                 
$c[] = 'size: '$v'px';
886             } elseif (
$k == 'start' or $k == 'value') {
887                 unset(
$a[$k]);
888             } elseif (
$k == 'type') {
889                 unset(
$a['type']);
890                 static 
$ol_type = array('i'=>'lower-roman''I'=>'upper-roman''a'=>'lower-latin''A'=>'upper-latin''1'=>'decimal');
891                 
$c[] = 'list-style-type: '. (isset($ol_type[$v]) ? $ol_type[$v] : 'decimal');
892             } elseif (
$k == 'vspace') {
893                 unset(
$a['vspace']); $c[] = "margin-top: {$v}px; margin-bottom: {$v}px";
894             }
895         }
896         if (
count($c)) {
897             
$c implode('; '$c);
898             
$a['style'] = isset($a['style']) ? rtrim($a['style'], ' ;'). '; '$c';'$c';';
899         }
900     }
901     
// unique ID
902     
if ($C['unique_ids'] && isset($a['id'])) {
903         if ( ! 
preg_match('`^[A-Za-z][A-Za-z0-9_\-.:]*$`', ($id $a['id'])) or (isset($GLOBALS['hl_Ids'][$id]) && $C['unique_ids'] == 1)) {
904             unset(
$a['id']);
905         }else {
906             while (isset(
$GLOBALS['hl_Ids'][$id])) {
907                 
$id $C['unique_ids']. $id;
908             }
909             
$GLOBALS['hl_Ids'][($a['id'] = $id)] = 1;
910         }
911     }
912     
// xml:lang
913     
if ($C['xml:lang'] && isset($a['lang'])) {
914         
$a['xml:lang'] = isset($a['xml:lang']) ? $a['xml:lang'] : $a['lang'];
915         if (
$C['xml:lang'] == 2) {
916             unset(
$a['lang']);
917         }
918     }
919     
// for transformed tag
920     
if ( ! empty($trt)){
921         
$a['style'] = isset($a['style']) ? rtrim($a['style'], ' ;'). '; '$trt $trt;
922     }
923     
// return with empty ele /
924     
if (empty($C['hook_tag'])) {
925         
$aA '';
926         foreach (
$a as $k => $v) {
927             
$aA .= " {$k}=\"{$v}\"";
928         }
929         return 
"<{$e}{$aA}". (isset($eE[$e]) ? ' /' ''). '>';
930     } else {
931         return 
$C['hook_tag']($e$a);
932     }
933 }
934
935
/**
936  * Transforming tags
937  */
938
function hl_tag2(&$e, &$a$t 1) {
939     
// transform tag
940     
if ($e == 'center') {
941         
$e 'div'
942         return 
'text-align: center;';
943     }
944     if (
$e == 'dir' or $e == 'menu') {
945         
$e 'ul'
946         return 
'';
947     }
948     if (
$e == 's' or $e == 'strike') {
949         
$e 'span'
950         return 
'text-decoration: line-through;';
951     }
952     if (
$e == 'u') {
953         
$e 'span'
954         return 
'text-decoration: underline;';
955     }
956     static 
$fs = array('0'=>'xx-small''1'=>'xx-small''2'=>'small''3'=>'medium''4'=>'large''5'=>'x-large''6'=>'xx-large''7'=>'300%''-1'=>'smaller''-2'=>'60%''+1'=>'larger''+2'=>'150%''+3'=>'200%''+4'=>'300%');
957     if (
$e == 'font') {
958         
$a2 '';
959         if (
preg_match('`face\s*=\s*(\'|")([^=]+?)\\1`i'$a$m) or preg_match('`face\s*=\s*([^"])(\S+)`i'$a$m)) {
960             
$a2 .= ' font-family: 'str_replace('"''\''trim($m[2])). ';';
961         }
962         if (
preg_match('`color\s*=\s*(\'|")?(.+?)(\\1|\s|$)`i'$a$m)) {
963             
$a2 .= ' color: 'trim($m[2]). ';';
964         }
965         if (
preg_match('`size\s*=\s*(\'|")?(.+?)(\\1|\s|$)`i'$a$m) && isset($fs[($m trim($m[2]))])) {
966             
$a2 .= ' font-size: '$fs[$m]. ';';
967         }
968         
$e 'span'
969         return 
ltrim($a2);
970     }
971     if (
$t == 2) {
972         
$e 0
973         return 
0;
974     }
975     return 
'';
976 }
977
978
// End of file: ./system/functions/htmlawed/htmlawed_function.php

Page URI: http://www.infopotato.com/index.php/code/function/htmlawed/