WordPress.org

Make WordPress Core

Changeset 28711


Ignore:
Timestamp:
06/10/14 00:29:35 (3 years ago)
Author:
wonderboymusic
Message:

LIKE escape sanity:

  • Deprecate like_escape()
  • Add a method to $wpdb, ->esc_like(), and add unit tests

$wpdb::esc_like() is not used yet. As such, many unit tests will throw Unexpected deprecated notice for like_escape. Subsequent commits will alleviate this.

Props miqrogroove.
See #10041.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/deprecated.php

    r28710 r28711  
    34603460 
    34613461/** 
     3462 * Formerly used to escape strings before searching the DB. It was poorly documented and never worked as described. 
     3463 * 
     3464 * @since 2.5.0 
     3465 * @deprecated 4.0.0 
     3466 * @deprecated Use wpdb::esc_like() 
     3467 * 
     3468 * @param string $text The text to be escaped. 
     3469 * @return string text, safe for inclusion in LIKE query. 
     3470 */ 
     3471function like_escape($text) { 
     3472    _deprecated_function( __FUNCTION__, '4.0', 'wpdb::esc_like()' ); 
     3473    return str_replace( array( "%", "_" ), array( "\\%", "\\_" ), $text ); 
     3474} 
     3475 
     3476/** 
    34623477 * Determines if the URL can be accessed over SSL. 
    34633478 * 
  • trunk/src/wp-includes/formatting.php

    r28708 r28711  
    31013101 
    31023102/** 
    3103  * Escapes text for SQL LIKE special characters % and _. 
    3104  * 
    3105  * @since 2.5.0 
    3106  * 
    3107  * @param string $text The text to be escaped. 
    3108  * @return string text, safe for inclusion in LIKE query. 
    3109  */ 
    3110 function like_escape($text) { 
    3111     return str_replace(array("%", "_"), array("\\%", "\\_"), $text); 
    3112 } 
    3113  
    3114 /** 
    31153103 * Convert full URL paths to absolute paths. 
    31163104 * 
  • trunk/src/wp-includes/wp-db.php

    r28657 r28711  
    11701170 
    11711171    /** 
     1172     * First half of escaping for LIKE special characters % and _ before preparing for MySQL. 
     1173     * 
     1174     * Use this only before wpdb::prepare() or esc_sql().  Reversing the order is very bad for security. 
     1175     * 
     1176     * Example Prepared Statement: 
     1177     *  $wild = '%'; 
     1178     *  $find = 'only 43% of planets'; 
     1179     *  $like = $wild . $wpdb->esc_like( $find ) . $wild; 
     1180     *  $sql  = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like ); 
     1181     * 
     1182     * Example Escape Chain: 
     1183     *  $sql  = esc_sql( $wpdb->esc_like( $input ) ); 
     1184     * 
     1185     * @since 4.0.0 
     1186     * 
     1187     * @param string $text The raw text to be escaped. The input typed by the user should have no extra or deleted slashes. 
     1188     * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call prepare or real_escape next. 
     1189     */ 
     1190    function esc_like( $text ) { 
     1191        return addcslashes( $text, '_%\\' ); 
     1192    } 
     1193 
     1194    /** 
    11721195     * Print SQL/DB error. 
    11731196     * 
  • trunk/tests/phpunit/tests/db.php

    r28635 r28711  
    110110 
    111111    /** 
     112     * @ticket 10041 
     113     */ 
     114    function test_esc_like() { 
     115        global $wpdb; 
     116 
     117        $inputs = array( 
     118            'howdy%', //Single Percent 
     119            'howdy_', //Single Underscore 
     120            'howdy\\', //Single slash 
     121            'howdy\\howdy%howdy_', //The works 
     122            'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', //Plain text 
     123        ); 
     124        $expected = array( 
     125            'howdy\\%', 
     126            'howdy\\_', 
     127            'howdy\\\\', 
     128            'howdy\\\\howdy\\%howdy\\_', 
     129            'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', 
     130        ); 
     131 
     132        foreach ($inputs as $key => $input) { 
     133            $this->assertEquals($expected[$key], $wpdb->esc_like($input)); 
     134        } 
     135    } 
     136 
     137    /** 
     138     * Test LIKE Queries 
     139     * 
     140     * Make sure $wpdb is fully compatible with esc_like() by testing the identity of various strings. 
     141     * When escaped properly, a string literal is always LIKE itself (1) 
     142     * and never LIKE any other string literal (0) no matter how crazy the SQL looks. 
     143     * 
     144     * @ticket 10041 
     145     * @dataProvider data_like_query 
     146     * @param $data string The haystack, raw. 
     147     * @param $like string The like phrase, raw. 
     148         * @param $result string The expected comparison result; '1' = true, '0' = false 
     149     */ 
     150    function test_like_query( $data, $like, $result ) { 
     151        global $wpdb; 
     152        return $this->assertEquals( $result, $wpdb->get_var( $wpdb->prepare( "SELECT %s LIKE %s", $data, $wpdb->esc_like( $like ) ) ) ); 
     153    } 
     154 
     155    function data_like_query() { 
     156        return array( 
     157            array( 
     158                'aaa', 
     159                'aaa', 
     160                '1', 
     161            ), 
     162            array( 
     163                'a\\aa', // SELECT 'a\\aa'  # This represents a\aa in both languages. 
     164                'a\\aa', // LIKE 'a\\\\aa' 
     165                '1', 
     166            ), 
     167            array( 
     168                'a%aa', 
     169                'a%aa', 
     170                '1', 
     171            ), 
     172            array( 
     173                'aaaa', 
     174                'a%aa', 
     175                '0', 
     176            ), 
     177            array( 
     178                'a\\%aa', // SELECT 'a\\%aa' 
     179                'a\\%aa', // LIKE 'a\\\\\\%aa' # The PHP literal would be "LIKE 'a\\\\\\\\\\\\%aa'".  This is why we need reliable escape functions! 
     180                '1', 
     181            ), 
     182            array( 
     183                'a%aa', 
     184                'a\\%aa', 
     185                '0', 
     186            ), 
     187            array( 
     188                'a\\%aa', 
     189                'a%aa', 
     190                '0', 
     191            ), 
     192            array( 
     193                'a_aa', 
     194                'a_aa', 
     195                '1', 
     196            ), 
     197            array( 
     198                'aaaa', 
     199                'a_aa', 
     200                '0', 
     201            ), 
     202            array( 
     203                'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', 
     204                'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', 
     205                '1', 
     206            ), 
     207        ); 
     208    } 
     209 
     210    /** 
    112211     * @ticket 18510 
    113212     */ 
  • trunk/tests/phpunit/tests/formatting/LikeEscape.php

    r25002 r28711  
    77    /** 
    88     * @ticket 10041 
     9     * @expectedDeprecated like_escape 
    910     */ 
    1011    function test_like_escape() { 
Note: See TracChangeset for help on using the changeset viewer.