Make WordPress Core

Changeset 28711


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