WordPress.org

Make WordPress Core

Changeset 28711


Ignore:
Timestamp:
06/10/2014 12:29:35 AM (4 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.