WordPress.org

Make WordPress Core

Changeset 10298


Ignore:
Timestamp:
01/04/09 23:37:47 (6 years ago)
Author:
azaozz
Message:

Latest version of the patch for refactor filters to avoid potential XSS attacks, props sambauers and DD32, see #8767

Location:
trunk/wp-includes
Files:
2 edited

Legend:

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

    r10297 r10298  
    9999if ( !function_exists( 'htmlspecialchars_decode' ) ) { 
    100100    // Added in PHP 5.1.0 
    101     // from php.net (modified by Sam Bauers to deal with some quirks in HTML_SPECIALCHARS constant) 
    102     function htmlspecialchars_decode( $str, $quote_style = ENT_COMPAT ) { 
    103         $table = array_flip( get_html_translation_table( HTML_SPECIALCHARS, $quote_style ) ); 
    104         $table = array_merge( array( ''' => "'" ), $table, array( '&' => "&", '&' => "&" ) ); 
    105         return strtr( $str, $table ); 
     101    // Error checks from PEAR::PHP_Compat 
     102    function htmlspecialchars_decode( $str, $quote_style = ENT_COMPAT ) 
     103    { 
     104        if ( !is_scalar( $string ) ) { 
     105            trigger_error( 'htmlspecialchars_decode() expects parameter 1 to be string, ' . gettype( $string ) . ' given', E_USER_WARNING ); 
     106            return; 
     107        } 
     108 
     109        if ( !is_int( $quote_style ) && $quote_style !== null ) { 
     110            trigger_error( 'htmlspecialchars_decode() expects parameter 2 to be integer, ' . gettype( $quote_style ) . ' given', E_USER_WARNING ); 
     111            return; 
     112        } 
     113 
     114        return wp_specialchars_decode( $str, $quote_style ); 
    106115    } 
    107116} 
  • trunk/wp-includes/formatting.php

    r10297 r10298  
    187187 * Converts a number of special characters into their HTML entities. 
    188188 * 
    189  * Specifically changes: & to &#038;, < to &lt; and > to &gt;. 
     189 * Specifically deals with: &, <, >, ", and '. 
    190190 * 
    191191 * $quote_style can be set to ENT_COMPAT to encode " to 
     
    200200 * @return string The encoded text with HTML entities. 
    201201 */ 
    202 function wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { 
     202function wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) 
     203{ 
     204    $string = (string) $string; 
     205 
    203206    if ( 0 === strlen( $string ) ) { 
    204207        return ''; 
     
    213216    } 
    214217 
    215     // Backwards compatibility 
    216218    switch ( $quote_style ) { 
    217         // Handle expected values first for speed 
    218         case ENT_NOQUOTES: 
    219             $_quote_style = ENT_NOQUOTES; 
     219        case ENT_QUOTES: 
     220        default: 
     221            $quote_style = ENT_QUOTES; 
     222            $_quote_style = ENT_QUOTES; 
    220223            break; 
    221224        case ENT_COMPAT: 
     225        case 'double': 
     226            $quote_style = ENT_COMPAT; 
    222227            $_quote_style = ENT_COMPAT; 
    223228            break; 
    224         case ENT_QUOTES: 
    225             $_quote_style = ENT_QUOTES; 
     229        case 'single': 
     230            $quote_style = ENT_NOQUOTES; 
     231            $_quote_style = 'single'; 
    226232            break; 
    227         // Old values 
     233        case ENT_NOQUOTES: 
    228234        case false: 
    229235        case 0: 
    230236        case '': 
    231237        case null: 
    232         case 'single': 
     238            $quote_style = ENT_NOQUOTES; 
    233239            $_quote_style = ENT_NOQUOTES; 
    234240            break; 
    235         case 'double': 
    236             $_quote_style = ENT_COMPAT; 
    237             break; 
    238         default: 
    239             $_quote_style = ENT_QUOTES; 
    240             break; 
    241     } 
    242  
    243     if ( version_compare( PHP_VERSION, '5.2.3', '>=' ) ) { 
    244         $string = htmlspecialchars( $string, $_quote_style, $charset, $double_encode ); 
    245     } else { 
    246         // Handle double encoding for PHP versions that don't support it in htmlspecialchars() 
    247         if ( !$double_encode ) { 
    248             $string = htmlspecialchars_decode( $string, $_quote_style ); 
    249             // Backwards compatibility 
    250             if ( 'single' === $quote_style ) { 
    251                 $string = str_replace( array( '&#039;', '&#39;' ), "'", $string ); 
    252             } 
    253         } 
    254         $string = htmlspecialchars( $string, $_quote_style, $charset ); 
     241    } 
     242 
     243    // Handle double encoding ourselves 
     244    if ( !$double_encode ) { 
     245        $string = wp_specialchars_decode( $string, $_quote_style ); 
     246        $string = preg_replace( '/&(#?x?[0-9]+|[a-z]+);/i', '|wp_entity|$1|/wp_entity|', $string ); 
     247    } 
     248 
     249    $string = htmlspecialchars( $string, $quote_style, $charset ); 
     250 
     251    // Handle double encoding ourselves 
     252    if ( !$double_encode ) { 
     253        $string = str_replace( array( '|wp_entity|', '|/wp_entity|' ), array( '&', ';' ), $string ); 
    255254    } 
    256255 
    257256    // Backwards compatibility 
    258     if ( 'single' === $quote_style ) { 
     257    if ( 'single' === $_quote_style ) { 
    259258        $string = str_replace( "'", '&#039;', $string ); 
    260259    } 
     
    264263 
    265264/** 
    266  * Converts all special characters into their HTML entities. 
    267  * 
    268  * $quote_style can be set to ENT_COMPAT to encode " to 
    269  * &quot;, or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded. 
     265 * Converts a number of HTML entities into their special characters. 
     266 * 
     267 * Specifically deals with: &, <, >, ", and '. 
     268 * 
     269 * $quote_style can be set to ENT_COMPAT to decode " entities, 
     270 * or ENT_QUOTES to do both " and '. Default is ENT_NOQUOTES where no quotes are decoded. 
    270271 * 
    271272 * @since 2.8 
    272273 * 
    273  * @param string $string The text which is to be encoded. 
    274  * @param mixed $quote_style Optional. Converts double quotes if set to ENT_COMPAT, both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES. Default is ENT_NOQUOTES. 
    275  * @param string $charset Optional. The character encoding of the string. Default is false. 
    276  * @param boolean $double_encode Optional. Whether or not to encode existing html entities. Default is false. 
    277  * @return string The encoded text with HTML entities. 
    278  */ 
    279 function wp_entities( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) { 
     274 * @param string $string The text which is to be decoded. 
     275 * @param mixed $quote_style Optional. Converts double quotes if set to ENT_COMPAT, both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES. Also compatible with old wp_specialchars() values; converting single quotes if set to 'single', double if set to 'double' or both if otherwise set. Default is ENT_NOQUOTES. 
     276 * @return string The decoded text without HTML entities. 
     277 */ 
     278function wp_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) 
     279{ 
     280    $string = (string) $string; 
     281 
    280282    if ( 0 === strlen( $string ) ) { 
    281283        return ''; 
    282284    } 
    283285 
    284     if ( !$charset ) { 
    285         $charset = get_option( 'blog_charset' ); 
    286     } 
    287     if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) { 
    288         $charset = 'UTF-8'; 
    289     } 
    290  
    291     if ( version_compare( PHP_VERSION, '5.2.3', '>=' ) ) { 
    292         $string = htmlentities( $string, $quote_style, $charset, $double_encode ); 
    293     } else { 
    294         // Handle double encoding for PHP versions that don't support it in htmlentities() 
    295         if ( !$double_encode ) { 
    296             // Multi-byte charsets are not supported below PHP 5.0.0 
    297             // 'cp866', 'cp1251', 'KOI8-R' charsets are not supported below PHP 4.3.2 
    298             $string = html_entity_decode( $string, $quote_style, $charset ); 
    299         } 
    300         // 'cp866', 'cp1251', 'KOI8-R' charsets are not supported below PHP 4.3.2 
    301         $string = htmlentities( $string, $quote_style, $charset ); 
    302     } 
    303  
    304     return $string; 
     286    // More complete than get_html_translation_table( HTML_SPECIALCHARS ) 
     287    $single = array( '&#039;'  => '\'', '&#x27;' => '\'' ); 
     288    $single_preg = array( '/&#0*39;/'  => '&#039;', '/&#x0*27;/i' => '&#x27;' ); 
     289    $double = array( '&quot;' => '"', '&#034;'  => '"', '&#x22;' => '"' ); 
     290    $double_preg = array( '/&#0*34;/'  => '&#034;', '/&#x0*22;/i' => '&#x22;' ); 
     291    $others = array( '&lt;'   => '<', '&#060;'  => '<', '&gt;'   => '>', '&#062;'  => '>', '&amp;'  => '&', '&#038;'  => '&', '&#x26;' => '&' ); 
     292    $others_preg = array( '/&#0*60;/'  => '&#060;', '/&#0*62;/'  => '&#062;', '/&#0*38;/'  => '&#038;', '/&#x0*26;/i' => '&#x26;' ); 
     293 
     294    switch ( $quote_style ) { 
     295        case ENT_QUOTES: 
     296        default: 
     297            $translation = array_merge( $single, $double, $others ); 
     298            $translation_preg = array_merge( $single_preg, $double_preg, $others_preg ); 
     299            break; 
     300        case ENT_COMPAT: 
     301        case 'double': 
     302            $translation = array_merge( $double, $others ); 
     303            $translation_preg = array_merge( $double_preg, $others_preg ); 
     304            break; 
     305        case 'single': 
     306            $translation = array_merge( $single, $others ); 
     307            $translation_preg = array_merge( $single_preg, $others_preg ); 
     308            break; 
     309        case ENT_NOQUOTES: 
     310        case false: 
     311        case 0: 
     312        case '': 
     313        case null: 
     314            $translation = $others; 
     315            $translation_preg = $others_preg; 
     316            break; 
     317    } 
     318 
     319    // Remove zero padding on numeric entities 
     320    $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string ); 
     321 
     322    // Replace characters according to translation table 
     323    return strtr( $string, $translation ); 
    305324} 
    306325 
     
    314333 * @return string The checked text. 
    315334 */ 
    316 function wp_check_invalid_utf8( $string, $strip = false ) { 
     335function wp_check_invalid_utf8( $string, $strip = false ) 
     336{ 
     337    $string = (string) $string; 
     338 
    317339    if ( 0 === strlen( $string ) ) { 
    318340        return ''; 
     
    18611883 */ 
    18621884function js_escape($text) { 
    1863     $safe_text = wp_specialchars($text, 'double'); 
    1864     $safe_text = preg_replace('/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes($safe_text)); 
    1865     $safe_text = preg_replace("/\r?\n/", "\\n", addslashes($safe_text)); 
    1866     return apply_filters('js_escape', $safe_text, $text); 
     1885    $safe_text = wp_check_invalid_utf8( $text ); 
     1886    $safe_text = wp_specialchars( $safe_text, ENT_COMPAT ); 
     1887    $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) ); 
     1888    $safe_text = preg_replace( "/\r?\n/", "\\n", addslashes( $safe_text ) ); 
     1889    return apply_filters( 'js_escape', $safe_text, $text ); 
    18671890} 
    18681891 
     
    18771900function attribute_escape( $text ) { 
    18781901    $safe_text = wp_check_invalid_utf8( $text ); 
    1879     $safe_text = wp_entities( $safe_text, ENT_QUOTES ); 
     1902    $safe_text = wp_specialchars( $safe_text, ENT_QUOTES ); 
    18801903    return apply_filters( 'attribute_escape', $safe_text, $text ); 
    18811904} 
Note: See TracChangeset for help on using the changeset viewer.