Changeset 2896

Show
Ignore:
Timestamp:
09/20/05 22:18:47 (3 years ago)
Author:
ryan
Message:

Filter posts with kses for users who do not have the unfiltered_html cap. Props donncha. fixes #1674

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/wp-includes/default-filters.php

    r2517 r2896  
    2626 
    2727add_filter('pre_comment_content', 'stripslashes', 1); 
    28 add_filter('pre_comment_content', 'wp_filter_kses'); 
    2928add_filter('pre_comment_content', 'wp_rel_nofollow', 15); 
    3029add_filter('pre_comment_content', 'balanceTags', 30); 
  • trunk/wp-includes/kses.php

    r2151 r2896  
    11<?php 
     2 
    23// Added wp_ prefix to avoid conflicts with existing kses users 
    34# kses 0.2.1 - HTML/XHTML filter that only allows some elements and attributes 
     
    78# E-mail:      metaur at users dot sourceforge dot net 
    89# Web page:    http://sourceforge.net/projects/kses 
    9 # Paper mail:  (not at the moment) 
     10# Paper mail:  Ulf Harnhammar 
     11#              Ymergatan 17 C 
     12#              753 25  Uppsala 
     13#              SWEDEN 
    1014# 
    1115# [kses strips evil scripts!] 
    1216if (!defined('CUSTOM_TAGS')) 
    1317    define('CUSTOM_TAGS', false); 
    14      
     18 
    1519// You can override this in your my-hacks.php file 
    1620if (!CUSTOM_TAGS) { 
    17 $allowedtags = array( 
    18     'a' => array( 
    19         'href' => array(), 
    20         'title' => array() 
    21         ), 
    22     'abbr' => array('title' => array()), 
    23     'acronym' => array('title' => array()), 
    24     'b' => array(), 
    25     'blockquote' => array('cite' => array()), 
    26 //  'br' => array(), 
    27     'code' => array(), 
    28 //  'del' => array('datetime' => array()), 
    29 //  'dd' => array(), 
    30 //  'dl' => array(), 
    31 //  'dt' => array(), 
    32     'em' => array(), 
    33     'i' => array(), 
    34 //  'ins' => array('datetime' => array(), 'cite' => array()), 
    35 //  'li' => array(), 
    36 //  'ol' => array(), 
    37 //  'p' => array(), 
    38 //  'q' => array(), 
    39     'strike' => array(), 
    40     'strong' => array(), 
    41 //  'sub' => array(), 
    42 //  'sup' => array(), 
    43 //  'u' => array(), 
    44 //  'ul' => array(), 
     21    $allowedposttags = array ('address' => array (), 'applet' => array ('codebase' => array (), 'code' => array (), 'name' => array (), 'alt' => array ()), 'area' => array ('shape' => array (), 'coords' => array (), 'href' => array (), 'alt' => array ()), 'a' => array ('href' => array (), 'title' => array (), 'rel' => array (), 'rev' => array (), 'name' => array ()), 'abbr' => array ('title' => array ()), 'acronym' => array ('title' => array ()), 'b' => array (), 'base' => array ('href' => array ()), 'basefont' => array ('size' => array ()), 'bdo' => array ('dir' => array ()), 'big' => array (), 'blockquote' => array ('cite' => array ()), 'body' => array ('alink' => array (), 'background' => array (), 'bgcolor' => array (), 'link' => array (), 'text' => array (), 'vlink' => array ()), 'br' => array (), 'button' => array ('disabled' => array (), 'name' => array (), 'type' => array (), 'value' => array ()), 'caption' => array ('align' => array ()), 'code' => array (), 'col' => array ('align' => array (), 'char' => array (), 'charoff' => array (), 'span' => array (), 'valign' => array (), 'width' => array ()), 'del' => array ('datetime' => array ()), 'dd' => array (), 'div' => array ('align' => array ()), 'dl' => array (), 'dt' => array (), 'em' => array (), 'fieldset' => array (), 'font' => array ('color' => array (), 'face' => array (), 'size' => array ()), 'form' => array ('action' => array (), 'accept' => array (), 'accept-charset' => array (), 'enctype' => array (), 'method' => array (), 'name' => array (), 'target' => array ()), 'frame' => array ('frameborder' => array (), 'longsesc' => array (), 'marginheight' => array (), 'marginwidth' => array (), 'name' => array (), 'noresize' => array (), 'scrolling' => array (), 'src' => array ()), 'frameset' => array ('cols' => array (), 'rows' => array ()), 'head' => array ('profile' => array ()), 'h1' => array ('align' => array ()), 'h2' => array ('align' => array ()), 'h3' => array ('align' => array ()), 'h4' => array ('align' => array ()), 'h5' => array ('align' => array ()), 'h6' => array ('align' => array ()), 'hr' => array ('align' => array (), 'noshade' => array (), 'size' => array (), 'width' => array ()), 'html' => array ('xmlns' => array ()), 'i' => array (), 'iframe' => array ('align' => array (), 'frameborder' => array (), 'height' => array (), 'londesc' => array (), 'marginheight' => array (), 'marginwidth' => array (), 'name' => array (), 'scrolling' => array (), 'src' => array (), 'width' => array ()), 'img' => array ('alt' => array (), 'align' => array (), 'border' => array (), 'height' => array (), 'hspace' => array (), 'ismap' => array (), 'longdesc' => array (), 'usemap' => array (), 'vspace' => array (), 'src' => array (), 'width' => array ()), 'input' => array ('accept' => array (), 'align' => array (), 'alt' => array (), 'checked' => array (), 'disabled' => array (), 'maxlength' => array (), 'name' => array (), 'readonly' => array (), 'size' => array (), 'src' => array (), 'type' => array (), 'value' => array ()), 'ins' => array ('datetime' => array (), 'cite' => array ()), 'kbd' => array (), 'label' => array ('for' => array ()), 'legend' => array ('align' => array ()), 'li' => array (), 'link' => array ('charset' => array (), 'href' => array (), 'hreflang' => array (), 'media' => array (), 'rel' => array (), 'rev' => array (), 'target' => array (), 'type' => array ()), 'map' => array ('id' => array (), 'name' => array ()), 'menu' => array (), 'meta' => array ('content' => array (), 'http-equiv' => array (), 'name' => array (), 'scheme' => array ()), 'noframes' => array (), 'noscript' => array (), 'object' => array ('align' => array (), 'archive' => array (), 'border' => array (), 'classid' => array (), 'codebase' => array (), 'codetype' => array (), 'data' => array (), 'declare' => array (), 'height' => array (), 'hspace' => array (), 'name' => array (), 'standby' => array (), 'type' => array (), 'usemap' => array (), 'vspace' => array (), 'width' => array ()), 'ol' => array ('compact' => array (), 'start' => array (), 'type' => array ()), 'optgroup' => array ('label' => array (), 'disabled' => array ()), 'option' => array ('disabled' => array (), 'label' => array (), 'selected' => array (), 'value' => array ()), 'p' => array ('align' => array ()), 'param' => array ('name' => array (), 'type' => array (), 'value' => array (), 'valuetype' => array ()), 'pre' => array ('width' => array ()), 'q' => array ('cite' => array ()), 's' => array (), 'strike' => array (), 'strong' => array (), 'style' => array ('type' => array (), 'media' => array ()), 'sub' => array (), 'sup' => array (), 'table' => array ('align' => array (), 'bgcolor' => array (), 'border' => array (), 'cellpadding' => array (), 'cellspacing' => array (), 'frame' => array (), 'rules' => array (), 'summary' => array (), 'width' => array ()), 'tbody' => array ('align' => array (), 'char' => array (), 'charoff' => array (), 'valign' => array ()), 'td' => array ('abbr' => array (), 'align' => array (), 'axis' => array (), 'bgcolor' => array (), 'char' => array (), 'charoff' => array (), 'colspan' => array (), 'headers' => array (), 'height' => array (), 'nowrap' => array (), 'rowspan' => array (), 'scope' => array (), 'valign' => array (), 'width' => array ()), 'textarea' => array ('cols' => array (), 'rows' => array (), 'disabled' => array (), 'name' => array (), 'readonly' => array ()), 'tfoot' => array ('align' => array (), 'char' => array (), 'charoff' => array (), 'valign' => array ()), 'th' => array ('abbr' => array (), 'align' => array (), 'axis' => array (), 'bgcolor' => array (), 'char' => array (), 'charoff' => array (), 'colspan' => array (), 'headers' => array (), 'height' => array (), 'nowrap' => array (), 'rowspan' => array (), 'scope' => array (), 'valign' => array (), 'width' => array ()), 'thead' => array ('align' => array (), 'char' => array (), 'charoff' => array (), 'valign' => array ()), 'title' => array (), 'tr' => array ('align' => array (), 'bgcolor' => array (), 'char' => array (), 'charoff' => array (), 'valign' => array ()), 'tt' => array (), 'u' => array (), 'ul' => array (), 'var' => array ()); 
     22    $allowedtags = array ('a' => array ('href' => array (), 'title' => array ()), 'abbr' => array ('title' => array ()), 'acronym' => array ('title' => array ()), 'b' => array (), 'blockquote' => array ('cite' => array ()), 
     23        //  'br' => array(), 
     24    'code' => array (), 
     25        //  'del' => array('datetime' => array()), 
     26        //  'dd' => array(), 
     27        //  'dl' => array(), 
     28        //  'dt' => array(), 
     29    'em' => array (), 'i' => array (), 
     30        //  'ins' => array('datetime' => array(), 'cite' => array()), 
     31        //  'li' => array(), 
     32        //  'ol' => array(), 
     33        //  'p' => array(), 
     34        //  'q' => array(), 
     35    'strike' => array (), 'strong' => array (), 
     36        //  'sub' => array(), 
     37        //  'sup' => array(), 
     38        //  'u' => array(), 
     39        //  'ul' => array(), 
    4540    ); 
    4641} 
    47 function wp_kses($string, $allowed_html, $allowed_protocols = 
    48                array('http', 'https', 'ftp', 'news', 'nntp', 'feed', 'gopher', 'mailto')) 
    49 ############################################################################### 
    50 # This function makes sure that only the allowed HTML element names, attribute 
    51 # names and attribute values plus only sane HTML entities will occur in 
    52 # $string. You have to remove any slashes from PHP's magic quotes before you 
    53 # call this function. 
    54 ############################################################################### 
    55 
    56   $string = wp_kses_no_null($string); 
    57   $string = wp_kses_js_entities($string); 
    58   $string = wp_kses_normalize_entities($string); 
    59   $string = wp_kses_hook($string); 
    60   $allowed_html_fixed = wp_kses_array_lc($allowed_html); 
    61   return wp_kses_split($string, $allowed_html_fixed, $allowed_protocols); 
     42function wp_kses($string, $allowed_html, $allowed_protocols = array ('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'feed', 'gopher', 'mailto')) 
     43    ############################################################################### 
     44        # This function makes sure that only the allowed HTML element names, attribute 
     45        # names and attribute values plus only sane HTML entities will occur in 
     46        # $string. You have to remove any slashes from PHP's magic quotes before you 
     47        # call this function. 
     48        ############################################################################### 
     49    { 
     50    $string = wp_kses_no_null($string); 
     51    $string = wp_kses_js_entities($string); 
     52    $string = wp_kses_normalize_entities($string); 
     53    $string = wp_kses_hook($string); 
     54    $allowed_html_fixed = wp_kses_array_lc($allowed_html); 
     55    return wp_kses_split($string, $allowed_html_fixed, $allowed_protocols); 
    6256} # function wp_kses 
    6357 
    64  
    6558function wp_kses_hook($string) 
    6659############################################################################### 
     
    6861############################################################################### 
    6962{ 
    70   return $string; 
     63   return $string; 
    7164} # function wp_kses_hook 
    7265 
    73  
    7466function wp_kses_version() 
    7567############################################################################### 
     
    7769############################################################################### 
    7870{ 
    79   return '0.2.1'; 
     71   return '0.2.2'; 
    8072} # function wp_kses_version 
    81  
    8273 
    8374function wp_kses_split($string, $allowed_html, $allowed_protocols) 
     
    8778############################################################################### 
    8879{ 
    89   return preg_replace('%(<'.   # EITHER: < 
    90                       '[^>]*'. # things that aren't > 
    91                       '(>|$)'. # > or end of string 
    92                       '|>)%e', # OR: just a > 
    93                       "wp_kses_split2('\\1', \$allowed_html, ". 
    94                       '$allowed_protocols)', 
    95                       $string); 
     80    return preg_replace('%(<'.# EITHER: < 
     81    '[^>]*'.# things that aren't > 
     82    '(>|$)'.# > or end of string 
     83    '|>)%e', # OR: just a > 
     84    "wp_kses_split2('\\1', \$allowed_html, ".'$allowed_protocols)', $string); 
    9685} # function wp_kses_split 
    97  
    9886 
    9987function wp_kses_split2($string, $allowed_html, $allowed_protocols) 
     
    10593############################################################################### 
    10694{ 
    107   $string = wp_kses_stripslashes($string); 
    108  
    109   if (substr($string, 0, 1) != '<') 
    110     return '&gt;'; 
    111     # It matched a ">" character 
    112  
    113   if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches)) 
    114     return ''; 
    115     # It's seriously malformed 
    116  
    117   $slash = trim($matches[1]); 
    118   $elem = $matches[2]; 
    119   $attrlist = $matches[3]; 
    120  
    121   if (!is_array($allowed_html[strtolower($elem)])) 
    122     return ''; 
    123     # They are using a not allowed HTML element 
    124  
    125   return wp_kses_attr("$slash$elem", $attrlist, $allowed_html, 
    126                    $allowed_protocols); 
     95    $string = wp_kses_stripslashes($string); 
     96 
     97    if (substr($string, 0, 1) != '<') 
     98        return '&gt;'; 
     99    # It matched a ">" character 
     100 
     101    if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches)) 
     102        return ''; 
     103    # It's seriously malformed 
     104 
     105    $slash = trim($matches[1]); 
     106    $elem = $matches[2]; 
     107    $attrlist = $matches[3]; 
     108 
     109    if (!@ is_array($allowed_html[strtolower($elem)])) 
     110        return ''; 
     111    # They are using a not allowed HTML element 
     112 
     113    if ($slash != '') 
     114        return "<$slash$elem>"; 
     115    # No attributes are allowed for closing elements 
     116 
     117    return wp_kses_attr("$slash$elem", $attrlist, $allowed_html, $allowed_protocols); 
    127118} # function wp_kses_split2 
    128  
    129119 
    130120function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) 
     
    138128############################################################################### 
    139129{ 
    140 # Is there a closing XHTML slash at the end of the attributes? 
    141  
    142   $xhtml_slash = ''; 
    143   if (preg_match('%\s/\s*$%', $attr)) 
    144     $xhtml_slash = ' /'; 
    145  
    146 # Are any attributes allowed at all for this element? 
    147  
    148   if (count($allowed_html[strtolower($element)]) == 0) 
    149     return "<$element$xhtml_slash>"; 
    150  
    151 # Split it 
    152  
    153   $attrarr = wp_kses_hair($attr, $allowed_protocols); 
    154  
    155 # Go through $attrarr, and save the allowed attributes for this element 
    156 # in $attr2 
    157  
    158   $attr2 = ''; 
    159  
    160   foreach ($attrarr as $arreach) 
    161   { 
    162     $current = $allowed_html[strtolower($element)] 
    163                             [strtolower($arreach['name'])]; 
    164     if ($current == '') 
    165       continue; # the attribute is not allowed 
    166  
    167     if (!is_array($current)) 
    168       $attr2 .= ' '.$arreach['whole']; 
    169     # there are no checks 
    170  
    171     else 
    172     { 
    173     # there are some checks 
    174       $ok = true; 
    175       foreach ($current as $currkey => $currval) 
    176         if (!wp_kses_check_attr_val($arreach['value'], $arreach['vless'], 
    177                                  $currkey, $currval)) 
    178         { $ok = false; break; } 
    179  
    180       if ($ok) 
    181         $attr2 .= ' '.$arreach['whole']; # it passed them 
    182     } # if !is_array($current) 
    183   } # foreach 
    184  
    185 # Remove any "<" or ">" characters 
    186  
    187   $attr2 = preg_replace('/[<>]/', '', $attr2); 
    188  
    189   return "<$element$attr2$xhtml_slash>"; 
     130    # Is there a closing XHTML slash at the end of the attributes? 
     131 
     132    $xhtml_slash = ''; 
     133    if (preg_match('%\s/\s*$%', $attr)) 
     134        $xhtml_slash = ' /'; 
     135 
     136    # Are any attributes allowed at all for this element? 
     137 
     138    if (@ count($allowed_html[strtolower($element)]) == 0) 
     139        return "<$element$xhtml_slash>"; 
     140 
     141    # Split it 
     142 
     143    $attrarr = wp_kses_hair($attr, $allowed_protocols); 
     144 
     145    # Go through $attrarr, and save the allowed attributes for this element 
     146    # in $attr2 
     147 
     148    $attr2 = ''; 
     149 
     150    foreach ($attrarr as $arreach) { 
     151        if (!@ isset ($allowed_html[strtolower($element)][strtolower($arreach['name'])])) 
     152            continue; # the attribute is not allowed 
     153 
     154        $current = $allowed_html[strtolower($element)][strtolower($arreach['name'])]; 
     155        if ($current == '') 
     156            continue; # the attribute is not allowed 
     157 
     158        if (!is_array($current)) 
     159            $attr2 .= ' '.$arreach['whole']; 
     160        # there are no checks 
     161 
     162        else { 
     163            # there are some checks 
     164            $ok = true; 
     165            foreach ($current as $currkey => $currval) 
     166                if (!wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval)) { 
     167                    $ok = false; 
     168                    break; 
     169                } 
     170 
     171            if ($ok) 
     172                $attr2 .= ' '.$arreach['whole']; # it passed them 
     173        } # if !is_array($current) 
     174    } # foreach 
     175 
     176    # Remove any "<" or ">" characters 
     177 
     178    $attr2 = preg_replace('/[<>]/', '', $attr2); 
     179 
     180    return "<$element$attr2$xhtml_slash>"; 
    190181} # function wp_kses_attr 
    191  
    192182 
    193183function wp_kses_hair($attr, $allowed_protocols) 
     
    201191############################################################################### 
    202192{ 
    203   $attrarr = array(); 
    204   $mode = 0; 
    205   $attrname = ''; 
    206  
    207 # Loop through the whole attribute list 
    208  
    209   while (strlen($attr) != 0) 
    210   { 
    211     $working = 0; # Was the last operation successful? 
    212  
    213     switch ($mode) 
    214     { 
    215       case 0: # attribute name, href for instance 
    216  
    217         if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) 
    218         { 
    219           $attrname = $match[1]; 
    220           $working = $mode = 1; 
    221           $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr); 
    222         } 
    223  
    224         break; 
    225  
    226       case 1: # equals sign or valueless ("selected") 
    227  
    228         if (preg_match('/^\s*=\s*/', $attr)) # equals sign 
    229         { 
    230           $working = 1; $mode = 2; 
    231           $attr = preg_replace('/^\s*=\s*/', '', $attr); 
    232           break; 
    233         } 
    234  
    235         if (preg_match('/^\s+/', $attr)) # valueless 
    236         { 
    237           $working = 1; $mode = 0; 
    238           $attrarr[] = array 
    239                         ('name'  => $attrname, 
    240                          'value' => '', 
    241                          'whole' => $attrname, 
    242                          'vless' => 'y'); 
    243           $attr = preg_replace('/^\s+/', '', $attr); 
    244         } 
    245  
    246         break; 
    247  
    248       case 2: # attribute value, a URL after href= for instance 
    249  
    250         if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) 
    251          # "value" 
    252         { 
    253           $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); 
    254  
    255           $attrarr[] = array 
    256                         ('name'  => $attrname, 
    257                          'value' => $thisval, 
    258                          'whole' => "$attrname=\"$thisval\"", 
    259                          'vless' => 'n'); 
    260           $working = 1; $mode = 0; 
    261           $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); 
    262           break; 
    263         } 
    264  
    265         if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) 
    266          # 'value' 
    267         { 
    268           $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); 
    269  
    270           $attrarr[] = array 
    271                         ('name'  => $attrname, 
    272                          'value' => $thisval, 
    273                          'whole' => "$attrname='$thisval'", 
    274                          'vless' => 'n'); 
    275           $working = 1; $mode = 0; 
    276           $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); 
    277           break; 
    278         } 
    279  
    280         if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) 
    281          # value 
    282         { 
    283           $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); 
    284  
    285           $attrarr[] = array 
    286                         ('name'  => $attrname, 
    287                          'value' => $thisval, 
    288                          'whole' => "$attrname=\"$thisval\"", 
    289                          'vless' => 'n'); 
    290                          # We add quotes to conform to W3C's HTML spec. 
    291           $working = 1; $mode = 0; 
    292           $attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr); 
    293         } 
    294  
    295         break; 
    296     } # switch 
    297  
    298     if ($working == 0) # not well formed, remove and try again 
    299     { 
    300       $attr = wp_kses_html_error($attr); 
    301       $mode = 0; 
    302     } 
    303   } # while 
    304  
    305   if ($mode == 1) 
    306   # special case, for when the attribute list ends with a valueless 
    307   # attribute like "selected" 
    308     $attrarr[] = array 
    309                   ('name'  => $attrname, 
    310                    'value' => '', 
    311                    'whole' => $attrname, 
    312                    'vless' => 'y'); 
    313  
    314   return $attrarr; 
     193    $attrarr = array (); 
     194    $mode = 0; 
     195    $attrname = ''; 
     196 
     197    # Loop through the whole attribute list 
     198 
     199    while (strlen($attr) != 0) { 
     200        $working = 0; # Was the last operation successful? 
     201 
     202        switch ($mode) { 
     203            case 0 : # attribute name, href for instance 
     204 
     205                if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) { 
     206                    $attrname = $match[1]; 
     207                    $working = $mode = 1; 
     208                    $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr); 
     209                } 
     210 
     211                break; 
     212 
     213            case 1 : # equals sign or valueless ("selected") 
     214 
     215                if (preg_match('/^\s*=\s*/', $attr)) # equals sign 
     216                    { 
     217                    $working = 1; 
     218                    $mode = 2; 
     219                    $attr = preg_replace('/^\s*=\s*/', '', $attr); 
     220                    break; 
     221                } 
     222 
     223                if (preg_match('/^\s+/', $attr)) # valueless 
     224                    { 
     225                    $working = 1; 
     226                    $mode = 0; 
     227                    $attrarr[] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); 
     228                    $attr = preg_replace('/^\s+/', '', $attr); 
     229                } 
     230 
     231                break; 
     232 
     233            case 2 : # attribute value, a URL after href= for instance 
     234 
     235                if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) 
     236                    # "value" 
     237                    { 
     238                    $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); 
     239 
     240                    $attrarr[] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); 
     241                    $working = 1; 
     242                    $mode = 0; 
     243                    $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); 
     244                    break; 
     245                } 
     246 
     247                if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) 
     248                    # 'value' 
     249                    { 
     250                    $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); 
     251 
     252                    $attrarr[] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n'); 
     253                    $working = 1; 
     254                    $mode = 0; 
     255                    $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); 
     256                    break; 
     257                } 
     258 
     259                if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) 
     260                    # value 
     261                    { 
     262                    $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); 
     263 
     264                    $attrarr[] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); 
     265                    # We add quotes to conform to W3C's HTML spec. 
     266                    $working = 1; 
     267                    $mode = 0; 
     268                    $attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr); 
     269                } 
     270 
     271                break; 
     272        } # switch 
     273 
     274        if ($working == 0) # not well formed, remove and try again 
     275            { 
     276            $attr = wp_kses_html_error($attr); 
     277            $mode = 0; 
     278        } 
     279    } # while 
     280 
     281    if ($mode == 1) 
     282        # special case, for when the attribute list ends with a valueless 
     283        # attribute like "selected" 
     284        $attrarr[] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); 
     285 
     286    return $attrarr; 
    315287} # function wp_kses_hair 
    316  
    317288 
    318289function wp_kses_check_attr_val($value, $vless, $checkname, $checkvalue) 
     
    323294############################################################################### 
    324295{ 
    325   $ok = true; 
    326  
    327   switch (strtolower($checkname)) 
    328   { 
    329     case 'maxlen': 
    330     # The maxlen check makes sure that the attribute value has a length not 
    331     # greater than the given value. This can be used to avoid Buffer Overflows 
    332     # in WWW clients and various Internet servers. 
    333  
    334       if (strlen($value) > $checkvalue) 
    335         $ok = false; 
    336       break; 
    337  
    338     case 'minlen': 
    339     # The minlen check makes sure that the attribute value has a length not 
    340     # smaller than the given value. 
    341  
    342       if (strlen($value) < $checkvalue) 
    343         $ok = false; 
    344       break; 
    345  
    346     case 'maxval': 
    347     # The maxval check does two things: it checks that the attribute value is 
    348     # an integer from 0 and up, without an excessive amount of zeroes or 
    349     # whitespace (to avoid Buffer Overflows). It also checks that the attribute 
    350     # value is not greater than the given value. 
    351     # This check can be used to avoid Denial of Service attacks. 
    352  
    353       if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value)) 
    354         $ok = false; 
    355       if ($value > $checkvalue) 
    356         $ok = false; 
    357       break; 
    358  
    359     case 'minval': 
    360     # The minval check checks that the attribute value is a positive integer, 
    361     # and that it is not smaller than the given value. 
    362  
    363       if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value)) 
    364         $ok = false; 
    365       if ($value < $checkvalue) 
    366         $ok = false; 
    367       break; 
    368  
    369     case 'valueless': 
    370     # The valueless check checks if the attribute has a value 
    371     # (like <a href="blah">) or not (<option selected>). If the given value 
    372     # is a "y" or a "Y", the attribute must not have a value. 
    373     # If the given value is an "n" or an "N", the attribute must have one. 
    374  
    375       if (strtolower($checkvalue) != $vless) 
    376         $ok = false; 
    377       break; 
    378   } # switch 
    379  
    380   return $ok; 
     296    $ok = true; 
     297 
     298    switch (strtolower($checkname)) { 
     299        case 'maxlen' : 
     300            # The maxlen check makes sure that the attribute value has a length not 
     301            # greater than the given value. This can be used to avoid Buffer Overflows 
     302            # in WWW clients and various Internet servers. 
     303 
     304            if (strlen($value) > $checkvalue) 
     305                $ok = false; 
     306            break; 
     307 
     308        case 'minlen' : 
     309            # The minlen check makes sure that the attribute value has a length not 
     310            # smaller than the given value. 
     311 
     312            if (strlen($value) < $checkvalue) 
     313                $ok = false; 
     314            break; 
     315 
     316        case 'maxval' : 
     317            # The maxval check does two things: it checks that the attribute value is 
     318            # an integer from 0 and up, without an excessive amount of zeroes or 
     319            # whitespace (to avoid Buffer Overflows). It also checks that the attribute 
     320            # value is not greater than the given value. 
     321            # This check can be used to avoid Denial of Service attacks. 
     322 
     323            if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value)) 
     324                $ok = false; 
     325            if ($value > $checkvalue) 
     326                $ok = false; 
     327            break; 
     328 
     329        case 'minval' : 
     330            # The minval check checks that the attribute value is a positive integer, 
     331            # and that it is not smaller than the given value. 
     332 
     333            if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value)) 
     334                $ok = false; 
     335            if ($value < $checkvalue) 
     336                $ok = false; 
     337            break; 
     338 
     339        case 'valueless' : 
     340            # The valueless check checks if the attribute has a value 
     341            # (like <a href="blah">) or not (<option selected>). If the given value 
     342            # is a "y" or a "Y", the attribute must not have a value. 
     343            # If the given value is an "n" or an "N", the attribute must have one. 
     344 
     345            if (strtolower($checkvalue) != $vless) 
     346                $ok = false; 
     347            break; 
     348    } # switch 
     349 
     350    return $ok; 
    381351} # function wp_kses_check_attr_val 
    382  
    383352 
    384353function wp_kses_bad_protocol($string, $allowed_protocols) 
     
    390359############################################################################### 
    391360{ 
    392   $string = wp_kses_no_null($string); 
    393   $string2 = $string.'a'; 
    394  
    395   while ($string != $string2) 
    396   { 
    397     $string2 = $string; 
    398     $string = wp_kses_bad_protocol_once($string, $allowed_protocols); 
    399   } # while 
    400  
    401   return $string; 
     361    $string = wp_kses_no_null($string); 
     362    $string2 = $string.'a'; 
     363 
     364    while ($string != $string2) { 
     365        $string2 = $string; 
     366        $string = wp_kses_bad_protocol_once($string, $allowed_protocols); 
     367    } # while 
     368 
     369    return $string; 
    402370} # function wp_kses_bad_protocol 
    403371 
    404  
    405372function wp_kses_no_null($string) 
    406373############################################################################### 
     
    408375############################################################################### 
    409376{ 
    410   $string = preg_replace('/\0+/', '', $string); 
    411   $string = preg_replace('/(\\\\0)+/', '', $string); 
    412  
    413   return $string; 
     377    $string = preg_replace('/\0+/', '', $string); 
     378    $string = preg_replace('/(\\\\0)+/', '', $string); 
     379 
     380    $string = preg_replace('/\xad+/', '', $string); # deals with Opera "feature" 
     381 
     382    return $string; 
    414383} # function wp_kses_no_null 
    415  
    416384 
    417385function wp_kses_stripslashes($string) 
     
    422390############################################################################### 
    423391{ 
    424   return preg_replace('%\\\\"%', '"', $string); 
     392   return preg_replace('%\\\\"%', '"', $string); 
    425393} # function wp_kses_stripslashes 
    426394 
    427  
    428395function wp_kses_array_lc($inarray) 
    429396############################################################################### 
     
    431398############################################################################### 
    432399{ 
    433   $outarray = array(); 
    434  
    435   foreach ($inarray as $inkey => $inval) 
    436   { 
    437     $outkey = strtolower($inkey); 
    438     $outarray[$outkey] = array(); 
    439  
    440     foreach ($inval as $inkey2 => $inval2) 
    441     { 
    442       $outkey2 = strtolower($inkey2); 
    443       $outarray[$outkey][$outkey2] = $inval2; 
    444     } # foreach $inval 
    445   } # foreach $inarray 
    446  
    447   return $outarray; 
     400    $outarray = array (); 
     401 
     402    foreach ($inarray as $inkey => $inval) { 
     403        $outkey = strtolower($inkey); 
     404        $outarray[$outkey] = array (); 
     405 
     406        foreach ($inval as $inkey2 => $inval2) { 
     407            $outkey2 = strtolower($inkey2); 
     408            $outarray[$outkey][$outkey2] = $inval2; 
     409        } # foreach $inval 
     410    } # foreach $inarray 
     411 
     412    return $outarray; 
    448413} # function wp_kses_array_lc 
    449  
    450414 
    451415function wp_kses_js_entities($string) 
     
    455419############################################################################### 
    456420{ 
    457   return preg_replace('%&\s*\{[^}]*(\}\s*;?|$)%', '', $string); 
     421   return preg_replace('%&\s*\{[^}]*(\}\s*;?|$)%', '', $string); 
    458422} # function wp_kses_js_entities 
    459  
    460423 
    461424function wp_kses_html_error($string) 
     
    466429############################################################################### 
    467430{ 
    468   return preg_replace('/^("[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*/', '', $string); 
     431   return preg_replace('/^("[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*/', '', $string); 
    469432} # function wp_kses_html_error 
    470  
    471433 
    472434function wp_kses_bad_protocol_once($string, $allowed_protocols) 
     
    476438############################################################################### 
    477439{ 
    478   return preg_replace('/^((&[^;]*;|[\sA-Za-z0-9])*)'. 
    479                       '(:|&#58;|&#[Xx]3[Aa];)\s*/e', 
    480                       'wp_kses_bad_protocol_once2("\\1", $allowed_protocols)', 
    481                       $string); 
     440    return preg_replace('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|&#58;|&#[Xx]3[Aa];)\s*/e', 'wp_kses_bad_protocol_once2("\\1", $allowed_protocols)', $string); 
    482441} # function wp_kses_bad_protocol_once 
    483  
    484442 
    485443function wp_kses_bad_protocol_once2($string, $allowed_protocols) 
     
    489447############################################################################### 
    490448{ 
    491   $string2 = wp_kses_decode_entities($string); 
    492   $string2 = preg_replace('/\s/', '', $string2); 
    493   $string2 = wp_kses_no_null($string2); 
    494   $string2 = strtolower($string2); 
    495  
    496   $allowed = false; 
    497   foreach ($allowed_protocols as $one_protocol) 
    498     if (strtolower($one_protocol) == $string2) 
    499     { 
    500       $allowed = true; 
    501       break; 
    502     } 
    503  
    504   if ($allowed) 
    505     return "$string2:"; 
    506   else 
    507     return ''; 
     449    $string2 = wp_kses_decode_entities($string); 
     450    $string2 = preg_replace('/\s/', '', $string2); 
     451    $string2 = wp_kses_no_null($string2); 
     452    $string2 = strtolower($string2); 
     453 
     454    $allowed = false; 
     455    foreach ($allowed_protocols as $one_protocol) 
     456        if (strtolower($one_protocol) == $string2) { 
     457            $allowed = true; 
     458            break; 
     459        } 
     460 
     461    if ($allowed) 
     462        return "$string2:"; 
     463    else 
     464        return ''; 
    508465} # function wp_kses_bad_protocol_once2 
    509  
    510466 
    511467function wp_kses_normalize_entities($string) 
     
    515471############################################################################### 
    516472{ 
    517 # Disarm all entities by converting & to &amp; 
    518  
    519   $string = str_replace('&', '&amp;', $string); 
    520  
    521 # Change back the allowed entities in our entity whitelist 
    522  
    523   $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]{0,19});/', 
    524                          '&\\1;', $string); 
    525   $string = preg_replace('/&amp;#0*([0-9]{1,5});/e', 
    526                          'wp_kses_normalize_entities2("\\1")', $string); 
    527   $string = preg_replace('/&amp;#([Xx])0*(([0-9A-Fa-f]{2}){1,2});/', 
    528                          '&#\\1\\2;', $string); 
    529  
    530   return $string; 
     473    # Disarm all entities by converting & to &amp; 
     474 
     475    $string = str_replace('&', '&amp;', $string); 
     476 
     477    # Change back the allowed entities in our entity whitelist 
     478 
     479    $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]{0,19});/', '&\\1;', $string); 
     480    $string = preg_replace('/&amp;#0*([0-9]{1,5});/e', 'wp_kses_normalize_entities2("\\1")', $string); 
     481    $string = preg_replace('/&amp;#([Xx])0*(([0-9A-Fa-f]{2}){1,2});/', '&#\\1\\2;', $string); 
     482 
     483    return $string; 
    531484} # function wp_kses_normalize_entities 
    532  
    533485 
    534486function wp_kses_normalize_entities2($i) 
     
    538490############################################################################### 
    539491{ 
    540   return (($i > 65535) ? "&amp;#$i;" : "&#$i;"); 
     492   return (($i > 65535) ? "&amp;#$i;" : "&#$i;"); 
    541493} # function wp_kses_normalize_entities2 
    542  
    543494 
    544495function wp_kses_decode_entities($string) 
     
    549500############################################################################### 
    550501{ 
    551   $string = preg_replace('/&#([0-9]+);/e', 'chr("\\1")', $string); 
    552   $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', 'chr(hexdec("\\1"))', 
    553                          $string); 
    554  
    555   return $string; 
     502    $string = preg_replace('/&#([0-9]+);/e', 'chr("\\1")', $string); 
     503    $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', 'chr(hexdec("\\1"))', $string); 
     504 
     505    return $string; 
    556506} # function wp_kses_decode_entities 
    557507 
    558 function wp_filter_kses( $string ) { 
     508function wp_filter_kses($data) { 
    559509    global $allowedtags; 
    560     return wp_kses($string, $allowedtags); 
     510    return wp_kses($data, $allowedtags); 
    561511} 
    562512 
     513function wp_filter_post_kses($data) { 
     514    global $allowedposttags; 
     515    return wp_kses($data, $allowedposttags); 
     516} 
     517 
     518function kses_init() { 
     519    global $current_user; 
     520 
     521    get_currentuserinfo(); // set $current_user 
     522    if (current_user_can('unfiltered_html') == false) { 
     523        add_filter('pre_comment_author', 'wp_filter_kses'); 
     524        add_filter('pre_comment_content', 'wp_filter_kses'); 
     525        add_filter('content_save_pre', 'wp_filter_post_kses'); 
     526    } 
     527} 
     528add_action('init', 'kses_init'); 
    563529?> 
     530