Wordpress 3.5
[autoinstalls/wordpress.git] / wp-includes / kses.php
index b9f13face0d4120acf5ef663840b1d8b3ce46272..4c42134e7a7d689c22d66aeb049b3140c7436900 100644 (file)
 /**
  * You can override this in a plugin.
  *
+ * The wp_kses_allowed_html filter is more powerful and supplies context.
+ * CUSTOM_TAGS is not recommended and should be considered deprecated.
+ *
+ * @see wp_kses_allowed_html()
+ *
  * @since 1.2.0
  */
 if ( ! defined( 'CUSTOM_TAGS' ) )
@@ -51,50 +56,42 @@ if ( ! CUSTOM_TAGS ) {
        $allowedposttags = array(
                'address' => array(),
                'a' => array(
-                       'class' => true,
                        'href' => true,
-                       'id' => true,
-                       'title' => true,
                        'rel' => true,
                        'rev' => true,
                        'name' => true,
                        'target' => true,
                ),
-               'abbr' => array(
-                       'class' => true,
-                       'title' => true,
-               ),
-               'acronym' => array(
-                       'title' => true,
+               'abbr' => array(),
+               'acronym' => array(),
+               'area' => array(
+                       'alt' => true,
+                       'coords' => true,
+                       'href' => true,
+                       'nohref' => true,
+                       'shape' => true,
+                       'target' => true,
                ),
                'article' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'aside' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'b' => array(),
                'big' => array(),
                'blockquote' => array(
-                       'id' => true,
                        'cite' => true,
-                       'class' => true,
                        'lang' => true,
                        'xml:lang' => true,
                ),
-               'br' => array (
-                       'class' => true,
-               ),
+               'br' => array(),
                'button' => array(
                        'disabled' => true,
                        'name' => true,
@@ -103,24 +100,18 @@ if ( ! CUSTOM_TAGS ) {
                ),
                'caption' => array(
                        'align' => true,
-                       'class' => true,
                ),
-               'cite' => array (
-                       'class' => true,
+               'cite' => array(
                        'dir' => true,
                        'lang' => true,
-                       'title' => true,
-               ),
-               'code' => array (
-                       'style' => true,
                ),
+               'code' => array(),
                'col' => array(
                        'align' => true,
                        'char' => true,
                        'charoff' => true,
                        'span' => true,
                        'dir' => true,
-                       'style' => true,
                        'valign' => true,
                        'width' => true,
                ),
@@ -130,19 +121,15 @@ if ( ! CUSTOM_TAGS ) {
                'dd' => array(),
                'details' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
                        'open' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'div' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'dl' => array(),
@@ -151,18 +138,14 @@ if ( ! CUSTOM_TAGS ) {
                'fieldset' => array(),
                'figure' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'figcaption' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'font' => array(
@@ -172,10 +155,8 @@ if ( ! CUSTOM_TAGS ) {
                ),
                'footer' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'form' => array(
@@ -189,59 +170,36 @@ if ( ! CUSTOM_TAGS ) {
                ),
                'h1' => array(
                        'align' => true,
-                       'class' => true,
-                       'id'    => true,
-                       'style' => true,
                ),
-               'h2' => array (
+               'h2' => array(
                        'align' => true,
-                       'class' => true,
-                       'id'    => true,
-                       'style' => true,
                ),
-               'h3' => array (
+               'h3' => array(
                        'align' => true,
-                       'class' => true,
-                       'id'    => true,
-                       'style' => true,
                ),
-               'h4' => array (
+               'h4' => array(
                        'align' => true,
-                       'class' => true,
-                       'id'    => true,
-                       'style' => true,
                ),
-               'h5' => array (
+               'h5' => array(
                        'align' => true,
-                       'class' => true,
-                       'id'    => true,
-                       'style' => true,
                ),
-               'h6' => array (
+               'h6' => array(
                        'align' => true,
-                       'class' => true,
-                       'id'    => true,
-                       'style' => true,
                ),
                'header' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'hgroup' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
-               'hr' => array (
+               'hr' => array(
                        'align' => true,
-                       'class' => true,
                        'noshade' => true,
                        'size' => true,
                        'width' => true,
@@ -251,13 +209,12 @@ if ( ! CUSTOM_TAGS ) {
                        'alt' => true,
                        'align' => true,
                        'border' => true,
-                       'class' => true,
                        'height' => true,
                        'hspace' => true,
                        'longdesc' => true,
                        'vspace' => true,
                        'src' => true,
-                       'style' => true,
+                       'usemap' => true,
                        'width' => true,
                ),
                'ins' => array(
@@ -271,65 +228,54 @@ if ( ! CUSTOM_TAGS ) {
                'legend' => array(
                        'align' => true,
                ),
-               'li' => array (
+               'li' => array(
                        'align' => true,
-                       'class' => true,
                ),
-               'menu' => array (
-                       'class' => true,
-                       'style' => true,
+               'map' => array(
+                       'name' => true,
+               ),
+               'menu' => array(
                        'type' => true,
                ),
                'nav' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'p' => array(
-                       'class' => true,
                        'align' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'pre' => array(
-                       'style' => true,
                        'width' => true,
                ),
                'q' => array(
                        'cite' => true,
                ),
                's' => array(),
-               'span' => array (
-                       'class' => true,
+               'span' => array(
                        'dir' => true,
                        'align' => true,
                        'lang' => true,
-                       'style' => true,
-                       'title' => true,
                        'xml:lang' => true,
                ),
                'section' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
+               'small' => array(),
                'strike' => array(),
                'strong' => array(),
                'sub' => array(),
                'summary' => array(
                        'align' => true,
-                       'class' => true,
                        'dir' => true,
                        'lang' => true,
-                       'style' => true,
                        'xml:lang' => true,
                ),
                'sup' => array(),
@@ -339,11 +285,8 @@ if ( ! CUSTOM_TAGS ) {
                        'border' => true,
                        'cellpadding' => true,
                        'cellspacing' => true,
-                       'class' => true,
                        'dir' => true,
-                       'id' => true,
                        'rules' => true,
-                       'style' => true,
                        'summary' => true,
                        'width' => true,
                ),
@@ -360,7 +303,6 @@ if ( ! CUSTOM_TAGS ) {
                        'bgcolor' => true,
                        'char' => true,
                        'charoff' => true,
-                       'class' => true,
                        'colspan' => true,
                        'dir' => true,
                        'headers' => true,
@@ -368,7 +310,6 @@ if ( ! CUSTOM_TAGS ) {
                        'nowrap' => true,
                        'rowspan' => true,
                        'scope' => true,
-                       'style' => true,
                        'valign' => true,
                        'width' => true,
                ),
@@ -382,7 +323,6 @@ if ( ! CUSTOM_TAGS ) {
                'tfoot' => array(
                        'align' => true,
                        'char' => true,
-                       'class' => true,
                        'charoff' => true,
                        'valign' => true,
                ),
@@ -393,7 +333,6 @@ if ( ! CUSTOM_TAGS ) {
                        'bgcolor' => true,
                        'char' => true,
                        'charoff' => true,
-                       'class' => true,
                        'colspan' => true,
                        'headers' => true,
                        'height' => true,
@@ -407,7 +346,6 @@ if ( ! CUSTOM_TAGS ) {
                        'align' => true,
                        'char' => true,
                        'charoff' => true,
-                       'class' => true,
                        'valign' => true,
                ),
                'title' => array(),
@@ -416,21 +354,15 @@ if ( ! CUSTOM_TAGS ) {
                        'bgcolor' => true,
                        'char' => true,
                        'charoff' => true,
-                       'class' => true,
-                       'style' => true,
                        'valign' => true,
                ),
                'tt' => array(),
                'u' => array(),
-               'ul' => array (
-                       'class' => true,
-                       'style' => true,
+               'ul' => array(
                        'type' => true,
                ),
-               'ol' => array (
-                       'class' => true,
+               'ol' => array(
                        'start' => true,
-                       'style' => true,
                        'type' => true,
                ),
                'var' => array(),
@@ -457,29 +389,18 @@ if ( ! CUSTOM_TAGS ) {
                'blockquote' => array(
                        'cite' => true,
                ),
-               //      'br' => array(),
                'cite' => array(),
                'code' => array(),
                'del' => array(
                        'datetime' => true,
                ),
-               //      'dd' => array(),
-               //      'dl' => array(),
-               //      'dt' => array(),
-               'em' => array (), 'i' => array (),
-               //      'ins' => array('datetime' => array(), 'cite' => array()),
-               //      'li' => array(),
-               //      'ol' => array(),
-               //      'p' => array(),
+               'em' => array(),
+               'i' => array(),
                'q' => array(
                        'cite' => true,
                ),
                'strike' => array(),
                'strong' => array(),
-               //      'sub' => array(),
-               //      'sup' => array(),
-               //      'u' => array(),
-               //      'ul' => array(),
        );
 
        $allowedentitynames = array(
@@ -525,6 +446,11 @@ if ( ! CUSTOM_TAGS ) {
                'sdot',    'lceil',  'rceil',   'lfloor', 'rfloor', 'lang',
                'rang',    'loz',    'spades',  'clubs',  'hearts', 'diams',
        );
+
+       $allowedposttags = array_map( '_wp_add_global_attributes', $allowedposttags );
+} else {
+       $allowedtags = wp_kses_array_lc( $allowedtags );
+       $allowedposttags = wp_kses_array_lc( $allowedposttags );
 }
 
 /**
@@ -547,15 +473,51 @@ if ( ! CUSTOM_TAGS ) {
  * @param array $allowed_protocols Optional. Allowed protocol in links.
  * @return string Filtered content with only allowed HTML elements
  */
-function wp_kses($string, $allowed_html, $allowed_protocols = array ()) {
+function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) {
        if ( empty( $allowed_protocols ) )
                $allowed_protocols = wp_allowed_protocols();
        $string = wp_kses_no_null($string);
        $string = wp_kses_js_entities($string);
        $string = wp_kses_normalize_entities($string);
-       $allowed_html_fixed = wp_kses_array_lc($allowed_html);
-       $string = wp_kses_hook($string, $allowed_html_fixed, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook
-       return wp_kses_split($string, $allowed_html_fixed, $allowed_protocols);
+       $string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook
+       return wp_kses_split($string, $allowed_html, $allowed_protocols);
+}
+
+/**
+ * Return a list of allowed tags and attributes for a given context.
+ *
+ * @since 3.5.0
+ *
+ * @param string $context The context for which to retrieve tags. Allowed values are
+ *  post | strip | data | entities or the name of a field filter such as pre_user_description.
+ * @return array List of allowed tags and their allowed attributes.
+ */
+function wp_kses_allowed_html( $context = '' ) {
+       global $allowedposttags, $allowedtags, $allowedentitynames;
+
+       if ( is_array( $context ) )
+               return apply_filters( 'wp_kses_allowed_html', $context, 'explicit' );
+
+       switch ( $context ) {
+               case 'post':
+                       return apply_filters( 'wp_kses_allowed_html', $allowedposttags, $context );
+                       break;
+               case 'user_description':
+               case 'pre_user_description':
+                       $tags = $allowedtags;
+                       $tags['a']['rel'] = true;
+                       return apply_filters( 'wp_kses_allowed_html', $tags, $context );
+                       break;
+               case 'strip':
+                       return apply_filters( 'wp_kses_allowed_html', array(), $context );
+                       break;
+               case 'entities':
+                       return apply_filters( 'wp_kses_allowed_html', $allowedentitynames, $context);
+                       break;
+               case 'data':
+               default:
+                       return apply_filters( 'wp_kses_allowed_html', $allowedtags, $context );
+       }
 }
 
 /**
@@ -571,7 +533,7 @@ function wp_kses($string, $allowed_html, $allowed_protocols = array ()) {
  * @param array $allowed_protocols Allowed protocol in links
  * @return string Filtered content through 'pre_kses' hook
  */
-function wp_kses_hook($string, $allowed_html, $allowed_protocols) {
+function wp_kses_hook( $string, $allowed_html, $allowed_protocols ) {
        $string = apply_filters('pre_kses', $string, $allowed_html, $allowed_protocols);
        return $string;
 }
@@ -599,7 +561,7 @@ function wp_kses_version() {
  * @param array $allowed_protocols Allowed protocols to keep
  * @return string Content with fixed HTML tags
  */
-function wp_kses_split($string, $allowed_html, $allowed_protocols) {
+function wp_kses_split( $string, $allowed_html, $allowed_protocols ) {
        global $pass_allowed_html, $pass_allowed_protocols;
        $pass_allowed_html = $allowed_html;
        $pass_allowed_protocols = $allowed_protocols;
@@ -667,6 +629,9 @@ function wp_kses_split2($string, $allowed_html, $allowed_protocols) {
        $elem = $matches[2];
        $attrlist = $matches[3];
 
+       if ( ! is_array( $allowed_html ) )
+               $allowed_html = wp_kses_allowed_html( $allowed_html );
+
        if ( ! isset($allowed_html[strtolower($elem)]) )
                return '';
        # They are using a not allowed HTML element
@@ -698,6 +663,9 @@ function wp_kses_split2($string, $allowed_html, $allowed_protocols) {
 function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) {
        # Is there a closing XHTML slash at the end of the attributes?
 
+       if ( ! is_array( $allowed_html ) )
+               $allowed_html = wp_kses_allowed_html( $allowed_html );
+
        $xhtml_slash = '';
        if (preg_match('%\s*/\s*$%', $attr))
                $xhtml_slash = ' /';
@@ -776,7 +744,7 @@ function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) {
  * @return array List of attributes after parsing
  */
 function wp_kses_hair($attr, $allowed_protocols) {
-       $attrarr = array ();
+       $attrarr = array();
        $mode = 0;
        $attrname = '';
        $uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action');
@@ -1285,9 +1253,8 @@ function _wp_kses_decode_entities_chr_hexdec( $match ) {
  * @param string $data Content to filter, expected to be escaped with slashes
  * @return string Filtered content
  */
-function wp_filter_kses($data) {
-       global $allowedtags;
-       return addslashes( wp_kses(stripslashes( $data ), $allowedtags) );
+function wp_filter_kses( $data ) {
+       return addslashes( wp_kses( stripslashes( $data ), current_filter() ) );
 }
 
 /**
@@ -1299,9 +1266,8 @@ function wp_filter_kses($data) {
  * @param string $data Content to filter, expected to not be escaped
  * @return string Filtered content
  */
-function wp_kses_data($data) {
-       global $allowedtags;
-       return wp_kses( $data , $allowedtags );
+function wp_kses_data( $data ) {
+       return wp_kses( $data , current_filter() );
 }
 
 /**
@@ -1311,14 +1277,12 @@ function wp_kses_data($data) {
  * data from forms.
  *
  * @since 2.0.0
- * @uses $allowedposttags
  *
  * @param string $data Post content to filter, expected to be escaped with slashes
  * @return string Filtered post content with allowed HTML tags and attributes intact.
  */
 function wp_filter_post_kses($data) {
-       global $allowedposttags;
-       return addslashes ( wp_kses(stripslashes( $data ), $allowedposttags) );
+       return addslashes ( wp_kses( stripslashes( $data ), 'post' ) );
 }
 
 /**
@@ -1328,14 +1292,12 @@ function wp_filter_post_kses($data) {
  * data from forms.
  *
  * @since 2.9.0
- * @uses $allowedposttags
  *
  * @param string $data Post content to filter
  * @return string Filtered post content with allowed HTML tags and attributes intact.
  */
 function wp_kses_post($data) {
-       global $allowedposttags;
-       return wp_kses( $data , $allowedposttags );
+       return wp_kses( $data , 'post' );
 }
 
 /**
@@ -1346,8 +1308,8 @@ function wp_kses_post($data) {
  * @param string $data Content to strip all HTML from
  * @return string Filtered content without any HTML
  */
-function wp_filter_nohtml_kses($data) {
-       return addslashes ( wp_kses(stripslashes( $data ), array()) );
+function wp_filter_nohtml_kses( $data ) {
+       return addslashes ( wp_kses( stripslashes( $data ), 'strip' ) );
 }
 
 /**
@@ -1483,3 +1445,29 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
 
        return $css;
 }
+
+/**
+ * Helper function to add global attributes to a tag in the allowed html list.
+ *
+ * @since 3.5.0
+ * @access private
+ *
+ * @param array $value An array of attributes.
+ * @return array The array of attributes with global attributes added.
+ */
+function _wp_add_global_attributes( $value ) {
+       $global_attributes = array(
+               'class' => true,
+               'id' => true,
+               'style' => true,
+               'title' => true,
+       );
+
+       if ( true === $value )
+               $value = array();
+
+       if ( is_array( $value ) )
+               return array_merge( $value, $global_attributes );
+
+       return $value;
+}