WordPress.org

Make WordPress Core

Changeset 21790


Ignore:
Timestamp:
09/10/2012 04:19:54 PM (8 years ago)
Author:
ryan
Message:
  • Introduce wp_kses_allowed_html() which accepts a context string and returns an array of allowed tags.
  • Remove explicit declarations of class, id, style, and title from $allowedposttags
  • Dynamicallly add global attributes to every tag for the 'post' context
  • No longer calls wp_kses_array_lc() every time wp_kses() runs. Instead it runs once if CUSTOM_TAGS is true. Plugins directly passing a custom allowed_html array will no longer get the lc treatment. Keep an eye out for problems with this.
  • wp_kses_data() and wp_filter_kses() pass current_filter() for the $allowed_html argument to wp_kses().
  • wp_kses_allowed_html() handles being passed a filter name for a context. If the filter is not a recognized one it defaults to using $allowedtags as was done before for wp_kses_data() and wp_filter_kses().
  • wp_kses_allowed_html() recognizes user_description and pre_user_description out of the box. For these it takes $allowedtags and inserts rel attribute support.
  • wp_kses_allowed_html() allows plugins to override the return values for the default contexts and support arbitrary contexts via a wp_kses_allowed_html filter.
  • wp_kses_hook() can now pass a string context for $allowed_html to the pre_kses filter. We might have to pass the result of wp_kses_allowed_html() instead if it turns out that plugins are digging in $allowed_html.

fixes #17977
see #20210

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/kses.php

    r21777 r21790  
    5252        'address' => array(),
    5353        'a' => array(
    54             'class' => true,
    5554            'href' => true,
    56             'id' => true,
    57             'title' => true,
    5855            'rel' => true,
    5956            'rev' => true,
     
    6158            'target' => true,
    6259        ),
    63         'abbr' => array(
    64             'class' => true,
    65             'title' => true,
    66         ),
    67         'acronym' => array(
    68             'title' => true,
     60        'abbr' => array(),
     61        'acronym' => array(),
     62        'area' => array(
     63            'alt' => true,
     64            'coords' => true,
     65            'href' => true,
     66            'nohref' => true,
     67            'shape' => true,
     68            'target' => true,
    6969        ),
    7070        'article' => array(
    7171            'align' => true,
    72             'class' => true,
    73             'dir' => true,
    74             'lang' => true,
    75             'style' => true,
     72            'dir' => true,
     73            'lang' => true,
    7674            'xml:lang' => true,
    7775        ),
    7876        'aside' => array(
    7977            'align' => true,
    80             'class' => true,
    81             'dir' => true,
    82             'lang' => true,
    83             'style' => true,
     78            'dir' => true,
     79            'lang' => true,
    8480            'xml:lang' => true,
    8581        ),
     
    8783        'big' => array(),
    8884        'blockquote' => array(
    89             'id' => true,
    9085            'cite' => true,
    91             'class' => true,
    9286            'lang' => true,
    9387            'xml:lang' => true,
    9488        ),
    95         'br' => array (
    96             'class' => true,
    97         ),
     89        'br' => array(),
    9890        'button' => array(
    9991            'disabled' => true,
     
    10496        'caption' => array(
    10597            'align' => true,
    106             'class' => true,
    107         ),
    108         'cite' => array (
    109             'class' => true,
    110             'dir' => true,
    111             'lang' => true,
    112             'title' => true,
    113         ),
    114         'code' => array (
    115             'style' => true,
    116         ),
     98        ),
     99        'cite' => array(
     100            'dir' => true,
     101            'lang' => true,
     102        ),
     103        'code' => array(),
    117104        'col' => array(
    118105            'align' => true,
     
    121108            'span' => true,
    122109            'dir' => true,
    123             'style' => true,
    124110            'valign' => true,
    125111            'width' => true,
     
    131117        'details' => array(
    132118            'align' => true,
    133             'class' => true,
    134119            'dir' => true,
    135120            'lang' => true,
    136121            'open' => true,
    137             'style' => true,
    138122            'xml:lang' => true,
    139123        ),
    140124        'div' => array(
    141125            'align' => true,
    142             'class' => true,
    143             'dir' => true,
    144             'lang' => true,
    145             'style' => true,
     126            'dir' => true,
     127            'lang' => true,
    146128            'xml:lang' => true,
    147129        ),
     
    152134        'figure' => array(
    153135            'align' => true,
    154             'class' => true,
    155             'dir' => true,
    156             'lang' => true,
    157             'style' => true,
     136            'dir' => true,
     137            'lang' => true,
    158138            'xml:lang' => true,
    159139        ),
    160140        'figcaption' => array(
    161141            'align' => true,
    162             'class' => true,
    163             'dir' => true,
    164             'lang' => true,
    165             'style' => true,
     142            'dir' => true,
     143            'lang' => true,
    166144            'xml:lang' => true,
    167145        ),
     
    173151        'footer' => array(
    174152            'align' => true,
    175             'class' => true,
    176             'dir' => true,
    177             'lang' => true,
    178             'style' => true,
     153            'dir' => true,
     154            'lang' => true,
    179155            'xml:lang' => true,
    180156        ),
     
    190166        'h1' => array(
    191167            'align' => true,
    192             'class' => true,
    193             'id'    => true,
    194             'style' => true,
    195         ),
    196         'h2' => array (
    197             'align' => true,
    198             'class' => true,
    199             'id'    => true,
    200             'style' => true,
    201         ),
    202         'h3' => array (
    203             'align' => true,
    204             'class' => true,
    205             'id'    => true,
    206             'style' => true,
    207         ),
    208         'h4' => array (
    209             'align' => true,
    210             'class' => true,
    211             'id'    => true,
    212             'style' => true,
    213         ),
    214         'h5' => array (
    215             'align' => true,
    216             'class' => true,
    217             'id'    => true,
    218             'style' => true,
    219         ),
    220         'h6' => array (
    221             'align' => true,
    222             'class' => true,
    223             'id'    => true,
    224             'style' => true,
     168        ),
     169        'h2' => array(
     170            'align' => true,
     171        ),
     172        'h3' => array(
     173            'align' => true,
     174        ),
     175        'h4' => array(
     176            'align' => true,
     177        ),
     178        'h5' => array(
     179            'align' => true,
     180        ),
     181        'h6' => array(
     182            'align' => true,
    225183        ),
    226184        'header' => array(
    227185            'align' => true,
    228             'class' => true,
    229             'dir' => true,
    230             'lang' => true,
    231             'style' => true,
     186            'dir' => true,
     187            'lang' => true,
    232188            'xml:lang' => true,
    233189        ),
    234190        'hgroup' => array(
    235191            'align' => true,
    236             'class' => true,
    237             'dir' => true,
    238             'lang' => true,
    239             'style' => true,
     192            'dir' => true,
     193            'lang' => true,
    240194            'xml:lang' => true,
    241195        ),
    242         'hr' => array (
    243             'align' => true,
    244             'class' => true,
     196        'hr' => array(
     197            'align' => true,
    245198            'noshade' => true,
    246199            'size' => true,
     
    252205            'align' => true,
    253206            'border' => true,
    254             'class' => true,
    255207            'height' => true,
    256208            'hspace' => true,
     
    258210            'vspace' => true,
    259211            'src' => true,
    260             'style' => true,
     212            'usemap' => true,
    261213            'width' => true,
    262214        ),
     
    272224            'align' => true,
    273225        ),
    274         'li' => array (
    275             'align' => true,
    276             'class' => true,
    277         ),
    278         'menu' => array (
    279             'class' => true,
    280             'style' => true,
     226        'li' => array(
     227            'align' => true,
     228        ),
     229        'map' => array(
     230            'name' => true,
     231        ),
     232        'menu' => array(
    281233            'type' => true,
    282234        ),
    283235        'nav' => array(
    284236            'align' => true,
    285             'class' => true,
    286             'dir' => true,
    287             'lang' => true,
    288             'style' => true,
     237            'dir' => true,
     238            'lang' => true,
    289239            'xml:lang' => true,
    290240        ),
    291241        'p' => array(
    292             'class' => true,
    293             'align' => true,
    294             'dir' => true,
    295             'lang' => true,
    296             'style' => true,
     242            'align' => true,
     243            'dir' => true,
     244            'lang' => true,
    297245            'xml:lang' => true,
    298246        ),
    299247        'pre' => array(
    300             'style' => true,
    301248            'width' => true,
    302249        ),
     
    305252        ),
    306253        's' => array(),
    307         'span' => array (
    308             'class' => true,
    309             'dir' => true,
    310             'align' => true,
    311             'lang' => true,
    312             'style' => true,
    313             'title' => true,
     254        'span' => array(
     255            'dir' => true,
     256            'align' => true,
     257            'lang' => true,
    314258            'xml:lang' => true,
    315259        ),
    316260        'section' => array(
    317261            'align' => true,
    318             'class' => true,
    319             'dir' => true,
    320             'lang' => true,
    321             'style' => true,
     262            'dir' => true,
     263            'lang' => true,
    322264            'xml:lang' => true,
    323265        ),
     
    328270        'summary' => array(
    329271            'align' => true,
    330             'class' => true,
    331             'dir' => true,
    332             'lang' => true,
    333             'style' => true,
     272            'dir' => true,
     273            'lang' => true,
    334274            'xml:lang' => true,
    335275        ),
     
    341281            'cellpadding' => true,
    342282            'cellspacing' => true,
    343             'class' => true,
    344             'dir' => true,
    345             'id' => true,
     283            'dir' => true,
    346284            'rules' => true,
    347             'style' => true,
    348285            'summary' => true,
    349286            'width' => true,
     
    362299            'char' => true,
    363300            'charoff' => true,
    364             'class' => true,
    365301            'colspan' => true,
    366302            'dir' => true,
     
    370306            'rowspan' => true,
    371307            'scope' => true,
    372             'style' => true,
    373308            'valign' => true,
    374309            'width' => true,
     
    384319            'align' => true,
    385320            'char' => true,
    386             'class' => true,
    387321            'charoff' => true,
    388322            'valign' => true,
     
    395329            'char' => true,
    396330            'charoff' => true,
    397             'class' => true,
    398331            'colspan' => true,
    399332            'headers' => true,
     
    409342            'char' => true,
    410343            'charoff' => true,
    411             'class' => true,
    412344            'valign' => true,
    413345        ),
     
    418350            'char' => true,
    419351            'charoff' => true,
    420             'class' => true,
    421             'style' => true,
    422352            'valign' => true,
    423353        ),
    424354        'tt' => array(),
    425355        'u' => array(),
    426         'ul' => array (
    427             'class' => true,
    428             'style' => true,
     356        'ul' => array(
    429357            'type' => true,
    430358        ),
    431         'ol' => array (
    432             'class' => true,
     359        'ol' => array(
    433360            'start' => true,
    434             'style' => true,
    435361            'type' => true,
    436362        ),
     
    468394        //  'dl' => array(),
    469395        //  'dt' => array(),
    470         'em' => array (), 'i' => array (),
     396        'em' => array(),
     397        'i' => array(),
    471398        //  'ins' => array('datetime' => array(), 'cite' => array()),
    472399        //  'li' => array(),
     
    527454        'rang',    'loz',    'spades',  'clubs',  'hearts', 'diams',
    528455    );
     456
     457    $allowedposttags = array_map( '_wp_add_global_attributes', $allowedposttags );
     458} else {
     459    $allowedtags = wp_kses_array_lc( $allowedtags );
     460    $allowedposttags = wp_kses_array_lc( $allowedposttags );
    529461}
    530462
     
    549481 * @return string Filtered content with only allowed HTML elements
    550482 */
    551 function wp_kses($string, $allowed_html, $allowed_protocols = array ()) {
     483function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) {
    552484    if ( empty( $allowed_protocols ) )
    553485        $allowed_protocols = wp_allowed_protocols();
     
    555487    $string = wp_kses_js_entities($string);
    556488    $string = wp_kses_normalize_entities($string);
    557     $allowed_html_fixed = wp_kses_array_lc($allowed_html);
    558     $string = wp_kses_hook($string, $allowed_html_fixed, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook
    559     return wp_kses_split($string, $allowed_html_fixed, $allowed_protocols);
     489    $string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook
     490    return wp_kses_split($string, $allowed_html, $allowed_protocols);
     491}
     492
     493/**
     494 * Return a list of allowed tags and attributes for a given context.
     495 *
     496 * @since 3.5.0
     497 *
     498 * @param string $context The context for which to retrieve tags. Allowed values are
     499 *  post | strip | data | entities or the name of a field filter such as pre_user_description.
     500 * @return array List of allowed tags and their allowed attributes.
     501 */
     502function wp_kses_allowed_html( $context = '' ) {
     503    global $allowedposttags, $allowedtags, $allowedentitynames;
     504
     505    if ( is_array( $context ) )
     506        return apply_filters( 'wp_kses_allowed_html', $context, 'explicit' );
     507
     508    switch ( $context ) {
     509        case 'post':
     510            return apply_filters( 'wp_kses_allowed_html', $allowedposttags, $context );
     511            break;
     512        case 'user_description':
     513        case 'pre_user_description':
     514            $tags = $allowedtags;
     515            $tags['a']['rel'] = true;
     516            return apply_filters( 'wp_kses_allowed_html', $tags, $context );
     517            break;
     518        case 'strip':
     519            return apply_filters( 'wp_kses_allowed_html', array(), $context );
     520            break;
     521        case 'entities':
     522            return apply_filters( 'wp_kses_allowed_html', $allowedentitynames, $context);
     523            break;
     524        case 'data':
     525        default:
     526            return apply_filters( 'wp_kses_allowed_html', $allowedtags, $context );
     527    }
    560528}
    561529
     
    573541 * @return string Filtered content through 'pre_kses' hook
    574542 */
    575 function wp_kses_hook($string, $allowed_html, $allowed_protocols) {
     543function wp_kses_hook( $string, $allowed_html, $allowed_protocols ) {
    576544    $string = apply_filters('pre_kses', $string, $allowed_html, $allowed_protocols);
    577545    return $string;
     
    601569 * @return string Content with fixed HTML tags
    602570 */
    603 function wp_kses_split($string, $allowed_html, $allowed_protocols) {
     571function wp_kses_split( $string, $allowed_html, $allowed_protocols ) {
    604572    global $pass_allowed_html, $pass_allowed_protocols;
    605573    $pass_allowed_html = $allowed_html;
     
    669637    $attrlist = $matches[3];
    670638
     639    if ( ! is_array( $allowed_html ) )
     640        $allowed_html = wp_kses_allowed_html( $allowed_html );
     641
    671642    if ( ! isset($allowed_html[strtolower($elem)]) )
    672643        return '';
     
    699670function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) {
    700671    # Is there a closing XHTML slash at the end of the attributes?
     672
     673    if ( ! is_array( $allowed_html ) )
     674        $allowed_html = wp_kses_allowed_html( $allowed_html );
    701675
    702676    $xhtml_slash = '';
     
    778752 */
    779753function wp_kses_hair($attr, $allowed_protocols) {
    780     $attrarr = array ();
     754    $attrarr = array();
    781755    $mode = 0;
    782756    $attrname = '';
     
    12871261 * @return string Filtered content
    12881262 */
    1289 function wp_filter_kses($data) {
    1290     global $allowedtags;
    1291     return addslashes( wp_kses(stripslashes( $data ), $allowedtags) );
     1263function wp_filter_kses( $data ) {
     1264    return addslashes( wp_kses( stripslashes( $data ), current_filter() ) );
    12921265}
    12931266
     
    13011274 * @return string Filtered content
    13021275 */
    1303 function wp_kses_data($data) {
    1304     global $allowedtags;
    1305     return wp_kses( $data , $allowedtags );
     1276function wp_kses_data( $data ) {
     1277    return wp_kses( $data , current_filter() );
    13061278}
    13071279
     
    13131285 *
    13141286 * @since 2.0.0
    1315  * @uses $allowedposttags
    13161287 *
    13171288 * @param string $data Post content to filter, expected to be escaped with slashes
     
    13191290 */
    13201291function wp_filter_post_kses($data) {
    1321     global $allowedposttags;
    1322     return addslashes ( wp_kses(stripslashes( $data ), $allowedposttags) );
     1292    return addslashes ( wp_kses( stripslashes( $data ), 'post' ) );
    13231293}
    13241294
     
    13301300 *
    13311301 * @since 2.9.0
    1332  * @uses $allowedposttags
    13331302 *
    13341303 * @param string $data Post content to filter
     
    13361305 */
    13371306function wp_kses_post($data) {
    1338     global $allowedposttags;
    1339     return wp_kses( $data , $allowedposttags );
     1307    return wp_kses( $data , 'post' );
    13401308}
    13411309
     
    13481316 * @return string Filtered content without any HTML
    13491317 */
    1350 function wp_filter_nohtml_kses($data) {
    1351     return addslashes ( wp_kses(stripslashes( $data ), array()) );
     1318function wp_filter_nohtml_kses( $data ) {
     1319    return addslashes ( wp_kses( stripslashes( $data ), 'strip' ) );
    13521320}
    13531321
     
    14851453    return $css;
    14861454}
     1455
     1456/**
     1457 * Helper function to add global attributes to a tag in the allowed html list.
     1458 *
     1459 * @since 3.5.0
     1460 * @access private
     1461 *
     1462 * @param array $value An array of attributes.
     1463 * @return array The array of attributes with global attributes added.
     1464 */
     1465function _wp_add_global_attributes( $value ) {
     1466    $global_attributes = array(
     1467        'class' => true,
     1468        'id' => true,
     1469        'style' => true,
     1470        'title' => true,
     1471    );
     1472
     1473    if ( true === $value )
     1474        $value = array();
     1475
     1476    if ( is_array( $value ) )
     1477        return array_merge( $value, $global_attributes );
     1478
     1479    return $value;
     1480}
Note: See TracChangeset for help on using the changeset viewer.