]>
git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/libraries/htmLawed/htmLawed.php
4 htmLawed 1.1.14, 8 August 2012
5 OOP code, 8 August 2012
6 Copyright Santosh Patnaik
7 Dual LGPL v3 and GPL v2+ license
8 A PHP Labware internal utility; www.bioinformatics.org/phplabware/internal_utilities/htmLawed
10 See htmLawed_README.txt/htm
15 public static function hl ( $t , $C = 1 , $S = array ()){
16 $C = is_array ( $C ) ? $C : array ();
17 if (! empty ( $C [ 'valid_xhtml' ])){
18 $C [ 'elements' ] = empty ( $C [ 'elements' ]) ? '*-center-dir-font-isindex-menu-s-strike-u' : $C [ 'elements' ];
19 $C [ 'make_tag_strict' ] = isset ( $C [ 'make_tag_strict' ]) ? $C [ 'make_tag_strict' ] : 2 ;
20 $C [ 'xml:lang' ] = isset ( $C [ 'xml:lang' ]) ? $C [ 'xml:lang' ] : 2 ;
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 ); // 86/deprecated+embed+ruby
24 if (! empty ( $C [ 'safe' ])){
25 unset ( $e [ 'applet' ], $e [ 'embed' ], $e [ 'iframe' ], $e [ 'object' ], $e [ 'script' ]);
27 $x = ! empty ( $C [ 'elements' ]) ? str_replace ( array ( " \n " , " \r " , " \t " , ' ' ), '' , $C [ 'elements' ]) : '*' ;
28 if ( $x == '-*' ){ $e
= array ();}
29 elseif ( strpos ( $x , '*' ) === false ){ $e
= array_flip ( explode ( ',' , $x
));}
32 preg_match_all ( '`(?:^|-|\+)[^\-+]+?(?=-|\+|$)`' , $x , $m , PREG_SET_ORDER
);
33 for ( $i = count ( $m ); -- $i >= 0 ;){ $m
[ $i
] = $m
[ $i
][ 0 ];}
35 if ( $v [ 0 ] == '+' ){ $e
[ substr ( $v
, 1 )] = 1 ;}
36 if ( $v [ 0 ] == '-' && isset ( $e [( $v = substr ( $v , 1 ))]) && ! in_array ( '+' . $v , $m )){ unset ( $e
[ $v
]);}
42 $x = ! empty ( $C [ 'deny_attribute' ]) ? str_replace ( array ( " \n " , " \r " , " \t " , ' ' ), '' , $C [ 'deny_attribute' ]) : '' ;
43 $x = array_flip (( isset ( $x [ 0 ]) && $x [ 0 ] == '*' ) ? explode ( '-' , $x ) : explode ( ',' , $x . (! empty ( $C [ 'safe' ]) ? ',on*' : '' )));
46 $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 );
48 $C [ 'deny_attribute' ] = $x ;
50 $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' ;
51 $C [ 'schemes' ] = array ();
52 foreach ( explode ( ';' , str_replace ( array ( ' ' , " \t " , " \r " , " \n " ), '' , $x )) as $v ){
53 $x = $x2 = null ; list ( $x , $x2 ) = explode ( ':' , $v , 2 );
54 if ( $x2 ){ $C
[ 'schemes' ][ $x
] = array_flip ( explode ( ',' , $x2
));}
56 if (! isset ( $C [ 'schemes' ][ '*' ])){ $C
[ 'schemes' ][ '*' ] = array ( 'file' => 1 , 'http' => 1 , 'https' => 1 ,);}
57 if (! empty ( $C [ 'safe' ]) && empty ( $C [ 'schemes' ][ 'style' ])){ $C
[ 'schemes' ][ 'style' ] = array ( '!' => 1 );}
58 $C [ 'abs_url' ] = isset ( $C [ 'abs_url' ]) ? $C [ 'abs_url' ] : 0 ;
59 if (! isset ( $C [ 'base_url' ]) or ! preg_match ( '`^[a-zA-Z\d.+\-]+://[^/]+/(.+?/)?$`' , $C [ 'base_url' ])){
60 $C [ 'base_url' ] = $C [ 'abs_url' ] = 0 ;
63 $C [ 'and_mark' ] = empty ( $C [ 'and_mark' ]) ? 0 : 1 ;
64 $C [ 'anti_link_spam' ] = ( isset ( $C [ 'anti_link_spam' ]) && is_array ( $C [ 'anti_link_spam' ]) && count ( $C [ 'anti_link_spam' ]) == 2 && ( empty ( $C [ 'anti_link_spam' ][ 0 ]) or htmLawed
:: hl_regex ( $C [ 'anti_link_spam' ][ 0 ])) && ( empty ( $C [ 'anti_link_spam' ][ 1 ]) or htmLawed
:: hl_regex ( $C [ 'anti_link_spam' ][ 1 ]))) ? $C [ 'anti_link_spam' ] : 0 ;
65 $C [ 'anti_mail_spam' ] = isset ( $C [ 'anti_mail_spam' ]) ? $C [ 'anti_mail_spam' ] : 0 ;
66 $C [ 'balance' ] = isset ( $C [ 'balance' ]) ? ( bool ) $C [ 'balance' ] : 1 ;
67 $C [ 'cdata' ] = isset ( $C [ 'cdata' ]) ? $C [ 'cdata' ] : ( empty ( $C [ 'safe' ]) ? 3 : 0 );
68 $C [ 'clean_ms_char' ] = empty ( $C [ 'clean_ms_char' ]) ? 0 : $C [ 'clean_ms_char' ];
69 $C [ 'comment' ] = isset ( $C [ 'comment' ]) ? $C [ 'comment' ] : ( empty ( $C [ 'safe' ]) ? 3 : 0 );
70 $C [ 'css_expression' ] = empty ( $C [ 'css_expression' ]) ? 0 : 1 ;
71 $C [ 'direct_list_nest' ] = empty ( $C [ 'direct_list_nest' ]) ? 0 : 1 ;
72 $C [ 'hexdec_entity' ] = isset ( $C [ 'hexdec_entity' ]) ? $C [ 'hexdec_entity' ] : 1 ;
73 $C [ 'hook' ] = (! empty ( $C [ 'hook' ]) && function_exists ( $C [ 'hook' ])) ? $C [ 'hook' ] : 0 ;
74 $C [ 'hook_tag' ] = (! empty ( $C [ 'hook_tag' ]) && function_exists ( $C [ 'hook_tag' ])) ? $C [ 'hook_tag' ] : 0 ;
75 $C [ 'keep_bad' ] = isset ( $C [ 'keep_bad' ]) ? $C [ 'keep_bad' ] : 6 ;
76 $C [ 'lc_std_val' ] = isset ( $C [ 'lc_std_val' ]) ? ( bool ) $C [ 'lc_std_val' ] : 1 ;
77 $C [ 'make_tag_strict' ] = isset ( $C [ 'make_tag_strict' ]) ? $C [ 'make_tag_strict' ] : 1 ;
78 $C [ 'named_entity' ] = isset ( $C [ 'named_entity' ]) ? ( bool ) $C [ 'named_entity' ] : 1 ;
79 $C [ 'no_deprecated_attr' ] = isset ( $C [ 'no_deprecated_attr' ]) ? $C [ 'no_deprecated_attr' ] : 1 ;
80 $C [ 'parent' ] = isset ( $C [ 'parent' ][ 0 ]) ? strtolower ( $C [ 'parent' ]) : 'body' ;
81 $C [ 'show_setting' ] = ! empty ( $C [ 'show_setting' ]) ? $C [ 'show_setting' ] : 0 ;
82 $C [ 'style_pass' ] = empty ( $C [ 'style_pass' ]) ? 0 : 1 ;
83 $C [ 'tidy' ] = empty ( $C [ 'tidy' ]) ? 0 : $C [ 'tidy' ];
84 $C [ 'unique_ids' ] = isset ( $C [ 'unique_ids' ]) ? $C [ 'unique_ids' ] : 1 ;
85 $C [ 'xml:lang' ] = isset ( $C [ 'xml:lang' ]) ? $C [ 'xml:lang' ] : 0 ;
87 if ( isset ( $GLOBALS [ 'C' ])){ $reC
= $GLOBALS
[ 'C' ];}
89 $S = is_array ( $S ) ? $S : htmLawed
:: hl_spec ( $S );
90 if ( isset ( $GLOBALS [ 'S' ])){ $reS
= $GLOBALS
[ 'S' ];}
93 $t = preg_replace ( '`[ \x00 - \x08\x0b - \x0c\x0e - \x1f ]`' , '' , $t );
94 if ( $C [ 'clean_ms_char' ]){
95 $x = array ( " \x7f " => '' , " \x80 " => '€' , " \x81 " => '' , " \x83 " => 'ƒ' , " \x85 " => '…' , " \x86 " => '†' , " \x87 " => '‡' , " \x88 " => 'ˆ' , " \x89 " => '‰' , " \x8a " => 'Š' , " \x8b " => '‹' , " \x8c " => 'Œ' , " \x8d " => '' , " \x8e " => 'Ž' , " \x8f " => '' , " \x90 " => '' , " \x95 " => '•' , " \x96 " => '–' , " \x97 " => '—' , " \x98 " => '˜' , " \x99 " => '™' , " \x9a " => 'š' , " \x9b " => '›' , " \x9c " => 'œ' , " \x9d " => '' , " \x9e " => 'ž' , " \x9f " => 'Ÿ' );
96 $x = $x +
( $C [ 'clean_ms_char' ] == 1 ? array ( " \x82 " => '‚' , " \x84 " => '„' , " \x91 " => '‘' , " \x92 " => '’' , " \x93 " => '“' , " \x94 " => '”' ) : array ( " \x82 " => ' \' ' , " \x84 " => '"' , " \x91 " => ' \' ' , " \x92 " => ' \' ' , " \x93 " => '"' , " \x94 " => '"' ));
99 if ( $C [ 'cdata' ] or $C [ 'comment' ]){ $t
= preg_replace_callback ( '`<!(?:(?:--.*?--)|(?:\[CDATA\[.*?\]\]))>`sm' , 'htmLawed::hl_cmtcd' , $t
);}
100 $t = preg_replace_callback ( '`&([A-Za-z][A-Za-z0-9] {1,30} |#(?:[0-9] {1,8} |[Xx][0-9A-Fa-f] {1,7} ));`' , 'htmLawed::hl_ent' , str_replace ( '&' , '&' , $t ));
101 if ( $C [ 'unique_ids' ] && ! isset ( $GLOBALS [ 'hl_Ids' ])){ $GLOBALS
[ 'hl_Ids' ] = array ();}
102 if ( $C [ 'hook' ]){ $t
= $C
[ 'hook' ]( $t
, $C
, $S
);}
103 if ( $C [ 'show_setting' ] && preg_match ( '`^[a-z][a-z0-9_]*$`i' , $C [ 'show_setting' ])){
104 $GLOBALS [ $C [ 'show_setting' ]] = array ( 'config' => $C , 'spec' => $S , 'time' => microtime ());
107 $t = preg_replace_callback ( '`<(?:(?:\s|$)|(?:[^>]*(?:>|$)))|>`m' , 'htmLawed::hl_tag' , $t );
108 $t = $C [ 'balance' ] ? htmLawed
:: hl_bal ( $t , $C [ 'keep_bad' ], $C [ 'parent' ]) : $t ;
109 $t = (( $C [ 'cdata' ] or $C [ 'comment' ]) && strpos ( $t , " \x01 " ) !== false ) ? str_replace ( array ( " \x01 " , " \x02 " , " \x03 " , " \x04 " , " \x05 " ), array ( '' , '' , '&' , '<' , '>' ), $t ) : $t ;
110 $t = $C [ 'tidy' ] ? htmLawed
:: hl_tidy ( $t , $C [ 'tidy' ], $C [ 'parent' ]) : $t ;
112 if ( isset ( $reC )){ $GLOBALS
[ 'C' ] = $reC
;}
113 if ( isset ( $reS )){ $GLOBALS
[ 'S' ] = $reS
;}
118 public static function hl_attrval ( $t , $p ){
119 // check attr val against $S
120 $o = 1 ; $l = strlen ( $t );
121 foreach ( $p as $k => $v ){
123 case 'maxlen' : if ( $l > $v ){ $o
= 0 ;}
124 break ; case 'minlen' : if ( $l < $v ){ $o
= 0 ;}
125 break ; case 'maxval' : if (( float )( $t ) > $v ){ $o
= 0 ;}
126 break ; case 'minval' : if (( float )( $t ) < $v ){ $o
= 0 ;}
127 break ; case 'match' : if (! preg_match ( $v , $t )){ $o
= 0 ;}
128 break ; case 'nomatch' : if ( preg_match ( $v , $t )){ $o
= 0 ;}
131 foreach ( explode ( '|' , $v ) as $n ){ if ( $t
== $n
){ $m
= 1 ; break ;}}
133 break ; case 'noneof' :
135 foreach ( explode ( '|' , $v ) as $n ){ if ( $t
== $n
){ $m
= 0 ; break ;}}
142 return ( $o ? $t : ( isset ( $p [ 'default' ]) ? $p [ 'default' ] : 0 ));
146 public static function hl_bal ( $t , $do = 1 , $in = 'div' ){
149 $cB = array ( 'blockquote' => 1 , 'form' => 1 , 'map' => 1 , 'noscript' => 1 ); // Block
150 $cE = array ( 'area' => 1 , 'br' => 1 , 'col' => 1 , 'embed' => 1 , 'hr' => 1 , 'img' => 1 , 'input' => 1 , 'isindex' => 1 , 'param' => 1 ); // Empty
151 $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
152 $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
153 $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
154 $cN2 = array_keys ( $cN );
155 $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 );
156 $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
157 if ( $GLOBALS [ 'C' ][ 'direct_list_nest' ]){ $cS
[ 'ol' ] = $cS
[ 'ul' ] +
= array ( 'ol' => 1 , 'ul' => 1 );}
158 $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
159 $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
160 // block/inline type; ins & del both type; #pcdata: text
161 $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 );
162 $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 );
163 $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
164 $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
167 // $in sets allowed child
168 $in = (( isset ( $eF [ $in ]) && $in != '#pcdata' ) or isset ( $eO [ $in ])) ? $in : 'div' ;
170 return (! $do ? '' : str_replace ( array ( '<' , '>' ), array ( '<' , '>' ), $t ));
172 if ( isset ( $cS [ $in ])){ $inOk
= $cS
[ $in
];}
173 elseif ( isset ( $cI [ $in ])){ $inOk
= $eI
; $cI
[ 'del' ] = 1 ; $cI
[ 'ins' ] = 1 ;}
174 elseif ( isset ( $cF [ $in ])){ $inOk
= $eF
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
175 elseif ( isset ( $cB [ $in ])){ $inOk
= $eB
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
176 if ( isset ( $cO [ $in ])){ $inOk
= $inOk + $cO
[ $in
];}
177 if ( isset ( $cN [ $in ])){ $inOk
= array_diff_assoc ( $inOk
, $cN
[ $in
]);}
179 $t = explode ( '<' , $t );
180 $ok = $q = array (); // $q seq list of open non-empty ele
183 for ( $i =- 1 , $ci = count ( $t ); ++
$i < $ci ;){
184 // allowed $ok in parent $p
188 if ( isset ( $cS [ $p ])){ $ok
= $cS
[ $p
];}
189 elseif ( isset ( $cI [ $p ])){ $ok
= $eI
; $cI
[ 'del' ] = 1 ; $cI
[ 'ins' ] = 1 ;}
190 elseif ( isset ( $cF [ $p ])){ $ok
= $eF
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
191 elseif ( isset ( $cB [ $p ])){ $ok
= $eB
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
192 if ( isset ( $cO [ $p ])){ $ok
= $ok + $cO
[ $p
];}
193 if ( isset ( $cN [ $p ])){ $ok
= array_diff_assoc ( $ok
, $cN
[ $p
]);}
194 } else {$ok
= $inOk
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
195 // bad tags, & ele content
196 if ( isset ( $e ) && ( $do == 1 or ( isset ( $ok [ '#pcdata' ]) && ( $do == 3 or $do == 5 )))){
197 echo '<' , $s , $e , $a , '>' ;
200 if ( strlen ( trim ( $x )) && (( $ql && isset ( $cB [ $p ])) or ( isset ( $cB [ $in ]) && ! $ql ))){
201 echo '<div>' , $x , '</div>' ;
203 elseif ( $do < 3 or isset ( $ok [ '#pcdata' ])){ echo $x
;}
204 elseif ( strpos ( $x , " \x02\x04 " )){
205 foreach ( preg_split ( '`( \x01\x02 [^ \x01\x02 ]+ \x02\x01 )`' , $x , - 1 , PREG_SPLIT_DELIM_CAPTURE
| PREG_SPLIT_NO_EMPTY
) as $v ){
206 echo ( substr ( $v , 0 , 2 ) == " \x01\x02 " ? $v : ( $do > 4 ? preg_replace ( '`\S`' , '' , $v ) : '' ));
208 } elseif ( $do > 4 ){ echo preg_replace ( '`\S`' , '' , $x
);}
211 if (! preg_match ( '`^(/?)([a-z1-6]+)([^>]*)>(.*)`sm' , $t [ $i ], $r )){ $x
= $t
[ $i
]; continue ;}
212 $s = null ; $e = null ; $a = null ; $x = null ; list ( $all , $s , $e , $a , $x ) = $r ;
215 if ( isset ( $cE [ $e ]) or ! in_array ( $e , $q )){ continue ;} // Empty/unopen
216 if ( $p == $e ){ array_pop ( $q
); echo '</' , $e
, '>' ; unset ( $e
); continue ;} // Last open
217 $add = '' ; // Nesting - close open tags that need to be
218 for ( $j =- 1 , $cj = count ( $q ); ++
$j < $cj ;){
219 if (( $d = array_pop ( $q )) == $e ){ break ;}
220 else {$add
.= "</{$d}>" ;}
222 echo $add , '</' , $e , '>' ; unset ( $e ); continue ;
225 // $cB ele needs $eB ele as child
226 if ( isset ( $cB [ $e ]) && strlen ( trim ( $x ))){
227 $t [ $i ] = " {$e}{ $a}>" ;
228 array_splice ( $t , $i +
1 , 0 , 'div>' . $x ); unset ( $e , $x ); ++
$ci ; -- $i ; continue ;
230 if ((( $ql && isset ( $cB [ $p ])) or ( isset ( $cB [ $in ]) && ! $ql )) && ! isset ( $eB [ $e ]) && ! isset ( $ok [ $e ])){
231 array_splice ( $t , $i , 0 , 'div>' ); unset ( $e , $x ); ++
$ci ; -- $i ; continue ;
233 // if no open ele, $in = parent; mostly immediate parent-child relation should hold
234 if (! $ql or ! isset ( $eN [ $e ]) or ! array_intersect ( $q , $cN2 )){
236 if ( $ql && isset ( $cT [ $p ])){ echo '</' , array_pop ( $q
), '>' ; unset ( $e
, $x
); -- $i
;}
239 if (! isset ( $cE [ $e ])){ $q
[] = $e
;}
240 echo '<' , $e , $a , '>' ; unset ( $e ); continue ;
242 // specific parent-child
243 if ( isset ( $cS [ $p ][ $e ])){
244 if (! isset ( $cE [ $e ])){ $q
[] = $e
;}
245 echo '<' , $e , $a , '>' ; unset ( $e ); continue ;
250 for ( $k =- 1 , $kc = count ( $q ); ++
$k < $kc ;){
253 if ( isset ( $cS [ $d ])){ $q2
[] = $d
; continue ;}
254 $ok2 = isset ( $cI [ $d ]) ? $eI : $eF ;
255 if ( isset ( $cO [ $d ])){ $ok2
= $ok2 + $cO
[ $d
];}
256 if ( isset ( $cN [ $d ])){ $ok2
= array_diff_assoc ( $ok2
, $cN
[ $d
]);}
257 if (! isset ( $ok2 [ $e ])){
258 if (! $k && ! isset ( $inOk [ $e ])){ continue 2 ;}
260 for (; ++
$k < $kc ;){ $add
= "</{$q[$k]}> {$add} " ;}
266 if (! isset ( $cE [ $e ])){ $q
[] = $e
;}
267 echo $add , '<' , $e , $a , '>' ; unset ( $e ); continue ;
274 if ( isset ( $cS [ $p ])){ $ok
= $cS
[ $p
];}
275 elseif ( isset ( $cI [ $p ])){ $ok
= $eI
; $cI
[ 'del' ] = 1 ; $cI
[ 'ins' ] = 1 ;}
276 elseif ( isset ( $cF [ $p ])){ $ok
= $eF
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
277 elseif ( isset ( $cB [ $p ])){ $ok
= $eB
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
278 if ( isset ( $cO [ $p ])){ $ok
= $ok + $cO
[ $p
];}
279 if ( isset ( $cN [ $p ])){ $ok
= array_diff_assoc ( $ok
, $cN
[ $p
]);}
280 } else {$ok
= $inOk
; unset ( $cI
[ 'del' ], $cI
[ 'ins' ]);}
281 if ( isset ( $e ) && ( $do == 1 or ( isset ( $ok [ '#pcdata' ]) && ( $do == 3 or $do == 5 )))){
282 echo '<' , $s , $e , $a , '>' ;
285 if ( strlen ( trim ( $x )) && (( $ql && isset ( $cB [ $p ])) or ( isset ( $cB [ $in ]) && ! $ql ))){
286 echo '<div>' , $x , '</div>' ;
288 elseif ( $do < 3 or isset ( $ok [ '#pcdata' ])){ echo $x
;}
289 elseif ( strpos ( $x , " \x02\x04 " )){
290 foreach ( preg_split ( '`( \x01\x02 [^ \x01\x02 ]+ \x02\x01 )`' , $x , - 1 , PREG_SPLIT_DELIM_CAPTURE
| PREG_SPLIT_NO_EMPTY
) as $v ){
291 echo ( substr ( $v , 0 , 2 ) == " \x01\x02 " ? $v : ( $do > 4 ? preg_replace ( '`\S`' , '' , $v ) : '' ));
293 } elseif ( $do > 4 ){ echo preg_replace ( '`\S`' , '' , $x
);}
295 while (! empty ( $q ) && ( $e = array_pop ( $q ))){ echo '</' , $e
, '>' ;}
296 $o = ob_get_contents ();
302 public static function hl_cmtcd ( $t ){
303 // comment/CDATA sec handler
306 if (!( $v = $C [ $n = $t [ 3 ] == '-' ? 'comment' : 'cdata' ])){ return $t
;}
307 if ( $v == 1 ){ return '' ;}
309 if ( substr (( $t = preg_replace ( '`--+`' , '-' , substr ( $t , 4 , - 3 ))), - 1 ) != ' ' ){ $t
.= ' ' ;}
311 else {$t
= substr ( $t
, 1 , - 1 );}
312 $t = $v == 2 ? str_replace ( array ( '&' , '<' , '>' ), array ( '&' , '<' , '>' ), $t ) : $t ;
313 return str_replace ( array ( '&' , '<' , '>' ), array ( " \x03 " , " \x04 " , " \x05 " ), ( $n == 'comment' ? " \x01\x02\x04 !-- $t--\x05\x02\x01 " : " \x01\x01\x04 $t\x05\x01\x01 " ));
317 public static function hl_ent ( $t ){
321 static $U = array ( 'quot' => 1 , 'amp' => 1 , 'lt' => 1 , 'gt' => 1 );
322 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' );
324 return ( $C [ 'and_mark' ] ? " \x06 " : '&' ). ( isset ( $U [ $t ]) ? $t : ( isset ( $N [ $t ]) ? (! $C [ 'named_entity' ] ? '#' . ( $C [ 'hexdec_entity' ] > 1 ? 'x' . dechex ( $N [ $t ]) : $N [ $t ]) : $t ) : 'amp;' . $t )). ';' ;
326 if (( $n = ctype_digit ( $t = substr ( $t , 1 )) ? intval ( $t ) : hexdec ( substr ( $t , 1 ))) < 9 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 ))){
327 return ( $C [ 'and_mark' ] ? " \x06 " : '&' ). "amp;# {$t} ;" ;
329 return ( $C [ 'and_mark' ] ? " \x06 " : '&' ). '#' . ((( ctype_digit ( $t ) && $C [ 'hexdec_entity' ] < 2 ) or ! $C [ 'hexdec_entity' ]) ? $n : 'x' . dechex ( $n )). ';' ;
333 public static function hl_prot ( $p , $c = null ){
337 if ( $c == null ){ $c
= 'style' ; $b
= $p
[ 1 ]; $a
= $p
[ 3 ]; $p
= trim ( $p
[ 2 ]);}
338 $c = isset ( $C [ 'schemes' ][ $c ]) ? $C [ 'schemes' ][ $c ] : $C [ 'schemes' ][ '*' ];
339 static $d = 'denied:' ;
340 if ( isset ( $c [ '!' ]) && substr ( $p , 0 , 7 ) != $d ){ $p
= "$d$p" ;}
341 if ( isset ( $c [ '*' ]) or ! strcspn ( $p , '#?;' ) or ( substr ( $p , 0 , 7 ) == $d )){ return "{$b} {$p}{ $a}" ;} // All ok, frag, query, param
342 if ( preg_match ( '`^([a-z\d\-+.&#; ]+?)(:|&#(58|x3a);|%3a| \\\\ 0 {0,4} 3a).`i' , $p , $m ) && ! isset ( $c [ strtolower ( $m [ 1 ])])){ // Denied prot
343 return " {$b}{ $d} {$p}{ $a}" ;
346 if ( $C [ 'abs_url' ] == - 1 && strpos ( $p , $C [ 'base_url' ]) === 0 ){ // Make url rel
347 $p = substr ( $p , strlen ( $C [ 'base_url' ]));
348 } elseif ( empty ( $m [ 1 ])){ // Make URL abs
349 if ( substr ( $p , 0 , 2 ) == '//' ){ $p
= substr ( $C
[ 'base_url' ], 0 , strpos ( $C
[ 'base_url' ], ':' ) +
1 ). $p
;}
350 elseif ( $p [ 0 ] == '/' ){ $p
= preg_replace ( '`(^.+?://[^/]+)(.*)`' , '$1' , $C
[ 'base_url' ]). $p
;}
351 elseif ( strcspn ( $p , './' )){ $p
= $C
[ 'base_url' ]. $p
;}
353 preg_match ( '`^([a-zA-Z\d\-+.]+://[^/]+)(.*)`' , $C [ 'base_url' ], $m );
354 $p = preg_replace ( '`(?<=/)\./`' , '' , $m [ 2 ]. $p );
355 while ( preg_match ( '`(?<=/)([^/] {3,} |[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`' , $p )){
356 $p = preg_replace ( '`(?<=/)([^/] {3,} |[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`' , '' , $p );
362 return " {$b}{ $p} {$a} " ;
366 public static function hl_regex ( $p ){
368 if ( empty ( $p )){ return 0 ;}
369 if ( $t = ini_get ( 'track_errors' )){ $o
= isset ( $php_errormsg
) ? $php_errormsg
: null ;}
370 else {
ini_set ( 'track_errors' , 1 );}
371 unset ( $php_errormsg );
372 if (( $d = ini_get ( 'display_errors' ))){ ini_set ( 'display_errors' , 0 );}
374 if ( $d ){ ini_set ( 'display_errors' , 1 );}
375 $r = isset ( $php_errormsg ) ? 0 : 1 ;
376 if ( $t ){ $php_errormsg
= isset ( $o
) ? $o
: null ;}
377 else {
ini_set ( 'track_errors' , 0 );}
382 public static function hl_spec ( $t ){
385 $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 )));
386 for ( $i = count (( $t = explode ( ';' , $t ))); -- $i >= 0 ;){
388 if ( empty ( $w ) or ( $e = strpos ( $w , '=' )) === false or ! strlen (( $a = substr ( $w , $e +
1 )))){ continue ;}
390 foreach ( explode ( ',' , $a ) as $v ){
391 if (! preg_match ( '`^([a-z:\-\*]+)(?:\((.*?)\))?`i' , $v , $m )){ continue ;}
392 if (( $x = strtolower ( $m [ 1 ])) == '-*' ){ $n
[ '*' ] = 1 ; continue ;}
393 if ( $x [ 0 ] == '-' ){ $n
[ substr ( $x
, 1 )] = 1 ; continue ;}
394 if (! isset ( $m [ 2 ])){ $y
[ $x
] = 1 ; continue ;}
395 foreach ( explode ( '/' , $m [ 2 ]) as $m ){
396 if ( empty ( $m ) or ( $p = strpos ( $m , '=' )) == 0 or $p < 5 ){ $y
[ $x
] = 1 ; continue ;}
397 $y [ $x ][ strtolower ( substr ( $m , 0 , $p ))] = str_replace ( array ( " \x01 " , " \x02 " , " \x03 " , " \x04 " , " \x05 " , " \x06 " , " \x07 " , " \x08 " ), array ( ";" , "|" , "~" , " " , "," , "/" , "(" , ")" ), substr ( $m , $p +
1 ));
399 if ( isset ( $y [ $x ][ 'match' ]) && ! htmLawed
:: hl_regex ( $y [ $x ][ 'match' ])){ unset ( $y
[ $x
][ 'match' ]);}
400 if ( isset ( $y [ $x ][ 'nomatch' ]) && ! htmLawed
:: hl_regex ( $y [ $x ][ 'nomatch' ])){ unset ( $y
[ $x
][ 'nomatch' ]);}
402 if (! count ( $y ) && ! count ( $n )){ continue ;}
403 foreach ( explode ( ',' , substr ( $w , 0 , $e )) as $v ){
404 if (! strlen (( $v = strtolower ( $v )))){ continue ;}
405 if ( count ( $y )){ $s
[ $v
] = $y
;}
406 if ( count ( $n )){ $s
[ $v
][ 'n' ] = $n
;}
413 public static function hl_tag ( $t ){
414 // tag/attribute handler
418 if ( $t == '< ' ){ return '< ' ;}
419 if ( $t == '>' ){ return '>' ;}
420 if (! preg_match ( '`^<(/?)([a-zA-Z][a-zA-Z1-6]*)([^>]*?)\s?>$`m' , $t , $m )){
421 return str_replace ( array ( '<' , '>' ), array ( '<' , '>' ), $t );
422 } elseif (! isset ( $C [ 'elements' ][( $e = strtolower ( $m [ 2 ]))])){
423 return (( $C [ 'keep_bad' ] %
2 ) ? str_replace ( array ( '<' , '>' ), array ( '<' , '>' ), $t ) : '' );
426 $a = str_replace ( array ( " \n " , " \r " , " \t " ), ' ' , trim ( $m [ 3 ]));
428 static $eD = array ( 'applet' => 1 , 'center' => 1 , 'dir' => 1 , 'embed' => 1 , 'font' => 1 , 'isindex' => 1 , 'menu' => 1 , 's' => 1 , 'strike' => 1 , 'u' => 1 ); // Deprecated
429 if ( $C [ 'make_tag_strict' ] && isset ( $eD [ $e ])){
430 $trt = htmLawed
:: hl_tag2 ( $e , $a , $C [ 'make_tag_strict' ]);
431 if (! $e ){ return (( $C
[ 'keep_bad' ] %
2 ) ? str_replace ( array ( '<' , '>' ), array ( '<' , '>' ), $t
) : '' );}
434 static $eE = array ( 'area' => 1 , 'br' => 1 , 'col' => 1 , 'embed' => 1 , 'hr' => 1 , 'img' => 1 , 'input' => 1 , 'isindex' => 1 , 'param' => 1 ); // Empty ele
436 return (! isset ( $eE [ $e ]) ? ( empty ( $C [ 'hook_tag' ]) ? "</ $e >" : $C [ 'hook_tag' ]( $e )) : (( $C [ 'keep_bad' ]) %
2 ? str_replace ( array ( '<' , '>' ), array ( '<' , '>' ), $t ) : '' ));
440 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 ), '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
441 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
442 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
443 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
445 if ( $C [ 'lc_std_val' ]){
446 // predef attr vals for $eAL & $aNE ele
447 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 );
448 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 );
449 $lcase = isset ( $eAL [ $e ]) ? 1 : 0 ;
453 if ( $C [ 'no_deprecated_attr' ]){
454 // dep attr:applicable ele
455 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 ));
456 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 );
457 $depTr = isset ( $eAD [ $e ]) ? 1 : 0 ;
461 if ( strpos ( $a , " \x01 " ) !== false ){ $a
= preg_replace ( '` \x01 [^ \x01 ]* \x01 `' , '' , $a
);} // No comment/CDATA sec
462 $mode = 0 ; $a = trim ( $a , ' /' ); $aA = array ();
467 if ( preg_match ( '`^[a-zA-Z][\-a-zA-Z:]+`' , $a , $m )){
468 $nm = strtolower ( $m [ 0 ]);
469 $w = $mode = 1 ; $a = ltrim ( substr_replace ( $a , '' , 0 , strlen ( $m [ 0 ])));
472 if ( $a [ 0 ] == '=' ){ // =
473 $w = 1 ; $mode = 2 ; $a = ltrim ( $a , '= ' );
475 $w = 1 ; $mode = 0 ; $a = ltrim ( $a );
478 break ; case 2 : // Val
479 if ( preg_match ( '`^((?:"[^"]*")|(?: \' [^ \' ]* \' )|(?:\s*[^\s" \' ]+))(.*)`' , $a , $m )){
480 $a = ltrim ( $m [ 2 ]); $m = $m [ 1 ]; $w = 1 ; $mode = 0 ;
481 $aA [ $nm ] = trim (( $m [ 0 ] == '"' or $m [ 0 ] == ' \' ' ) ? substr ( $m , 1 , - 1 ) : $m );
485 if ( $w == 0 ){ // Parse errs, deal with space, " & '
486 $a = preg_replace ( '`^(?:"[^"]*("|$)| \' [^ \' ]*( \' |$)|\S)*\s*`' , '' , $a );
490 if ( $mode == 1 ){ $aA
[ $nm
] = '' ;}
494 $rl = isset ( $S [ $e ]) ? $S [ $e ] : array ();
495 $a = array (); $nfr = 0 ;
496 foreach ( $aA as $k => $v ){
497 if ((( isset ( $C [ 'deny_attribute' ][ '*' ]) ? isset ( $C [ 'deny_attribute' ][ $k ]) : ! isset ( $C [ 'deny_attribute' ][ $k ])) && ( isset ( $aN [ $k ][ $e ]) or ( isset ( $aNU [ $k ]) && ! isset ( $aNU [ $k ][ $e ]))) && ! isset ( $rl [ 'n' ][ $k ]) && ! isset ( $rl [ 'n' ][ '*' ])) or isset ( $rl [ $k ])){
498 if ( isset ( $aNE [ $k ])){ $v
= $k
;}
499 elseif (! empty ( $lcase ) && (( $e != 'button' or $e != 'input' ) or $k == 'type' )){ // Rather loose but ?not cause issues
500 $v = ( isset ( $aNL [( $v2 = strtolower ( $v ))])) ? $v2 : $v ;
502 if ( $k == 'style' && ! $C [ 'style_pass' ]){
503 if ( false !== strpos ( $v , '&#' )){
504 static $sC = array ( ' ' => ' ' , ' ' => ' ' , 'E' => 'e' , 'E' => 'e' , 'e' => 'e' , 'e' => 'e' , 'X' => 'x' , 'X' => 'x' , 'x' => 'x' , 'x' => 'x' , 'P' => 'p' , 'P' => 'p' , 'p' => 'p' , 'p' => 'p' , 'S' => 's' , 'S' => 's' , 's' => 's' , 's' => 's' , 'I' => 'i' , 'I' => 'i' , 'i' => 'i' , 'i' => 'i' , 'O' => 'o' , 'O' => 'o' , 'o' => 'o' , 'o' => 'o' , 'N' => 'n' , 'N' => 'n' , 'n' => 'n' , 'n' => 'n' , 'U' => 'u' , 'U' => 'u' , 'u' => 'u' , 'u' => 'u' , 'R' => 'r' , 'R' => 'r' , 'r' => 'r' , 'r' => 'r' , 'L' => 'l' , 'L' => 'l' , 'l' => 'l' , 'l' => 'l' , '(' => '(' , '(' => '(' , ')' => ')' , ')' => ')' , ' ' => ':' , ' ' => ':' , '"' => '"' , '"' => '"' , ''' => "'" , ''' => "'" , '/' => '/' , '/' => '/' , '*' => '*' , '*' => '*' , '\' => ' \\ ' , '\' => ' \\ ' );
507 $v = preg_replace_callback ( '`(url(?:\()(?: )*(?: \' |"|&(?:quot|apos);)?)(.+?)((?: \' |"|&(?:quot|apos);)?(?: )*(?:\)))`iS' , 'htmLawed::hl_prot' , $v );
508 $v = ! $C [ 'css_expression' ] ? preg_replace ( '`expression`i' , ' ' , preg_replace ( '` \\\\ \S|(/|(%2f))(\*|(%2a))`i' , ' ' , $v )) : $v ;
509 } elseif ( isset ( $aNP [ $k ]) or strpos ( $k , 'src' ) !== false or $k [ 0 ] == 'o' ){
510 $v = str_replace ( " \xad " , ' ' , ( strpos ( $v , '&' ) !== false ? str_replace ( array ( '­' , '­' , '­' ), ' ' , $v ) : $v ));
511 $v = htmLawed
:: hl_prot ( $v , $k );
512 if ( $k == 'href' ){ // X-spam
513 if ( $C [ 'anti_mail_spam' ] && strpos ( $v , 'mailto:' ) === 0 ){
514 $v = str_replace ( '@' , htmlspecialchars ( $C [ 'anti_mail_spam' ]), $v );
515 } elseif ( $C [ 'anti_link_spam' ]){
516 $r1 = $C [ 'anti_link_spam' ][ 1 ];
517 if (! empty ( $r1 ) && preg_match ( $r1 , $v )){ continue ;}
518 $r0 = $C [ 'anti_link_spam' ][ 0 ];
519 if (! empty ( $r0 ) && preg_match ( $r0 , $v )){
520 if ( isset ( $a [ 'rel' ])){
521 if (! preg_match ( '` \b nofollow \b `i' , $a [ 'rel' ])){ $a
[ 'rel' ] .= ' nofollow' ;}
522 } elseif ( isset ( $aA [ 'rel' ])){
523 if (! preg_match ( '` \b nofollow \b `i' , $aA [ 'rel' ])){ $nfr
= 1 ;}
524 } else {$a
[ 'rel' ] = 'nofollow' ;}
529 if ( isset ( $rl [ $k ]) && is_array ( $rl [ $k ]) && ( $v = htmLawed
:: hl_attrval ( $v , $rl [ $k ])) === 0 ){ continue ;}
530 $a [ $k ] = str_replace ( '"' , '"' , $v );
533 if ( $nfr ){ $a
[ 'rel' ] = isset ( $a
[ 'rel' ]) ? $a
[ 'rel' ]. ' nofollow' : 'nofollow' ;}
536 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' ));
538 foreach ( $eAR [ $e ] as $k => $v ){
539 if (! isset ( $a [ $k ])){ $a
[ $k
] = isset ( $v
[ 0 ]) ? $v
: $k
;}
546 foreach ( $a as $k => $v ){
547 if ( $k == 'style' or ! isset ( $aND [ $k ][ $e ])){ continue ;}
550 if ( $e == 'img' && ( $v == 'left' or $v == 'right' )){ $c
[] = 'float: ' . $v
;}
551 elseif (( $e == 'div' or $e == 'table' ) && $v == 'center' ){ $c
[] = 'margin: auto' ;}
552 else {$c
[] = 'text-align: ' . $v
;}
553 } elseif ( $k == 'bgcolor' ){
554 unset ( $a [ 'bgcolor' ]);
555 $c [] = 'background-color: ' . $v ;
556 } elseif ( $k == 'border' ){
557 unset ( $a [ 'border' ]); $c [] = "border: {$v} px" ;
558 } elseif ( $k == 'bordercolor' ){
559 unset ( $a [ 'bordercolor' ]); $c [] = 'border-color: ' . $v ;
560 } elseif ( $k == 'clear' ){
561 unset ( $a [ 'clear' ]); $c [] = 'clear: ' . ( $v != 'all' ? $v : 'both' );
562 } elseif ( $k == 'compact' ){
563 unset ( $a [ 'compact' ]); $c [] = 'font-size: 85%' ;
564 } elseif ( $k == 'height' or $k == 'width' ){
565 unset ( $a [ $k ]); $c [] = $k . ': ' . ( $v [ 0 ] != '*' ? $v . ( ctype_digit ( $v ) ? 'px' : '' ) : 'auto' );
566 } elseif ( $k == 'hspace' ){
567 unset ( $a [ 'hspace' ]); $c [] = "margin-left: {$v} px; margin-right: {$v} px" ;
568 } elseif ( $k == 'language' && ! isset ( $a [ 'type' ])){
569 unset ( $a [ 'language' ]);
570 $a [ 'type' ] = 'text/' . strtolower ( $v );
571 } elseif ( $k == 'name' ){
572 if ( $C [ 'no_deprecated_attr' ] == 2 or ( $e != 'a' && $e != 'map' )){ unset ( $a
[ 'name' ]);}
573 if (! isset ( $a [ 'id' ]) && preg_match ( '`[a-zA-Z][a-zA-Z\d.:_\-]*`' , $v )){ $a
[ 'id' ] = $v
;}
574 } elseif ( $k == 'noshade' ){
575 unset ( $a [ 'noshade' ]); $c [] = 'border-style: none; border: 0; background-color: gray; color: gray' ;
576 } elseif ( $k == 'nowrap' ){
577 unset ( $a [ 'nowrap' ]); $c [] = 'white-space: nowrap' ;
578 } elseif ( $k == 'size' ){
579 unset ( $a [ 'size' ]); $c [] = 'size: ' . $v . 'px' ;
580 } elseif ( $k == 'start' or $k == 'value' ){
582 } elseif ( $k == 'type' ){
584 static $ol_type = array ( 'i' => 'lower-roman' , 'I' => 'upper-roman' , 'a' => 'lower-latin' , 'A' => 'upper-latin' , '1' => 'decimal' );
585 $c [] = 'list-style-type: ' . ( isset ( $ol_type [ $v ]) ? $ol_type [ $v ] : 'decimal' );
586 } elseif ( $k == 'vspace' ){
587 unset ( $a [ 'vspace' ]); $c [] = "margin-top: {$v} px; margin-bottom: {$v} px" ;
591 $c = implode ( '; ' , $c );
592 $a [ 'style' ] = isset ( $a [ 'style' ]) ? rtrim ( $a [ 'style' ], ' ;' ). '; ' . $c . ';' : $c . ';' ;
596 if ( $C [ 'unique_ids' ] && isset ( $a [ 'id' ])){
597 if (! preg_match ( '`^[A-Za-z][A-Za-z0-9_\-.:]*$`' , ( $id = $a [ 'id' ])) or ( isset ( $GLOBALS [ 'hl_Ids' ][ $id ]) && $C [ 'unique_ids' ] == 1 )){ unset ( $a [ 'id' ]);
599 while ( isset ( $GLOBALS [ 'hl_Ids' ][ $id ])){ $id
= $C
[ 'unique_ids' ]. $id
;}
600 $GLOBALS [ 'hl_Ids' ][( $a [ 'id' ] = $id )] = 1 ;
604 if ( $C [ 'xml:lang' ] && isset ( $a [ 'lang' ])){
605 $a [ 'xml:lang' ] = isset ( $a [ 'xml:lang' ]) ? $a [ 'xml:lang' ] : $a [ 'lang' ];
606 if ( $C [ 'xml:lang' ] == 2 ){ unset ( $a
[ 'lang' ]);}
608 // for transformed tag
610 $a [ 'style' ] = isset ( $a [ 'style' ]) ? rtrim ( $a [ 'style' ], ' ;' ). '; ' . $trt : $trt ;
612 // return with empty ele /
613 if ( empty ( $C [ 'hook_tag' ])){
615 foreach ( $a as $k => $v ){ $aA
.= " {$k}= \"{ $v} \" " ;}
616 return "< {$e}{ $aA}" . ( isset ( $eE [ $e ]) ? ' /' : '' ). '>' ;
618 else {
return $C
[ 'hook_tag' ]( $e
, $a
);}
622 public static function hl_tag2 (& $e , & $a , $t = 1 ){
624 if ( $e == 'center' ){ $e
= 'div' ; return 'text-align: center;' ;}
625 if ( $e == 'dir' or $e == 'menu' ){ $e
= 'ul' ; return '' ;}
626 if ( $e == 's' or $e == 'strike' ){ $e
= 'span' ; return 'text-decoration: line-through;' ;}
627 if ( $e == 'u' ){ $e
= 'span' ; return 'text-decoration: underline;' ;}
628 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%' );
631 if ( preg_match ( '`face\s*=\s*( \' |")([^=]+?) \\ 1`i' , $a , $m ) or preg_match ( '`face\s*=(\s*)(\S+)`i' , $a , $m )){
632 $a2 .= ' font-family: ' . str_replace ( '"' , ' \' ' , trim ( $m [ 2 ])). ';' ;
634 if ( preg_match ( '`color\s*=\s*( \' |")?(.+?)( \\ 1|\s|$)`i' , $a , $m )){
635 $a2 .= ' color: ' . trim ( $m [ 2 ]). ';' ;
637 if ( preg_match ( '`size\s*=\s*( \' |")?(.+?)( \\ 1|\s|$)`i' , $a , $m ) && isset ( $fs [( $m = trim ( $m [ 2 ]))])){
638 $a2 .= ' font-size: ' . $fs [ $m ]. ';' ;
640 $e = 'span' ; return ltrim ( $a2 );
642 if ( $t == 2 ){ $e
= 0 ; return 0 ;}
647 public static function hl_tidy ( $t , $w , $p ){
649 if ( strpos ( ' pre,script,textarea' , " $p ," )){ return $t
;}
650 $t = str_replace ( ' </' , '</' , preg_replace ( array ( '`(<\w[^>]*(?<!/)>)\s+`' , '`\s+`' , '`(<\w[^>]*(?<!/)>) `' ), array ( ' $1' , ' ', ' $1' ), preg_replace_callback ( array ( '`(<(!\[CDATA\[))(.+?)(\]\]>)`sm' , '`(<(!--))(.+?)(-->)`sm' , '`(<(pre|script|textarea)[^>]*?>)(.+?)(</\2>)`sm' ), create_function ( ' $m' , ' return $m [ 1 ]. str_replace ( array ( "<" , ">" , " \n " , " \r " , " \t " , " " ), array ( " \x01 " , " \x02 " , " \x03 " , " \x04 " , " \x05 " , " \x07 " ), $m [ 3 ]). $m [ 4 ]; '), $t )));
651 if(( $w = strtolower( $w )) == -1){
652 return str_replace(array(" \x01 ", " \x02 ", " \x03 ", " \x04 ", " \x05 ", " \x07 "), array(' < ', ' > ', " \n ", " \r ", " \t ", ' '), $t );
654 $s = strpos(" $w" , ' t
') ? " \t " : ' ';
655 $s = preg_match(' `\d`
', $w , $m ) ? str_repeat( $s , $m [0]) : str_repeat( $s , ( $s == " \t " ? 1 : 2));
656 $N = preg_match(' `
[ ts
]([ 1 - 9 ]) `
', $w , $m ) ? $m [1] : 0;
658 $b = array(' button
'=>1, ' input
'=>1, ' option
'=>1);
659 $c = array(' caption
'=>1, ' dd
'=>1, ' dt
'=>1, ' h1
'=>1, ' h2
'=>1, ' h3
'=>1, ' h4
'=>1, ' h5
'=>1, ' h6
'=>1, ' isindex
'=>1, ' label
'=>1, ' legend
'=>1, ' li
'=>1, ' object '=>1, ' p
'=>1, ' pre
'=>1, ' td
'=>1, ' textarea
'=>1, ' th
'=>1);
660 $d = array(' address
'=>1, ' blockquote
'=>1, ' center
'=>1, ' colgroup
'=>1, ' dir
'=>1, ' div
'=>1, ' dl
'=>1, ' fieldset
'=>1, ' form
'=>1, ' hr
'=>1, ' iframe
'=>1, ' map
'=>1, ' menu
'=>1, ' noscript
'=>1, ' ol
'=>1, ' optgroup
'=>1, ' rbc
'=>1, ' rtc
'=>1, ' ruby
'=>1, ' script
'=>1, ' select
'=>1, ' table
'=>1, ' tbody
'=>1, ' tfoot
'=>1, ' thead
'=>1, ' tr
'=>1, ' ul
'=>1);
661 $T = explode(' < ', $t );
667 if(isset( $d [ $p ])) {echo str_repeat($s, ++$n);}
668 echo ltrim(array_shift( $t ));
669 for( $i =-1, $j =count( $t ); ++ $i < $j ;){
670 $r = ' '; list( $e , $r ) = explode(' > ', $t [ $i ]);
671 $x = $e [0] == ' / ' ? 0 : (substr( $e , -1) == ' / ' ? 1 : ( $e [0] != ' ! ' ? 2 : -1));
672 $y = ! $x ? ltrim( $e , ' / ') : ( $x > 0 ? substr( $e , 0, strcspn( $e , ' ')) : 0);
676 if( $n ) {echo "\n", str_repeat($s, --$n), "$e\n", str_repeat($s, $n);}
677 else {++$N; ob_end_clean(); continue 2;}
679 else {echo "\n", str_repeat($s, $n), "$e\n", str_repeat($s, ($x != 1 ? ++$n : $n));}
680 echo ltrim( $r ); continue;
682 $f = " \n ". str_repeat( $s , $n );
684 if(! $x ) {echo $e, $f, ltrim($r);}
685 else {echo $f, $e, $r;}
686 }elseif(isset( $b [ $y ])){echo $f , $e , $r ;
687 }elseif(isset( $a [ $y ])){echo $e , $f , ltrim( $r );
688 }elseif(! $y ){echo $f , $e , $f , ltrim( $r );
693 $t = preg_replace(' `
[\n] \s
*?[\n] +`
', " \n ", ob_get_contents());
695 if(( $l = strpos(" $w" , ' r
') ? (strpos(" $w" , ' n
') ? " \r\n " : " \r ") : 0)){
696 $t = str_replace(" \n ", $l , $t );
698 return str_replace(array(" \x01 ", " \x02 ", " \x03 ", " \x04 ", " \x05 ", " \x07 "), array(' < ', ' > ', " \n ", " \r ", " \t ", ' '), $t );
702 public static function hl_version(){
708 public static function kses( $t , $h , $p =array(' http
', ' https
', ' ftp
', ' news
', ' nntp
', ' telnet
', ' gopher
', ' mailto
')){
710 foreach( $h as $k => $v ){
711 $h [ $k ][' n
'][' * '] = 1;
713 $C [' cdata
'] = $C [' comment
'] = $C [' make_tag_strict
'] = $C [' no_deprecated_attr
'] = $C [' unique_ids
'] = 0;
715 $C [' elements
'] = count( $h ) ? strtolower(implode(' , ', array_keys( $h ))) : ' -* ';
716 $C [' hook
'] = ' htmLawed
:: kses_hook
';
717 $C [' schemes
'] = ' *: '. implode(' , ', $p );
718 return htmLawed::hl( $t , $C , $h );
722 public static function kses_hook( $t , & $C , & $S ){