[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ -> kses.php (source)

   1  <?php
   2  /**
   3   * kses 0.2.2 - HTML/XHTML filter that only allows some elements and attributes
   4   * Copyright (C) 2002, 2003, 2005  Ulf Harnhammar
   5   *
   6   * This program is free software and open source software; you can redistribute
   7   * it and/or modify it under the terms of the GNU General Public License as
   8   * published by the Free Software Foundation; either version 2 of the License,
   9   * or (at your option) any later version.
  10   *
  11   * This program is distributed in the hope that it will be useful, but WITHOUT
  12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14   * more details.
  15   *
  16   * You should have received a copy of the GNU General Public License along
  17   * with this program; if not, write to the Free Software Foundation, Inc.,
  18   * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19   * http://www.gnu.org/licenses/gpl.html
  20   *
  21   * [kses strips evil scripts!]
  22   *
  23   * Added wp_ prefix to avoid conflicts with existing kses users
  24   *
  25   * @version 0.2.2
  26   * @copyright (C) 2002, 2003, 2005
  27   * @author Ulf Harnhammar <http://advogato.org/person/metaur/>
  28   *
  29   * @package External
  30   * @subpackage KSES
  31   *
  32   */
  33  
  34  /**
  35   * You can override this in a plugin.
  36   *
  37   * The wp_kses_allowed_html filter is more powerful and supplies context.
  38   * CUSTOM_TAGS is not recommended and should be considered deprecated.
  39   *
  40   * @see wp_kses_allowed_html()
  41   *
  42   * @since 1.2.0
  43   */
  44  if ( ! defined( 'CUSTOM_TAGS' ) )
  45      define( 'CUSTOM_TAGS', false );
  46  
  47  if ( ! CUSTOM_TAGS ) {
  48      /**
  49       * Kses global for default allowable HTML tags.
  50       *
  51       * Can be override by using CUSTOM_TAGS constant.
  52       *
  53       * @global array $allowedposttags
  54       * @since 2.0.0
  55       */
  56      $allowedposttags = array(
  57          'address' => array(),
  58          'a' => array(
  59              'href' => true,
  60              'rel' => true,
  61              'rev' => true,
  62              'name' => true,
  63              'target' => true,
  64          ),
  65          'abbr' => array(),
  66          'acronym' => array(),
  67          'area' => array(
  68              'alt' => true,
  69              'coords' => true,
  70              'href' => true,
  71              'nohref' => true,
  72              'shape' => true,
  73              'target' => true,
  74          ),
  75          'article' => array(
  76              'align' => true,
  77              'dir' => true,
  78              'lang' => true,
  79              'xml:lang' => true,
  80          ),
  81          'aside' => array(
  82              'align' => true,
  83              'dir' => true,
  84              'lang' => true,
  85              'xml:lang' => true,
  86          ),
  87          'b' => array(),
  88          'big' => array(),
  89          'blockquote' => array(
  90              'cite' => true,
  91              'lang' => true,
  92              'xml:lang' => true,
  93          ),
  94          'br' => array(),
  95          'button' => array(
  96              'disabled' => true,
  97              'name' => true,
  98              'type' => true,
  99              'value' => true,
 100          ),
 101          'caption' => array(
 102              'align' => true,
 103          ),
 104          'cite' => array(
 105              'dir' => true,
 106              'lang' => true,
 107          ),
 108          'code' => array(),
 109          'col' => array(
 110              'align' => true,
 111              'char' => true,
 112              'charoff' => true,
 113              'span' => true,
 114              'dir' => true,
 115              'valign' => true,
 116              'width' => true,
 117          ),
 118          'del' => array(
 119              'datetime' => true,
 120          ),
 121          'dd' => array(),
 122          'details' => array(
 123              'align' => true,
 124              'dir' => true,
 125              'lang' => true,
 126              'open' => true,
 127              'xml:lang' => true,
 128          ),
 129          'div' => array(
 130              'align' => true,
 131              'dir' => true,
 132              'lang' => true,
 133              'xml:lang' => true,
 134          ),
 135          'dl' => array(),
 136          'dt' => array(),
 137          'em' => array(),
 138          'fieldset' => array(),
 139          'figure' => array(
 140              'align' => true,
 141              'dir' => true,
 142              'lang' => true,
 143              'xml:lang' => true,
 144          ),
 145          'figcaption' => array(
 146              'align' => true,
 147              'dir' => true,
 148              'lang' => true,
 149              'xml:lang' => true,
 150          ),
 151          'font' => array(
 152              'color' => true,
 153              'face' => true,
 154              'size' => true,
 155          ),
 156          'footer' => array(
 157              'align' => true,
 158              'dir' => true,
 159              'lang' => true,
 160              'xml:lang' => true,
 161          ),
 162          'form' => array(
 163              'action' => true,
 164              'accept' => true,
 165              'accept-charset' => true,
 166              'enctype' => true,
 167              'method' => true,
 168              'name' => true,
 169              'target' => true,
 170          ),
 171          'h1' => array(
 172              'align' => true,
 173          ),
 174          'h2' => array(
 175              'align' => true,
 176          ),
 177          'h3' => array(
 178              'align' => true,
 179          ),
 180          'h4' => array(
 181              'align' => true,
 182          ),
 183          'h5' => array(
 184              'align' => true,
 185          ),
 186          'h6' => array(
 187              'align' => true,
 188          ),
 189          'header' => array(
 190              'align' => true,
 191              'dir' => true,
 192              'lang' => true,
 193              'xml:lang' => true,
 194          ),
 195          'hgroup' => array(
 196              'align' => true,
 197              'dir' => true,
 198              'lang' => true,
 199              'xml:lang' => true,
 200          ),
 201          'hr' => array(
 202              'align' => true,
 203              'noshade' => true,
 204              'size' => true,
 205              'width' => true,
 206          ),
 207          'i' => array(),
 208          'img' => array(
 209              'alt' => true,
 210              'align' => true,
 211              'border' => true,
 212              'height' => true,
 213              'hspace' => true,
 214              'longdesc' => true,
 215              'vspace' => true,
 216              'src' => true,
 217              'usemap' => true,
 218              'width' => true,
 219          ),
 220          'ins' => array(
 221              'datetime' => true,
 222              'cite' => true,
 223          ),
 224          'kbd' => array(),
 225          'label' => array(
 226              'for' => true,
 227          ),
 228          'legend' => array(
 229              'align' => true,
 230          ),
 231          'li' => array(
 232              'align' => true,
 233              'value' => true,
 234          ),
 235          'map' => array(
 236              'name' => true,
 237          ),
 238          'menu' => array(
 239              'type' => true,
 240          ),
 241          'nav' => array(
 242              'align' => true,
 243              'dir' => true,
 244              'lang' => true,
 245              'xml:lang' => true,
 246          ),
 247          'p' => array(
 248              'align' => true,
 249              'dir' => true,
 250              'lang' => true,
 251              'xml:lang' => true,
 252          ),
 253          'pre' => array(
 254              'width' => true,
 255          ),
 256          'q' => array(
 257              'cite' => true,
 258          ),
 259          's' => array(),
 260          'span' => array(
 261              'dir' => true,
 262              'align' => true,
 263              'lang' => true,
 264              'xml:lang' => true,
 265          ),
 266          'section' => array(
 267              'align' => true,
 268              'dir' => true,
 269              'lang' => true,
 270              'xml:lang' => true,
 271          ),
 272          'small' => array(),
 273          'strike' => array(),
 274          'strong' => array(),
 275          'sub' => array(),
 276          'summary' => array(
 277              'align' => true,
 278              'dir' => true,
 279              'lang' => true,
 280              'xml:lang' => true,
 281          ),
 282          'sup' => array(),
 283          'table' => array(
 284              'align' => true,
 285              'bgcolor' => true,
 286              'border' => true,
 287              'cellpadding' => true,
 288              'cellspacing' => true,
 289              'dir' => true,
 290              'rules' => true,
 291              'summary' => true,
 292              'width' => true,
 293          ),
 294          'tbody' => array(
 295              'align' => true,
 296              'char' => true,
 297              'charoff' => true,
 298              'valign' => true,
 299          ),
 300          'td' => array(
 301              'abbr' => true,
 302              'align' => true,
 303              'axis' => true,
 304              'bgcolor' => true,
 305              'char' => true,
 306              'charoff' => true,
 307              'colspan' => true,
 308              'dir' => true,
 309              'headers' => true,
 310              'height' => true,
 311              'nowrap' => true,
 312              'rowspan' => true,
 313              'scope' => true,
 314              'valign' => true,
 315              'width' => true,
 316          ),
 317          'textarea' => array(
 318              'cols' => true,
 319              'rows' => true,
 320              'disabled' => true,
 321              'name' => true,
 322              'readonly' => true,
 323          ),
 324          'tfoot' => array(
 325              'align' => true,
 326              'char' => true,
 327              'charoff' => true,
 328              'valign' => true,
 329          ),
 330          'th' => array(
 331              'abbr' => true,
 332              'align' => true,
 333              'axis' => true,
 334              'bgcolor' => true,
 335              'char' => true,
 336              'charoff' => true,
 337              'colspan' => true,
 338              'headers' => true,
 339              'height' => true,
 340              'nowrap' => true,
 341              'rowspan' => true,
 342              'scope' => true,
 343              'valign' => true,
 344              'width' => true,
 345          ),
 346          'thead' => array(
 347              'align' => true,
 348              'char' => true,
 349              'charoff' => true,
 350              'valign' => true,
 351          ),
 352          'title' => array(),
 353          'tr' => array(
 354              'align' => true,
 355              'bgcolor' => true,
 356              'char' => true,
 357              'charoff' => true,
 358              'valign' => true,
 359          ),
 360          'tt' => array(),
 361          'u' => array(),
 362          'ul' => array(
 363              'type' => true,
 364          ),
 365          'ol' => array(
 366              'start' => true,
 367              'type' => true,
 368          ),
 369          'var' => array(),
 370      );
 371  
 372      /**
 373       * Kses allowed HTML elements.
 374       *
 375       * @global array $allowedtags
 376       * @since 1.0.0
 377       */
 378      $allowedtags = array(
 379          'a' => array(
 380              'href' => true,
 381              'title' => true,
 382          ),
 383          'abbr' => array(
 384              'title' => true,
 385          ),
 386          'acronym' => array(
 387              'title' => true,
 388          ),
 389          'b' => array(),
 390          'blockquote' => array(
 391              'cite' => true,
 392          ),
 393          'cite' => array(),
 394          'code' => array(),
 395          'del' => array(
 396              'datetime' => true,
 397          ),
 398          'em' => array(),
 399          'i' => array(),
 400          'q' => array(
 401              'cite' => true,
 402          ),
 403          'strike' => array(),
 404          'strong' => array(),
 405      );
 406  
 407      $allowedentitynames = array(
 408          'nbsp',    'iexcl',  'cent',    'pound',  'curren', 'yen',
 409          'brvbar',  'sect',   'uml',     'copy',   'ordf',   'laquo',
 410          'not',     'shy',    'reg',     'macr',   'deg',    'plusmn',
 411          'acute',   'micro',  'para',    'middot', 'cedil',  'ordm',
 412          'raquo',   'iquest', 'Agrave',  'Aacute', 'Acirc',  'Atilde',
 413          'Auml',    'Aring',  'AElig',   'Ccedil', 'Egrave', 'Eacute',
 414          'Ecirc',   'Euml',   'Igrave',  'Iacute', 'Icirc',  'Iuml',
 415          'ETH',     'Ntilde', 'Ograve',  'Oacute', 'Ocirc',  'Otilde',
 416          'Ouml',    'times',  'Oslash',  'Ugrave', 'Uacute', 'Ucirc',
 417          'Uuml',    'Yacute', 'THORN',   'szlig',  'agrave', 'aacute',
 418          'acirc',   'atilde', 'auml',    'aring',  'aelig',  'ccedil',
 419          'egrave',  'eacute', 'ecirc',   'euml',   'igrave', 'iacute',
 420          'icirc',   'iuml',   'eth',     'ntilde', 'ograve', 'oacute',
 421          'ocirc',   'otilde', 'ouml',    'divide', 'oslash', 'ugrave',
 422          'uacute',  'ucirc',  'uuml',    'yacute', 'thorn',  'yuml',
 423          'quot',    'amp',    'lt',      'gt',     'apos',   'OElig',
 424          'oelig',   'Scaron', 'scaron',  'Yuml',   'circ',   'tilde',
 425          'ensp',    'emsp',   'thinsp',  'zwnj',   'zwj',    'lrm',
 426          'rlm',     'ndash',  'mdash',   'lsquo',  'rsquo',  'sbquo',
 427          'ldquo',   'rdquo',  'bdquo',   'dagger', 'Dagger', 'permil',
 428          'lsaquo',  'rsaquo', 'euro',    'fnof',   'Alpha',  'Beta',
 429          'Gamma',   'Delta',  'Epsilon', 'Zeta',   'Eta',    'Theta',
 430          'Iota',    'Kappa',  'Lambda',  'Mu',     'Nu',     'Xi',
 431          'Omicron', 'Pi',     'Rho',     'Sigma',  'Tau',    'Upsilon',
 432          'Phi',     'Chi',    'Psi',     'Omega',  'alpha',  'beta',
 433          'gamma',   'delta',  'epsilon', 'zeta',   'eta',    'theta',
 434          'iota',    'kappa',  'lambda',  'mu',     'nu',     'xi',
 435          'omicron', 'pi',     'rho',     'sigmaf', 'sigma',  'tau',
 436          'upsilon', 'phi',    'chi',     'psi',    'omega',  'thetasym',
 437          'upsih',   'piv',    'bull',    'hellip', 'prime',  'Prime',
 438          'oline',   'frasl',  'weierp',  'image',  'real',   'trade',
 439          'alefsym', 'larr',   'uarr',    'rarr',   'darr',   'harr',
 440          'crarr',   'lArr',   'uArr',    'rArr',   'dArr',   'hArr',
 441          'forall',  'part',   'exist',   'empty',  'nabla',  'isin',
 442          'notin',   'ni',     'prod',    'sum',    'minus',  'lowast',
 443          'radic',   'prop',   'infin',   'ang',    'and',    'or',
 444          'cap',     'cup',    'int',     'sim',    'cong',   'asymp',
 445          'ne',      'equiv',  'le',      'ge',     'sub',    'sup',
 446          'nsub',    'sube',   'supe',    'oplus',  'otimes', 'perp',
 447          'sdot',    'lceil',  'rceil',   'lfloor', 'rfloor', 'lang',
 448          'rang',    'loz',    'spades',  'clubs',  'hearts', 'diams',
 449          'sup1',    'sup2',   'sup3',    'frac14', 'frac12', 'frac34',
 450          'there4',
 451      );
 452  
 453      $allowedposttags = array_map( '_wp_add_global_attributes', $allowedposttags );
 454  } else {
 455      $allowedtags = wp_kses_array_lc( $allowedtags );
 456      $allowedposttags = wp_kses_array_lc( $allowedposttags );
 457  }
 458  
 459  /**
 460   * Filters content and keeps only allowable HTML elements.
 461   *
 462   * This function makes sure that only the allowed HTML element names, attribute
 463   * names and attribute values plus only sane HTML entities will occur in
 464   * $string. You have to remove any slashes from PHP's magic quotes before you
 465   * call this function.
 466   *
 467   * The default allowed protocols are 'http', 'https', 'ftp', 'mailto', 'news',
 468   * 'irc', 'gopher', 'nntp', 'feed', 'telnet, 'mms', 'rtsp' and 'svn'. This
 469   * covers all common link protocols, except for 'javascript' which should not
 470   * be allowed for untrusted users.
 471   *
 472   * @since 1.0.0
 473   *
 474   * @param string $string Content to filter through kses
 475   * @param array $allowed_html List of allowed HTML elements
 476   * @param array $allowed_protocols Optional. Allowed protocol in links.
 477   * @return string Filtered content with only allowed HTML elements
 478   */
 479  function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) {
 480      if ( empty( $allowed_protocols ) )
 481          $allowed_protocols = wp_allowed_protocols();
 482      $string = wp_kses_no_null($string);
 483      $string = wp_kses_js_entities($string);
 484      $string = wp_kses_normalize_entities($string);
 485      $string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook
 486      return wp_kses_split($string, $allowed_html, $allowed_protocols);
 487  }
 488  
 489  /**
 490   * Return a list of allowed tags and attributes for a given context.
 491   *
 492   * @since 3.5.0
 493   *
 494   * @param string $context The context for which to retrieve tags. Allowed values are
 495   *  post | strip | data | entities or the name of a field filter such as pre_user_description.
 496   * @return array List of allowed tags and their allowed attributes.
 497   */
 498  function wp_kses_allowed_html( $context = '' ) {
 499      global $allowedposttags, $allowedtags, $allowedentitynames;
 500  
 501      if ( is_array( $context ) )
 502          return apply_filters( 'wp_kses_allowed_html', $context, 'explicit' );
 503  
 504      switch ( $context ) {
 505          case 'post':
 506              return apply_filters( 'wp_kses_allowed_html', $allowedposttags, $context );
 507              break;
 508          case 'user_description':
 509          case 'pre_user_description':
 510              $tags = $allowedtags;
 511              $tags['a']['rel'] = true;
 512              return apply_filters( 'wp_kses_allowed_html', $tags, $context );
 513              break;
 514          case 'strip':
 515              return apply_filters( 'wp_kses_allowed_html', array(), $context );
 516              break;
 517          case 'entities':
 518              return apply_filters( 'wp_kses_allowed_html', $allowedentitynames, $context);
 519              break;
 520          case 'data':
 521          default:
 522              return apply_filters( 'wp_kses_allowed_html', $allowedtags, $context );
 523      }
 524  }
 525  
 526  /**
 527   * You add any kses hooks here.
 528   *
 529   * There is currently only one kses WordPress hook and it is called here. All
 530   * parameters are passed to the hooks and expected to receive a string.
 531   *
 532   * @since 1.0.0
 533   *
 534   * @param string $string Content to filter through kses
 535   * @param array $allowed_html List of allowed HTML elements
 536   * @param array $allowed_protocols Allowed protocol in links
 537   * @return string Filtered content through 'pre_kses' hook
 538   */
 539  function wp_kses_hook( $string, $allowed_html, $allowed_protocols ) {
 540      $string = apply_filters('pre_kses', $string, $allowed_html, $allowed_protocols);
 541      return $string;
 542  }
 543  
 544  /**
 545   * This function returns kses' version number.
 546   *
 547   * @since 1.0.0
 548   *
 549   * @return string KSES Version Number
 550   */
 551  function wp_kses_version() {
 552      return '0.2.2';
 553  }
 554  
 555  /**
 556   * Searches for HTML tags, no matter how malformed.
 557   *
 558   * It also matches stray ">" characters.
 559   *
 560   * @since 1.0.0
 561   *
 562   * @param string $string Content to filter
 563   * @param array $allowed_html Allowed HTML elements
 564   * @param array $allowed_protocols Allowed protocols to keep
 565   * @return string Content with fixed HTML tags
 566   */
 567  function wp_kses_split( $string, $allowed_html, $allowed_protocols ) {
 568      global $pass_allowed_html, $pass_allowed_protocols;
 569      $pass_allowed_html = $allowed_html;
 570      $pass_allowed_protocols = $allowed_protocols;
 571      return preg_replace_callback( '%(<!--.*?(-->|$))|(<[^>]*(>|$)|>)%', '_wp_kses_split_callback', $string );
 572  }
 573  
 574  /**
 575   * Callback for wp_kses_split.
 576   *
 577   * @since 3.1.0
 578   * @access private
 579   */
 580  function _wp_kses_split_callback( $match ) {
 581      global $pass_allowed_html, $pass_allowed_protocols;
 582      return wp_kses_split2( $match[0], $pass_allowed_html, $pass_allowed_protocols );
 583  }
 584  
 585  /**
 586   * Callback for wp_kses_split for fixing malformed HTML tags.
 587   *
 588   * This function does a lot of work. It rejects some very malformed things like
 589   * <:::>. It returns an empty string, if the element isn't allowed (look ma, no
 590   * strip_tags()!). Otherwise it splits the tag into an element and an attribute
 591   * list.
 592   *
 593   * After the tag is split into an element and an attribute list, it is run
 594   * through another filter which will remove illegal attributes and once that is
 595   * completed, will be returned.
 596   *
 597   * @access private
 598   * @since 1.0.0
 599   * @uses wp_kses_attr()
 600   *
 601   * @param string $string Content to filter
 602   * @param array $allowed_html Allowed HTML elements
 603   * @param array $allowed_protocols Allowed protocols to keep
 604   * @return string Fixed HTML element
 605   */
 606  function wp_kses_split2($string, $allowed_html, $allowed_protocols) {
 607      $string = wp_kses_stripslashes($string);
 608  
 609      if (substr($string, 0, 1) != '<')
 610          return '&gt;';
 611      # It matched a ">" character
 612  
 613      if ( '<!--' == substr( $string, 0, 4 ) ) {
 614          $string = str_replace( array('<!--', '-->'), '', $string );
 615          while ( $string != ($newstring = wp_kses($string, $allowed_html, $allowed_protocols)) )
 616              $string = $newstring;
 617          if ( $string == '' )
 618              return '';
 619          // prevent multiple dashes in comments
 620          $string = preg_replace('/--+/', '-', $string);
 621          // prevent three dashes closing a comment
 622          $string = preg_replace('/-$/', '', $string);
 623          return "<!--{$string}-->";
 624      }
 625      # Allow HTML comments
 626  
 627      if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches))
 628          return '';
 629      # It's seriously malformed
 630  
 631      $slash = trim($matches[1]);
 632      $elem = $matches[2];
 633      $attrlist = $matches[3];
 634  
 635      if ( ! is_array( $allowed_html ) )
 636          $allowed_html = wp_kses_allowed_html( $allowed_html );
 637  
 638      if ( ! isset($allowed_html[strtolower($elem)]) )
 639          return '';
 640      # They are using a not allowed HTML element
 641  
 642      if ($slash != '')
 643          return "</$elem>";
 644      # No attributes are allowed for closing elements
 645  
 646      return wp_kses_attr( $elem, $attrlist, $allowed_html, $allowed_protocols );
 647  }
 648  
 649  /**
 650   * Removes all attributes, if none are allowed for this element.
 651   *
 652   * If some are allowed it calls wp_kses_hair() to split them further, and then
 653   * it builds up new HTML code from the data that kses_hair() returns. It also
 654   * removes "<" and ">" characters, if there are any left. One more thing it does
 655   * is to check if the tag has a closing XHTML slash, and if it does, it puts one
 656   * in the returned code as well.
 657   *
 658   * @since 1.0.0
 659   *
 660   * @param string $element HTML element/tag
 661   * @param string $attr HTML attributes from HTML element to closing HTML element tag
 662   * @param array $allowed_html Allowed HTML elements
 663   * @param array $allowed_protocols Allowed protocols to keep
 664   * @return string Sanitized HTML element
 665   */
 666  function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) {
 667      # Is there a closing XHTML slash at the end of the attributes?
 668  
 669      if ( ! is_array( $allowed_html ) )
 670          $allowed_html = wp_kses_allowed_html( $allowed_html );
 671  
 672      $xhtml_slash = '';
 673      if (preg_match('%\s*/\s*$%', $attr))
 674          $xhtml_slash = ' /';
 675  
 676      # Are any attributes allowed at all for this element?
 677      if ( ! isset($allowed_html[strtolower($element)]) || count($allowed_html[strtolower($element)]) == 0 )
 678          return "<$element$xhtml_slash>";
 679  
 680      # Split it
 681      $attrarr = wp_kses_hair($attr, $allowed_protocols);
 682  
 683      # Go through $attrarr, and save the allowed attributes for this element
 684      # in $attr2
 685      $attr2 = '';
 686  
 687      $allowed_attr = $allowed_html[strtolower($element)];
 688      foreach ($attrarr as $arreach) {
 689          if ( ! isset( $allowed_attr[strtolower($arreach['name'])] ) )
 690              continue; # the attribute is not allowed
 691  
 692          $current = $allowed_attr[strtolower($arreach['name'])];
 693          if ( $current == '' )
 694              continue; # the attribute is not allowed
 695  
 696          if ( strtolower( $arreach['name'] ) == 'style' ) {
 697              $orig_value = $arreach['value'];
 698              $value = safecss_filter_attr( $orig_value );
 699  
 700              if ( empty( $value ) )
 701                  continue;
 702  
 703              $arreach['value'] = $value;
 704              $arreach['whole'] = str_replace( $orig_value, $value, $arreach['whole'] );
 705          }
 706  
 707          if ( ! is_array($current) ) {
 708              $attr2 .= ' '.$arreach['whole'];
 709          # there are no checks
 710  
 711          } else {
 712              # there are some checks
 713              $ok = true;
 714              foreach ($current as $currkey => $currval) {
 715                  if ( ! wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval) ) {
 716                      $ok = false;
 717                      break;
 718                  }
 719              }
 720  
 721              if ( $ok )
 722                  $attr2 .= ' '.$arreach['whole']; # it passed them
 723          } # if !is_array($current)
 724      } # foreach
 725  
 726      # Remove any "<" or ">" characters
 727      $attr2 = preg_replace('/[<>]/', '', $attr2);
 728  
 729      return "<$element$attr2$xhtml_slash>";
 730  }
 731  
 732  /**
 733   * Builds an attribute list from string containing attributes.
 734   *
 735   * This function does a lot of work. It parses an attribute list into an array
 736   * with attribute data, and tries to do the right thing even if it gets weird
 737   * input. It will add quotes around attribute values that don't have any quotes
 738   * or apostrophes around them, to make it easier to produce HTML code that will
 739   * conform to W3C's HTML specification. It will also remove bad URL protocols
 740   * from attribute values. It also reduces duplicate attributes by using the
 741   * attribute defined first (foo='bar' foo='baz' will result in foo='bar').
 742   *
 743   * @since 1.0.0
 744   *
 745   * @param string $attr Attribute list from HTML element to closing HTML element tag
 746   * @param array $allowed_protocols Allowed protocols to keep
 747   * @return array List of attributes after parsing
 748   */
 749  function wp_kses_hair($attr, $allowed_protocols) {
 750      $attrarr = array();
 751      $mode = 0;
 752      $attrname = '';
 753      $uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action');
 754  
 755      # Loop through the whole attribute list
 756  
 757      while (strlen($attr) != 0) {
 758          $working = 0; # Was the last operation successful?
 759  
 760          switch ($mode) {
 761              case 0 : # attribute name, href for instance
 762  
 763                  if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) {
 764                      $attrname = $match[1];
 765                      $working = $mode = 1;
 766                      $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
 767                  }
 768  
 769                  break;
 770  
 771              case 1 : # equals sign or valueless ("selected")
 772  
 773                  if (preg_match('/^\s*=\s*/', $attr)) # equals sign
 774                      {
 775                      $working = 1;
 776                      $mode = 2;
 777                      $attr = preg_replace('/^\s*=\s*/', '', $attr);
 778                      break;
 779                  }
 780  
 781                  if (preg_match('/^\s+/', $attr)) # valueless
 782                      {
 783                      $working = 1;
 784                      $mode = 0;
 785                      if(false === array_key_exists($attrname, $attrarr)) {
 786                          $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y');
 787                      }
 788                      $attr = preg_replace('/^\s+/', '', $attr);
 789                  }
 790  
 791                  break;
 792  
 793              case 2 : # attribute value, a URL after href= for instance
 794  
 795                  if (preg_match('%^"([^"]*)"(\s+|/?$)%', $attr, $match))
 796                      # "value"
 797                      {
 798                      $thisval = $match[1];
 799                      if ( in_array(strtolower($attrname), $uris) )
 800                          $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols);
 801  
 802                      if(false === array_key_exists($attrname, $attrarr)) {
 803                          $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n');
 804                      }
 805                      $working = 1;
 806                      $mode = 0;
 807                      $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr);
 808                      break;
 809                  }
 810  
 811                  if (preg_match("%^'([^']*)'(\s+|/?$)%", $attr, $match))
 812                      # 'value'
 813                      {
 814                      $thisval = $match[1];
 815                      if ( in_array(strtolower($attrname), $uris) )
 816                          $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols);
 817  
 818                      if(false === array_key_exists($attrname, $attrarr)) {
 819                          $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n');
 820                      }
 821                      $working = 1;
 822                      $mode = 0;
 823                      $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr);
 824                      break;
 825                  }
 826  
 827                  if (preg_match("%^([^\s\"']+)(\s+|/?$)%", $attr, $match))
 828                      # value
 829                      {
 830                      $thisval = $match[1];
 831                      if ( in_array(strtolower($attrname), $uris) )
 832                          $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols);
 833  
 834                      if(false === array_key_exists($attrname, $attrarr)) {
 835                          $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n');
 836                      }
 837                      # We add quotes to conform to W3C's HTML spec.
 838                      $working = 1;
 839                      $mode = 0;
 840                      $attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr);
 841                  }
 842  
 843                  break;
 844          } # switch
 845  
 846          if ($working == 0) # not well formed, remove and try again
 847          {
 848              $attr = wp_kses_html_error($attr);
 849              $mode = 0;
 850          }
 851      } # while
 852  
 853      if ($mode == 1 && false === array_key_exists($attrname, $attrarr))
 854          # special case, for when the attribute list ends with a valueless
 855          # attribute like "selected"
 856          $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y');
 857  
 858      return $attrarr;
 859  }
 860  
 861  /**
 862   * Performs different checks for attribute values.
 863   *
 864   * The currently implemented checks are "maxlen", "minlen", "maxval", "minval"
 865   * and "valueless".
 866   *
 867   * @since 1.0.0
 868   *
 869   * @param string $value Attribute value
 870   * @param string $vless Whether the value is valueless. Use 'y' or 'n'
 871   * @param string $checkname What $checkvalue is checking for.
 872   * @param mixed $checkvalue What constraint the value should pass
 873   * @return bool Whether check passes
 874   */
 875  function wp_kses_check_attr_val($value, $vless, $checkname, $checkvalue) {
 876      $ok = true;
 877  
 878      switch (strtolower($checkname)) {
 879          case 'maxlen' :
 880              # The maxlen check makes sure that the attribute value has a length not
 881              # greater than the given value. This can be used to avoid Buffer Overflows
 882              # in WWW clients and various Internet servers.
 883  
 884              if (strlen($value) > $checkvalue)
 885                  $ok = false;
 886              break;
 887  
 888          case 'minlen' :
 889              # The minlen check makes sure that the attribute value has a length not
 890              # smaller than the given value.
 891  
 892              if (strlen($value) < $checkvalue)
 893                  $ok = false;
 894              break;
 895  
 896          case 'maxval' :
 897              # The maxval check does two things: it checks that the attribute value is
 898              # an integer from 0 and up, without an excessive amount of zeroes or
 899              # whitespace (to avoid Buffer Overflows). It also checks that the attribute
 900              # value is not greater than the given value.
 901              # This check can be used to avoid Denial of Service attacks.
 902  
 903              if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value))
 904                  $ok = false;
 905              if ($value > $checkvalue)
 906                  $ok = false;
 907              break;
 908  
 909          case 'minval' :
 910              # The minval check makes sure that the attribute value is a positive integer,
 911              # and that it is not smaller than the given value.
 912  
 913              if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value))
 914                  $ok = false;
 915              if ($value < $checkvalue)
 916                  $ok = false;
 917              break;
 918  
 919          case 'valueless' :
 920              # The valueless check makes sure if the attribute has a value
 921              # (like <a href="blah">) or not (<option selected>). If the given value
 922              # is a "y" or a "Y", the attribute must not have a value.
 923              # If the given value is an "n" or an "N", the attribute must have one.
 924  
 925              if (strtolower($checkvalue) != $vless)
 926                  $ok = false;
 927              break;
 928      } # switch
 929  
 930      return $ok;
 931  }
 932  
 933  /**
 934   * Sanitize string from bad protocols.
 935   *
 936   * This function removes all non-allowed protocols from the beginning of
 937   * $string. It ignores whitespace and the case of the letters, and it does
 938   * understand HTML entities. It does its work in a while loop, so it won't be
 939   * fooled by a string like "javascript:javascript:alert(57)".
 940   *
 941   * @since 1.0.0
 942   *
 943   * @param string $string Content to filter bad protocols from
 944   * @param array $allowed_protocols Allowed protocols to keep
 945   * @return string Filtered content
 946   */
 947  function wp_kses_bad_protocol($string, $allowed_protocols) {
 948      $string = wp_kses_no_null($string);
 949      $iterations = 0;
 950  
 951      do {
 952          $original_string = $string;
 953          $string = wp_kses_bad_protocol_once($string, $allowed_protocols);
 954      } while ( $original_string != $string && ++$iterations < 6 );
 955  
 956      if ( $original_string != $string )
 957          return '';
 958  
 959      return $string;
 960  }
 961  
 962  /**
 963   * Removes any null characters in $string.
 964   *
 965   * @since 1.0.0
 966   *
 967   * @param string $string
 968   * @return string
 969   */
 970  function wp_kses_no_null($string) {
 971      $string = preg_replace('/\0+/', '', $string);
 972      $string = preg_replace('/(\\\\0)+/', '', $string);
 973  
 974      return $string;
 975  }
 976  
 977  /**
 978   * Strips slashes from in front of quotes.
 979   *
 980   * This function changes the character sequence \" to just ". It leaves all
 981   * other slashes alone. It's really weird, but the quoting from
 982   * preg_replace(//e) seems to require this.
 983   *
 984   * @since 1.0.0
 985   *
 986   * @param string $string String to strip slashes
 987   * @return string Fixed string with quoted slashes
 988   */
 989  function wp_kses_stripslashes($string) {
 990      return preg_replace('%\\\\"%', '"', $string);
 991  }
 992  
 993  /**
 994   * Goes through an array and changes the keys to all lower case.
 995   *
 996   * @since 1.0.0
 997   *
 998   * @param array $inarray Unfiltered array
 999   * @return array Fixed array with all lowercase keys
1000   */
1001  function wp_kses_array_lc($inarray) {
1002      $outarray = array ();
1003  
1004      foreach ( (array) $inarray as $inkey => $inval) {
1005          $outkey = strtolower($inkey);
1006          $outarray[$outkey] = array ();
1007  
1008          foreach ( (array) $inval as $inkey2 => $inval2) {
1009              $outkey2 = strtolower($inkey2);
1010              $outarray[$outkey][$outkey2] = $inval2;
1011          } # foreach $inval
1012      } # foreach $inarray
1013  
1014      return $outarray;
1015  }
1016  
1017  /**
1018   * Removes the HTML JavaScript entities found in early versions of Netscape 4.
1019   *
1020   * @since 1.0.0
1021   *
1022   * @param string $string
1023   * @return string
1024   */
1025  function wp_kses_js_entities($string) {
1026      return preg_replace('%&\s*\{[^}]*(\}\s*;?|$)%', '', $string);
1027  }
1028  
1029  /**
1030   * Handles parsing errors in wp_kses_hair().
1031   *
1032   * The general plan is to remove everything to and including some whitespace,
1033   * but it deals with quotes and apostrophes as well.
1034   *
1035   * @since 1.0.0
1036   *
1037   * @param string $string
1038   * @return string
1039   */
1040  function wp_kses_html_error($string) {
1041      return preg_replace('/^("[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*/', '', $string);
1042  }
1043  
1044  /**
1045   * Sanitizes content from bad protocols and other characters.
1046   *
1047   * This function searches for URL protocols at the beginning of $string, while
1048   * handling whitespace and HTML entities.
1049   *
1050   * @since 1.0.0
1051   *
1052   * @param string $string Content to check for bad protocols
1053   * @param string $allowed_protocols Allowed protocols
1054   * @return string Sanitized content
1055   */
1056  function wp_kses_bad_protocol_once($string, $allowed_protocols, $count = 1 ) {
1057      $string2 = preg_split( '/:|&#0*58;|&#x0*3a;/i', $string, 2 );
1058      if ( isset($string2[1]) && ! preg_match('%/\?%', $string2[0]) ) {
1059          $string = trim( $string2[1] );
1060          $protocol = wp_kses_bad_protocol_once2( $string2[0], $allowed_protocols );
1061          if ( 'feed:' == $protocol ) {
1062              if ( $count > 2 )
1063                  return '';
1064              $string = wp_kses_bad_protocol_once( $string, $allowed_protocols, ++$count );
1065              if ( empty( $string ) )
1066                  return $string;
1067          }
1068          $string = $protocol . $string;
1069      }
1070  
1071      return $string;
1072  }
1073  
1074  /**
1075   * Callback for wp_kses_bad_protocol_once() regular expression.
1076   *
1077   * This function processes URL protocols, checks to see if they're in the
1078   * whitelist or not, and returns different data depending on the answer.
1079   *
1080   * @access private
1081   * @since 1.0.0
1082   *
1083   * @param string $string URI scheme to check against the whitelist
1084   * @param string $allowed_protocols Allowed protocols
1085   * @return string Sanitized content
1086   */
1087  function wp_kses_bad_protocol_once2( $string, $allowed_protocols ) {
1088      $string2 = wp_kses_decode_entities($string);
1089      $string2 = preg_replace('/\s/', '', $string2);
1090      $string2 = wp_kses_no_null($string2);
1091      $string2 = strtolower($string2);
1092  
1093      $allowed = false;
1094      foreach ( (array) $allowed_protocols as $one_protocol )
1095          if ( strtolower($one_protocol) == $string2 ) {
1096              $allowed = true;
1097              break;
1098          }
1099  
1100      if ($allowed)
1101          return "$string2:";
1102      else
1103          return '';
1104  }
1105  
1106  /**
1107   * Converts and fixes HTML entities.
1108   *
1109   * This function normalizes HTML entities. It will convert "AT&T" to the correct
1110   * "AT&amp;T", "&#00058;" to "&#58;", "&#XYZZY;" to "&amp;#XYZZY;" and so on.
1111   *
1112   * @since 1.0.0
1113   *
1114   * @param string $string Content to normalize entities
1115   * @return string Content with normalized entities
1116   */
1117  function wp_kses_normalize_entities($string) {
1118      # Disarm all entities by converting & to &amp;
1119  
1120      $string = str_replace('&', '&amp;', $string);
1121  
1122      # Change back the allowed entities in our entity whitelist
1123  
1124      $string = preg_replace_callback('/&amp;([A-Za-z]{2,8}[0-9]{0,2});/', 'wp_kses_named_entities', $string);
1125      $string = preg_replace_callback('/&amp;#(0*[0-9]{1,7});/', 'wp_kses_normalize_entities2', $string);
1126      $string = preg_replace_callback('/&amp;#[Xx](0*[0-9A-Fa-f]{1,6});/', 'wp_kses_normalize_entities3', $string);
1127  
1128      return $string;
1129  }
1130  
1131  /**
1132   * Callback for wp_kses_normalize_entities() regular expression.
1133   *
1134   * This function only accepts valid named entity references, which are finite,
1135   * case-sensitive, and highly scrutinized by HTML and XML validators.
1136   *
1137   * @since 3.0.0
1138   *
1139   * @param array $matches preg_replace_callback() matches array
1140   * @return string Correctly encoded entity
1141   */
1142  function wp_kses_named_entities($matches) {
1143      global $allowedentitynames;
1144  
1145      if ( empty($matches[1]) )
1146          return '';
1147  
1148      $i = $matches[1];
1149      return ( ( ! in_array($i, $allowedentitynames) ) ? "&amp;$i;" : "&$i;" );
1150  }
1151  
1152  /**
1153   * Callback for wp_kses_normalize_entities() regular expression.
1154   *
1155   * This function helps wp_kses_normalize_entities() to only accept 16-bit values
1156   * and nothing more for &#number; entities.
1157   *
1158   * @access private
1159   * @since 1.0.0
1160   *
1161   * @param array $matches preg_replace_callback() matches array
1162   * @return string Correctly encoded entity
1163   */
1164  function wp_kses_normalize_entities2($matches) {
1165      if ( empty($matches[1]) )
1166          return '';
1167  
1168      $i = $matches[1];
1169      if (valid_unicode($i)) {
1170          $i = str_pad(ltrim($i,'0'), 3, '0', STR_PAD_LEFT);
1171          $i = "&#$i;";
1172      } else {
1173          $i = "&amp;#$i;";
1174      }
1175  
1176      return $i;
1177  }
1178  
1179  /**
1180   * Callback for wp_kses_normalize_entities() for regular expression.
1181   *
1182   * This function helps wp_kses_normalize_entities() to only accept valid Unicode
1183   * numeric entities in hex form.
1184   *
1185   * @access private
1186   *
1187   * @param array $matches preg_replace_callback() matches array
1188   * @return string Correctly encoded entity
1189   */
1190  function wp_kses_normalize_entities3($matches) {
1191      if ( empty($matches[1]) )
1192          return '';
1193  
1194      $hexchars = $matches[1];
1195      return ( ( ! valid_unicode(hexdec($hexchars)) ) ? "&amp;#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';' );
1196  }
1197  
1198  /**
1199   * Helper function to determine if a Unicode value is valid.
1200   *
1201   * @param int $i Unicode value
1202   * @return bool True if the value was a valid Unicode number
1203   */
1204  function valid_unicode($i) {
1205      return ( $i == 0x9 || $i == 0xa || $i == 0xd ||
1206              ($i >= 0x20 && $i <= 0xd7ff) ||
1207              ($i >= 0xe000 && $i <= 0xfffd) ||
1208              ($i >= 0x10000 && $i <= 0x10ffff) );
1209  }
1210  
1211  /**
1212   * Convert all entities to their character counterparts.
1213   *
1214   * This function decodes numeric HTML entities (&#65; and &#x41;). It doesn't do
1215   * anything with other entities like &auml;, but we don't need them in the URL
1216   * protocol whitelisting system anyway.
1217   *
1218   * @since 1.0.0
1219   *
1220   * @param string $string Content to change entities
1221   * @return string Content after decoded entities
1222   */
1223  function wp_kses_decode_entities($string) {
1224      $string = preg_replace_callback('/&#([0-9]+);/', '_wp_kses_decode_entities_chr', $string);
1225      $string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', '_wp_kses_decode_entities_chr_hexdec', $string);
1226  
1227      return $string;
1228  }
1229  
1230  /**
1231   * Regex callback for wp_kses_decode_entities()
1232   *
1233   * @param array $match preg match
1234   * @return string
1235   */
1236  function _wp_kses_decode_entities_chr( $match ) {
1237      return chr( $match[1] );
1238  }
1239  
1240  /**
1241   * Regex callback for wp_kses_decode_entities()
1242   *
1243   * @param array $match preg match
1244   * @return string
1245   */
1246  function _wp_kses_decode_entities_chr_hexdec( $match ) {
1247      return chr( hexdec( $match[1] ) );
1248  }
1249  
1250  /**
1251   * Sanitize content with allowed HTML Kses rules.
1252   *
1253   * @since 1.0.0
1254   * @uses $allowedtags
1255   *
1256   * @param string $data Content to filter, expected to be escaped with slashes
1257   * @return string Filtered content
1258   */
1259  function wp_filter_kses( $data ) {
1260      return addslashes( wp_kses( stripslashes( $data ), current_filter() ) );
1261  }
1262  
1263  /**
1264   * Sanitize content with allowed HTML Kses rules.
1265   *
1266   * @since 2.9.0
1267   * @uses $allowedtags
1268   *
1269   * @param string $data Content to filter, expected to not be escaped
1270   * @return string Filtered content
1271   */
1272  function wp_kses_data( $data ) {
1273      return wp_kses( $data , current_filter() );
1274  }
1275  
1276  /**
1277   * Sanitize content for allowed HTML tags for post content.
1278   *
1279   * Post content refers to the page contents of the 'post' type and not $_POST
1280   * data from forms.
1281   *
1282   * @since 2.0.0
1283   *
1284   * @param string $data Post content to filter, expected to be escaped with slashes
1285   * @return string Filtered post content with allowed HTML tags and attributes intact.
1286   */
1287  function wp_filter_post_kses($data) {
1288      return addslashes ( wp_kses( stripslashes( $data ), 'post' ) );
1289  }
1290  
1291  /**
1292   * Sanitize content for allowed HTML tags for post content.
1293   *
1294   * Post content refers to the page contents of the 'post' type and not $_POST
1295   * data from forms.
1296   *
1297   * @since 2.9.0
1298   *
1299   * @param string $data Post content to filter
1300   * @return string Filtered post content with allowed HTML tags and attributes intact.
1301   */
1302  function wp_kses_post($data) {
1303      return wp_kses( $data , 'post' );
1304  }
1305  
1306  /**
1307   * Strips all of the HTML in the content.
1308   *
1309   * @since 2.1.0
1310   *
1311   * @param string $data Content to strip all HTML from
1312   * @return string Filtered content without any HTML
1313   */
1314  function wp_filter_nohtml_kses( $data ) {
1315      return addslashes ( wp_kses( stripslashes( $data ), 'strip' ) );
1316  }
1317  
1318  /**
1319   * Adds all Kses input form content filters.
1320   *
1321   * All hooks have default priority. The wp_filter_kses() function is added to
1322   * the 'pre_comment_content' and 'title_save_pre' hooks.
1323   *
1324   * The wp_filter_post_kses() function is added to the 'content_save_pre',
1325   * 'excerpt_save_pre', and 'content_filtered_save_pre' hooks.
1326   *
1327   * @since 2.0.0
1328   * @uses add_filter() See description for what functions are added to what hooks.
1329   */
1330  function kses_init_filters() {
1331      // Normal filtering
1332      add_filter('title_save_pre', 'wp_filter_kses');
1333  
1334      // Comment filtering
1335      if ( current_user_can( 'unfiltered_html' ) )
1336          add_filter( 'pre_comment_content', 'wp_filter_post_kses' );
1337      else
1338          add_filter( 'pre_comment_content', 'wp_filter_kses' );
1339  
1340      // Post filtering
1341      add_filter('content_save_pre', 'wp_filter_post_kses');
1342      add_filter('excerpt_save_pre', 'wp_filter_post_kses');
1343      add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
1344  }
1345  
1346  /**
1347   * Removes all Kses input form content filters.
1348   *
1349   * A quick procedural method to removing all of the filters that kses uses for
1350   * content in WordPress Loop.
1351   *
1352   * Does not remove the kses_init() function from 'init' hook (priority is
1353   * default). Also does not remove kses_init() function from 'set_current_user'
1354   * hook (priority is also default).
1355   *
1356   * @since 2.0.6
1357   */
1358  function kses_remove_filters() {
1359      // Normal filtering
1360      remove_filter('title_save_pre', 'wp_filter_kses');
1361  
1362      // Comment filtering
1363      remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
1364      remove_filter( 'pre_comment_content', 'wp_filter_kses' );
1365  
1366      // Post filtering
1367      remove_filter('content_save_pre', 'wp_filter_post_kses');
1368      remove_filter('excerpt_save_pre', 'wp_filter_post_kses');
1369      remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');
1370  }
1371  
1372  /**
1373   * Sets up most of the Kses filters for input form content.
1374   *
1375   * If you remove the kses_init() function from 'init' hook and
1376   * 'set_current_user' (priority is default), then none of the Kses filter hooks
1377   * will be added.
1378   *
1379   * First removes all of the Kses filters in case the current user does not need
1380   * to have Kses filter the content. If the user does not have unfiltered_html
1381   * capability, then Kses filters are added.
1382   *
1383   * @uses kses_remove_filters() Removes the Kses filters
1384   * @uses kses_init_filters() Adds the Kses filters back if the user
1385   *        does not have unfiltered HTML capability.
1386   * @since 2.0.0
1387   */
1388  function kses_init() {
1389      kses_remove_filters();
1390  
1391      if (current_user_can('unfiltered_html') == false)
1392          kses_init_filters();
1393  }
1394  
1395  add_action('init', 'kses_init');
1396  add_action('set_current_user', 'kses_init');
1397  
1398  /**
1399   * Inline CSS filter
1400   *
1401   * @since 2.8.1
1402   */
1403  function safecss_filter_attr( $css, $deprecated = '' ) {
1404      if ( !empty( $deprecated ) )
1405          _deprecated_argument( __FUNCTION__, '2.8.1' ); // Never implemented
1406  
1407      $css = wp_kses_no_null($css);
1408      $css = str_replace(array("\n","\r","\t"), '', $css);
1409  
1410      if ( preg_match( '%[\\(&=}]|/\*%', $css ) ) // remove any inline css containing \ ( & } = or comments
1411          return '';
1412  
1413      $css_array = explode( ';', trim( $css ) );
1414      $allowed_attr = apply_filters( 'safe_style_css', array( 'text-align', 'margin', 'color', 'float',
1415      'border', 'background', 'background-color', 'border-bottom', 'border-bottom-color',
1416      'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-left',
1417      'border-left-color', 'border-left-style', 'border-left-width', 'border-right', 'border-right-color',
1418      'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top',
1419      'border-top-color', 'border-top-style', 'border-top-width', 'border-width', 'caption-side',
1420      'clear', 'cursor', 'direction', 'font', 'font-family', 'font-size', 'font-style',
1421      'font-variant', 'font-weight', 'height', 'letter-spacing', 'line-height', 'margin-bottom',
1422      'margin-left', 'margin-right', 'margin-top', 'overflow', 'padding', 'padding-bottom',
1423      'padding-left', 'padding-right', 'padding-top', 'text-decoration', 'text-indent', 'vertical-align',
1424      'width' ) );
1425  
1426      if ( empty($allowed_attr) )
1427          return $css;
1428  
1429      $css = '';
1430      foreach ( $css_array as $css_item ) {
1431          if ( $css_item == '' )
1432              continue;
1433          $css_item = trim( $css_item );
1434          $found = false;
1435          if ( strpos( $css_item, ':' ) === false ) {
1436              $found = true;
1437          } else {
1438              $parts = explode( ':', $css_item );
1439              if ( in_array( trim( $parts[0] ), $allowed_attr ) )
1440                  $found = true;
1441          }
1442          if ( $found ) {
1443              if( $css != '' )
1444                  $css .= ';';
1445              $css .= $css_item;
1446          }
1447      }
1448  
1449      return $css;
1450  }
1451  
1452  /**
1453   * Helper function to add global attributes to a tag in the allowed html list.
1454   *
1455   * @since 3.5.0
1456   * @access private
1457   *
1458   * @param array $value An array of attributes.
1459   * @return array The array of attributes with global attributes added.
1460   */
1461  function _wp_add_global_attributes( $value ) {
1462      $global_attributes = array(
1463          'class' => true,
1464          'id' => true,
1465          'style' => true,
1466          'title' => true,
1467      );
1468  
1469      if ( true === $value )
1470          $value = array();
1471  
1472      if ( is_array( $value ) )
1473          return array_merge( $value, $global_attributes );
1474  
1475      return $value;
1476  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu