Make WordPress Core

Ticket #10041: 10041.7.diff

File 10041.7.diff, 29.7 KB (added by wonderboymusic, 10 years ago)
  • src/wp-admin/includes/class-wp-ms-sites-list-table.php

     
    3838                        $s = trim($s, '*');
    3939                }
    4040
    41                 $like_s = esc_sql( like_escape( $s ) );
    42 
    4341                // If the network is large and a search is not being performed, show only the latest blogs with no paging in order
    4442                // to avoid expensive count queries.
    4543                if ( !$s && wp_is_large_network() ) {
     
    5856                                        preg_match( '/^[0-9]{1,3}\.[0-9]{1,3}\.?$/', $s ) ||
    5957                                        preg_match( '/^[0-9]{1,3}\.$/', $s ) ) {
    6058                        // IPv4 address
    61                         $reg_blog_ids = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->registration_log} WHERE {$wpdb->registration_log}.IP LIKE ( '{$like_s}$wild' )" );
     59                        $sql = $wpdb->prepare( "SELECT blog_id FROM {$wpdb->registration_log} WHERE {$wpdb->registration_log}.IP LIKE %s", $wpdb->esc_like( $s ) . $wild );
     60                        $reg_blog_ids = $wpdb->get_col( $sql );
    6261
    6362                        if ( !$reg_blog_ids )
    6463                                $reg_blog_ids = array( 0 );
     
    6968                                AND {$wpdb->blogs}.blog_id IN (" . implode( ', ', $reg_blog_ids ) . ")";
    7069                } else {
    7170                        if ( is_numeric($s) && empty( $wild ) ) {
    72                                 $query .= " AND ( {$wpdb->blogs}.blog_id = '{$like_s}' )";
     71                                $query .= $wpdb->prepare( " AND ( {$wpdb->blogs}.blog_id = %s )", $s );
    7372                        } elseif ( is_subdomain_install() ) {
    74                                 $blog_s = str_replace( '.' . $current_site->domain, '', $like_s );
    75                                 $blog_s .= $wild . '.' . $current_site->domain;
    76                                 $query .= " AND ( {$wpdb->blogs}.domain LIKE '$blog_s' ) ";
     73                                $blog_s = str_replace( '.' . $current_site->domain, '', $s );
     74                                $blog_s = $wpdb->esc_like( $blog_s ) . $wild . $wpdb->esc_like( '.' . $current_site->domain );
     75                                $query .= $wpdb->prepare( " AND ( {$wpdb->blogs}.domain LIKE %s ) ", $blog_s );
    7776                        } else {
    78                                 if ( $like_s != trim('/', $current_site->path) )
    79                                         $blog_s = $current_site->path . $like_s . $wild . '/';
    80                                 else
    81                                         $blog_s = $like_s;
    82                                 $query .= " AND  ( {$wpdb->blogs}.path LIKE '$blog_s' )";
     77                                if ( $s != trim('/', $current_site->path) ) {
     78                                        $blog_s = $wpdb->esc_like( $current_site->path . $s ) . $wild . $wpdb->esc_like( '/' );
     79                                } else {
     80                                        $blog_s = $wpdb->esc_like( $s );
     81                                }
     82                                $query .= $wpdb->prepare( " AND  ( {$wpdb->blogs}.path LIKE %s )", $blog_s );
    8383                        }
    8484                }
    8585
  • src/wp-admin/includes/schema.php

     
    553553        // The multi-table delete syntax is used to delete the transient record from table a,
    554554        // and the corresponding transient_timeout record from table b.
    555555        $time = time();
    556         $wpdb->query("DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE
    557                 a.option_name LIKE '\_transient\_%' AND
    558                 a.option_name NOT LIKE '\_transient\_timeout\_%' AND
    559                 b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
    560                 AND b.option_value < $time");
     556        $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
     557                WHERE a.option_name LIKE %s
     558                AND a.option_name NOT LIKE %s
     559                AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
     560                AND b.option_value < %d";
     561        $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', $time ) );
    561562
    562563        if ( is_main_site() && is_main_network() ) {
    563                 $wpdb->query("DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE
    564                         a.option_name LIKE '\_site\_transient\_%' AND
    565                         a.option_name NOT LIKE '\_site\_transient\_timeout\_%' AND
    566                         b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
    567                         AND b.option_value < $time");
    568     }
     564                $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b
     565                        WHERE a.option_name LIKE %s
     566                        AND a.option_name NOT LIKE %s
     567                        AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
     568                        AND b.option_value < %d";
     569                $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like( '_site_transient_timeout_' ) . '%', $time ) );
     570        }
    569571}
    570572
    571573/**
  • src/wp-admin/includes/template.php

     
    632632         *
    633633         * @param int $limit Number of custom fields to retrieve. Default 30.
    634634         */
    635         $limit = (int) apply_filters( 'postmeta_form_limit', 30 );
    636         $keys = $wpdb->get_col( "
    637                 SELECT meta_key
     635        $limit = apply_filters( 'postmeta_form_limit', 30 );
     636        $sql = "SELECT meta_key
    638637                FROM $wpdb->postmeta
    639638                GROUP BY meta_key
    640                 HAVING meta_key NOT LIKE '\_%'
     639                HAVING meta_key NOT LIKE %s
    641640                ORDER BY meta_key
    642                 LIMIT $limit" );
     641                LIMIT %d";
     642        $keys = $wpdb->get_col( $wpdb->prepare( $sql, $wpdb->esc_like( '_' ) . '%', $limit ) );
    643643        if ( $keys ) {
    644644                natcasesort( $keys );
    645645                $meta_key_input_id = 'metakeyselect';
  • src/wp-admin/includes/upgrade.php

     
    465465                }
    466466        }
    467467
    468         $wpdb->query("UPDATE $wpdb->options SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
    469         WHERE option_name LIKE 'links_rating_image%'
    470         AND option_value LIKE 'wp-links/links-images/%'");
     468        $sql = "UPDATE $wpdb->options
     469                SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
     470                WHERE option_name LIKE %s
     471                AND option_value LIKE %s";
     472        $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) );
    471473
    472474        $done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
    473475        if ($done_ids) :
     
    11001102
    11011103        // 3.0 screen options key name changes.
    11021104        if ( is_main_site() && !defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) {
    1103                 $prefix = like_escape($wpdb->base_prefix);
    1104                 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key LIKE '{$prefix}%meta-box-hidden%' OR meta_key LIKE '{$prefix}%closedpostboxes%' OR meta_key LIKE '{$prefix}%manage-%-columns-hidden%' OR meta_key LIKE '{$prefix}%meta-box-order%' OR meta_key LIKE '{$prefix}%metaboxorder%' OR meta_key LIKE '{$prefix}%screen_layout%'
    1105                                          OR meta_key = 'manageedittagscolumnshidden' OR meta_key='managecategoriescolumnshidden' OR meta_key = 'manageedit-tagscolumnshidden' OR meta_key = 'manageeditcolumnshidden' OR meta_key = 'categories_per_page' OR meta_key = 'edit_tags_per_page'" );
     1105                $sql = "DELETE FROM $wpdb->usermeta
     1106                        WHERE meta_key LIKE %s
     1107                        OR meta_key LIKE %s
     1108                        OR meta_key LIKE %s
     1109                        OR meta_key LIKE %s
     1110                        OR meta_key LIKE %s
     1111                        OR meta_key LIKE %s
     1112                        OR meta_key = 'manageedittagscolumnshidden'
     1113                        OR meta_key = 'managecategoriescolumnshidden'
     1114                        OR meta_key = 'manageedit-tagscolumnshidden'
     1115                        OR meta_key = 'manageeditcolumnshidden'
     1116                        OR meta_key = 'categories_per_page'
     1117                        OR meta_key = 'edit_tags_per_page'";
     1118                $prefix = $wpdb->esc_like( $wpdb->base_prefix );
     1119                $wpdb->query( $wpdb->prepare( $sql,
     1120                        $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%',
     1121                        $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%',
     1122                        $prefix . '%' . $wpdb->esc_like( 'manage-'         ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%',
     1123                        $prefix . '%' . $wpdb->esc_like( 'meta-box-order'  ) . '%',
     1124                        $prefix . '%' . $wpdb->esc_like( 'metaboxorder'    ) . '%',
     1125                        $prefix . '%' . $wpdb->esc_like( 'screen_layout'   ) . '%'
     1126                ) );
    11061127        }
    11071128
    11081129}
     
    12841305                // The multi-table delete syntax is used to delete the transient record from table a,
    12851306                // and the corresponding transient_timeout record from table b.
    12861307                $time = time();
    1287                 $wpdb->query("DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b WHERE
    1288                         a.meta_key LIKE '\_site\_transient\_%' AND
    1289                         a.meta_key NOT LIKE '\_site\_transient\_timeout\_%' AND
    1290                         b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
    1291                         AND b.meta_value < $time");
     1308                $sql = "DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b
     1309                        WHERE a.meta_key LIKE %s
     1310                        AND a.meta_key NOT LIKE %s
     1311                        AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
     1312                        AND b.meta_value < %d";
     1313                $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like ( '_site_transient_timeout_' ) . '%', $time ) );
    12921314        }
    12931315
    12941316        // 2.8
     
    13821404 */
    13831405function maybe_create_table($table_name, $create_ddl) {
    13841406        global $wpdb;
    1385         if ( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name )
     1407       
     1408        $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
     1409
     1410        if ( $wpdb->get_var( $query ) == $table_name ) {
    13861411                return true;
     1412        }
    13871413        //didn't find it try to create it.
    13881414        $wpdb->query($create_ddl);
    13891415        // we cannot directly tell that whether this succeeded!
    1390         if ( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name )
     1416        if ( $wpdb->get_var( $query ) == $table_name ) {
    13911417                return true;
     1418        }
    13921419        return false;
    13931420}
    13941421
  • src/wp-admin/install.php

     
    7474 */
    7575function display_setup_form( $error = null ) {
    7676        global $wpdb;
    77         $user_table = ( $wpdb->get_var("SHOW TABLES LIKE '$wpdb->users'") != null );
    7877
     78        $sql = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $wpdb->users ) );
     79        $user_table = ( $wpdb->get_var( $sql ) != null );
     80
    7981        // Ensure that Blogs appear in search engines by default
    8082        $blog_public = 1;
    8183        if ( ! empty( $_POST ) )
  • src/wp-admin/maint/repair.php

     
    3636        $tables = $wpdb->tables();
    3737
    3838        // Sitecategories may not exist if global terms are disabled.
    39         if ( is_multisite() && ! $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->sitecategories'" ) )
     39        $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $wpdb->sitecategories ) );
     40        if ( is_multisite() && ! $wpdb->get_var( $query ) ) {
    4041                unset( $tables['sitecategories'] );
     42        }
    4143
    4244        /**
    4345         * Filter additional database tables to repair.
  • src/wp-admin/network/site-settings.php

     
    113113        <table class="form-table">
    114114                <?php
    115115                $blog_prefix = $wpdb->get_blog_prefix( $id );
    116                 $options = $wpdb->get_results( "SELECT * FROM {$blog_prefix}options WHERE option_name NOT LIKE '\_%' AND option_name NOT LIKE '%user_roles'" );
     116                $sql = "SELECT * FROM {$blog_prefix}options
     117                        WHERE option_name NOT LIKE %s
     118                        AND option_name NOT LIKE %s";
     119                $query = $wpdb->prepare( $sql,
     120                        $wpdb->esc_like( '_' ) . '%',
     121                        '%' . $wpdb->esc_like( 'user_roles' )
     122                );
     123                $options = $wpdb->get_results( $query );
    117124                foreach ( $options as $option ) {
    118125                        if ( $option->option_name == 'default_role' )
    119126                                $editblog_default_role = $option->option_value;
  • src/wp-admin/network.php

     
    3939 */
    4040function network_domain_check() {
    4141        global $wpdb;
    42         if ( $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->site'" ) )
     42
     43        $sql = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $wpdb->site ) );
     44        if ( $wpdb->get_var( $sql ) ) {
    4345                return $wpdb->get_var( "SELECT domain FROM $wpdb->site ORDER BY id ASC LIMIT 1" );
     46        }
    4447        return false;
    4548}
    4649
  • src/wp-includes/bookmark.php

     
    208208
    209209        $search = '';
    210210        if ( ! empty( $r['search'] ) ) {
    211                 $search = esc_sql( like_escape( $r['search'] ) );
    212                 $search = " AND ( (link_url LIKE '%$search%') OR (link_name LIKE '%$search%') OR (link_description LIKE '%$search%') ) ";
     211                $like = '%' . $wpdb->esc_like( $r['search'] ) . '%';
     212                $search = $wpdb->prepare(" AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ", $like, $like, $like );
    213213        }
    214214
    215215        $category_query = '';
  • src/wp-includes/canonical.php

     
    504504        global $wpdb, $wp_rewrite;
    505505
    506506        if ( get_query_var('name') ) {
    507                 $where = $wpdb->prepare("post_name LIKE %s", like_escape( get_query_var('name') ) . '%');
     507                $where = $wpdb->prepare("post_name LIKE %s", $wpdb->esc_like( get_query_var('name') ) . '%');
    508508
    509509                // if any of post_type, year, monthnum, or day are set, use them to refine the query
    510510                if ( get_query_var('post_type') )
  • src/wp-includes/class-wp-xmlrpc-server.php

     
    57645764                        } elseif ( is_string($urltest['fragment']) ) {
    57655765                                // ...or a string #title, a little more complicated
    57665766                                $title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']);
    5767                                 $sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", like_escape( $title ) );
     5767                                $sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title );
    57685768                                if (! ($post_ID = $wpdb->get_var($sql)) ) {
    57695769                                        // returning unknown error '0' is better than die()ing
    57705770                                        return $this->pingback_error( 0, '' );
  • src/wp-includes/comment.php

     
    481481         * @return string
    482482         */
    483483        protected function get_search_sql( $string, $cols ) {
    484                 $string = esc_sql( like_escape( $string ) );
     484                global $wpdb;
    485485
    486486                $searches = array();
    487487                foreach ( $cols as $col )
    488                         $searches[] = "$col LIKE '%$string%'";
     488                        $searches[] = $wpdb->prepare( "$col LIKE %s", $wpdb->esc_like( $string ) );
    489489
    490490                return ' AND (' . implode(' OR ', $searches) . ')';
    491491        }
  • src/wp-includes/deprecated.php

     
    34573457        _deprecated_function( __FUNCTION__, '3.9' );
    34583458        return $content;
    34593459}
     3460
     3461/**
     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}
  • src/wp-includes/formatting.php

     
    31003100}
    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 *
    31173105 * Removes the http or https protocols and the domain. Keeps the path '/' at the
  • src/wp-includes/functions.php

     
    479479
    480480        foreach ( $pung as $link_test ) {
    481481                if ( ! in_array( $link_test, $post_links_temp ) ) { // link no longer in post
    482                         $mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ) . '%') );
     482                        $mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post_ID, $wpdb->esc_like( $link_test ) . '%') );
    483483                        foreach ( $mids as $mid )
    484484                                delete_metadata_by_mid( 'post', $mid );
    485485                }
     
    498498        }
    499499
    500500        foreach ( (array) $post_links as $url ) {
    501                 if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $url ) . '%' ) ) ) {
     501                if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post_ID, $wpdb->esc_like( $url ) . '%' ) ) ) {
    502502
    503503                        if ( $headers = wp_get_http_headers( $url) ) {
    504504                                $len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
  • src/wp-includes/meta.php

     
    10471047                        } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) {
    10481048                                $meta_value = array_slice( $meta_value, 0, 2 );
    10491049                                $meta_compare_string = '%s AND %s';
    1050                         } elseif ( 'LIKE' == substr( $meta_compare, -4 ) ) {
    1051                                 $meta_value = '%' . like_escape( $meta_value ) . '%';
     1050                        } elseif ( 'LIKE' == $meta_compare || 'NOT LIKE' == $meta_compare ) ) {
     1051                                $meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%';
    10521052                                $meta_compare_string = '%s';
    10531053                        } else {
    10541054                                $meta_compare_string = '%s';
  • src/wp-includes/ms-load.php

     
    397397
    398398        $title = __( 'Error establishing a database connection' );
    399399        $msg  = '<h1>' . $title . '</h1>';
    400         if ( ! is_admin() )
     400        if ( ! is_admin() ) {
    401401                die( $msg );
     402        }
    402403        $msg .= '<p>' . __( 'If your site does not display, please contact the owner of this network.' ) . '';
    403404        $msg .= ' ' . __( 'If you are the owner of this network please check that MySQL is running properly and all tables are error free.' ) . '</p>';
    404         if ( ! $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->site'" ) )
     405        $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $wpdb->site ) );
     406        if ( ! $wpdb->get_var( $query ) ) {
    405407                $msg .= '<p>' . sprintf( __( '<strong>Database tables are missing.</strong> This means that MySQL is not running, WordPress was not installed properly, or someone deleted <code>%s</code>. You really should look at your database now.' ), $wpdb->site ) . '</p>';
    406         else
     408        } else {
    407409                $msg .= '<p>' . sprintf( __( '<strong>Could not find site <code>%1$s</code>.</strong> Searched for table <code>%2$s</code> in database <code>%3$s</code>. Is that right?' ), rtrim( $domain . $path, '/' ), $wpdb->blogs, DB_NAME ) . '</p>';
     410        }
    408411        $msg .= '<p><strong>' . __( 'What do I do now?' ) . '</strong> ';
    409412        $msg .= __( 'Read the <a target="_blank" href="http://codex.wordpress.org/Debugging_a_WordPress_Network">bug report</a> page. Some of the guidelines there may help you figure out what went wrong.' );
    410413        $msg .= ' ' . __( 'If you&#8217;re still stuck with this message, then check that your database contains the following tables:' ) . '</p><ul>';
  • src/wp-includes/post.php

     
    47964796
    47974797        if ( ! empty($meta['thumb']) ) {
    47984798                // Don't delete the thumb if another attachment uses it
    4799                 if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $meta['thumb'] . '%', $post_id)) ) {
     4799                if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id)) ) {
    48004800                        $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
    48014801                        /** This filter is documented in wp-admin/custom-header.php */
    48024802                        $thumbfile = apply_filters( 'wp_delete_file', $thumbfile );
  • src/wp-includes/query.php

     
    19831983                $searchand = '';
    19841984                $q['search_orderby_title'] = array();
    19851985                foreach ( $q['search_terms'] as $term ) {
    1986                         $term = like_escape( esc_sql( $term ) );
    1987                         if ( $n )
    1988                                 $q['search_orderby_title'][] = "$wpdb->posts.post_title LIKE '%$term%'";
     1986                        if ( $n ) {
     1987                                $like = '%' . $wpdb->esc_like( $term ) . '%';
     1988                                $q['search_orderby_title'][] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like );
     1989                        }
    19891990
    1990                         $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
     1991                        $like = $n . $wpdb->esc_like( $term ) . $n;
     1992                        $search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title LIKE %s) OR ($wpdb->posts.post_content LIKE %s))", $like, $like );
    19911993                        $searchand = ' AND ';
    19921994                }
    19931995
     
    20862088
    20872089                if ( $q['search_terms_count'] > 1 ) {
    20882090                        $num_terms = count( $q['search_orderby_title'] );
    2089                         $search_orderby_s = like_escape( esc_sql( $q['s'] ) );
     2091                        $like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
    20902092
    20912093                        $search_orderby = '(CASE ';
    20922094                        // sentence match in 'post_title'
    2093                         $search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";
     2095                        $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like );
    20942096
    20952097                        // sanity limit, sort as sentence when more than 6 terms
    20962098                        // (few searches are longer than 6 terms and most titles are not)
     
    21032105                        }
    21042106
    21052107                        // sentence match in 'post_content'
    2106                         $search_orderby .= "WHEN $wpdb->posts.post_content LIKE '%{$search_orderby_s}%' THEN 4 ";
     2108                        $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 4 ", $like );
    21072109                        $search_orderby .= 'ELSE 5 END)';
    21082110                } else {
    21092111                        // single word or sentence search
  • src/wp-includes/taxonomy.php

     
    14801480        }
    14811481
    14821482        if ( ! empty( $args['name__like'] ) ) {
    1483                 $name__like = like_escape( $args['name__like'] );
    1484                 $where .= $wpdb->prepare( " AND t.name LIKE %s", '%' . $name__like . '%' );
     1483                $where .= $wpdb->prepare( " AND t.name LIKE %s", '%' . $wpdb->esc_like( $args['name__like'] ) . '%' );
    14851484        }
    14861485
    14871486        if ( ! empty( $args['description__like'] ) ) {
    1488                 $description__like = like_escape( $args['description__like'] );
    1489                 $where .= $wpdb->prepare( " AND tt.description LIKE %s", '%' . $description__like . '%' );
     1487                $where .= $wpdb->prepare( " AND tt.description LIKE %s", '%' . $wpdb->esc_like( $args['description__like'] ) . '%' );
    14901488        }
    14911489
    14921490        if ( '' !== $parent ) {
     
    15171515        }
    15181516
    15191517        if ( ! empty( $args['search'] ) ) {
    1520                 $search = like_escape( $args['search'] );
    1521                 $where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', '%' . $search . '%', '%' . $search . '%' );
     1518                $like = '%' . $wpdb->esc_like( $args['search'] ) . '%';
     1519                $where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like );
    15221520        }
    15231521
    15241522        $selects = array();
  • src/wp-includes/user.php

     
    797797         * @return string
    798798         */
    799799        protected function get_search_sql( $string, $cols, $wild = false ) {
    800                 $string = esc_sql( $string );
     800                global $wpdb;
    801801
    802802                $searches = array();
    803803                $leading_wild = ( 'leading' == $wild || 'both' == $wild ) ? '%' : '';
     
    804804                $trailing_wild = ( 'trailing' == $wild || 'both' == $wild ) ? '%' : '';
    805805                foreach ( $cols as $col ) {
    806806                        if ( 'ID' == $col )
    807                                 $searches[] = "$col = '$string'";
     807                                $searches[] = $wpdb->prepare( "$col = %s", $string );
    808808                        else
    809                                 $searches[] = "$col LIKE '$leading_wild" . like_escape($string) . "$trailing_wild'";
     809                                $searches[] = $wpdb->prepare( "$col LIKE %s", $leading_wild . $wpdb->esc_like( $string ) . $trailing_wild );
    810810                }
    811811
    812812                return ' AND (' . implode(' OR ', $searches) . ')';
     
    11491149                // Build a CPU-intensive query that will return concise information.
    11501150                $select_count = array();
    11511151                foreach ( $avail_roles as $this_role => $name ) {
    1152                         $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%\"" . like_escape( $this_role ) . "\"%', false))";
     1152                        $select_count[] = $wpdb->prepare( "COUNT(NULLIF(`meta_value` LIKE %s, false))", '%' . $wpdb->esc_like( '"' . $this_role . '"' ) . '%');
    11531153                }
    11541154                $select_count = implode(', ', $select_count);
    11551155
  • src/wp-includes/wp-db.php

     
    11691169        }
    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         *
    11741197         * @since 0.71
  • tests/phpunit/tests/db.php

     
    337337                $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE ID = %d", $last ) );
    338338                $this->assertEquals( 'Walter Replace Sobchak', $row->display_name );
    339339        }
     340
     341        /**
     342         * @ticket 10041
     343         */
     344        function test_esc_like() {
     345                global $wpdb;
     346
     347                $inputs = array(
     348                        'howdy%', //Single Percent
     349                        'howdy_', //Single Underscore
     350                        'howdy\\', //Single slash
     351                        'howdy\\howdy%howdy_', //The works
     352                        'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', //Plain text
     353                );
     354                $expected = array(
     355                        'howdy\\%',
     356                        'howdy\\_',
     357                        'howdy\\\\',
     358                        'howdy\\\\howdy\\%howdy\\_',
     359                        'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?',
     360                );
     361
     362                foreach ($inputs as $key => $input) {
     363                        $this->assertEquals($expected[$key], $wpdb->esc_like($input));
     364                }
     365        }
     366
     367        /**
     368         * Test LIKE Queries
     369         *
     370         * Make sure $wpdb is fully compatible with esc_like() by testing the identity of various strings.
     371         * When escaped properly, a string literal is always LIKE itself (1)
     372         * and never LIKE any other string literal (0) no matter how crazy the SQL looks.
     373         *
     374         * @ticket 10041
     375         * @dataProvider data_like_query
     376         * @param $data string The haystack, raw.
     377         * @param $like string The like phrase, raw.
     378         * @param $result string The expected comparison result; '1' = true, '0' = false
     379         */
     380        function test_like_query( $data, $like, $result ) {
     381                global $wpdb;
     382                return $this->assertEquals( $result, $wpdb->get_var( $wpdb->prepare( "SELECT %s LIKE %s", $data, $wpdb->esc_like( $like ) ) ) );
     383        }
     384
     385        function data_like_query() {
     386                return array(
     387                        array(
     388                                'aaa',
     389                                'aaa',
     390                                '1',
     391                        ),
     392                        array(
     393                                'a\\aa', // SELECT 'a\\aa'  # This represents a\aa in both languages.
     394                                'a\\aa', // LIKE 'a\\\\aa'
     395                                '1',
     396                        ),
     397                        array(
     398                                'a%aa',
     399                                'a%aa',
     400                                '1',
     401                        ),
     402                        array(
     403                                'aaaa',
     404                                'a%aa',
     405                                '0',
     406                        ),
     407                        array(
     408                                'a\\%aa', // SELECT 'a\\%aa'
     409                                'a\\%aa', // LIKE 'a\\\\\\%aa' # The PHP literal would be "LIKE 'a\\\\\\\\\\\\%aa'".  This is why we need reliable escape functions!
     410                                '1',
     411                        ),
     412                        array(
     413                                'a%aa',
     414                                'a\\%aa',
     415                                '0',
     416                        ),
     417                        array(
     418                                'a\\%aa',
     419                                'a%aa',
     420                                '0',
     421                        ),
     422                        array(
     423                                'a_aa',
     424                                'a_aa',
     425                                '1',
     426                        ),
     427                        array(
     428                                'aaaa',
     429                                'a_aa',
     430                                '0',
     431                        ),
     432                        array(
     433                                'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?',
     434                                'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?',
     435                                '1',
     436                        ),
     437                );
     438        }
    340439}
  • tests/phpunit/tests/formatting/LikeEscape.php

     
    1 <?php
    2 
    3 /**
    4  * @group formatting
    5  */
    6 class Tests_Formatting_LikeEscape extends WP_UnitTestCase {
    7         /**
    8          * @ticket 10041
    9          */
    10         function test_like_escape() {
    11 
    12                 $inputs = array(
    13                         'howdy%', //Single Percent
    14                         'howdy_', //Single Underscore
    15                         'howdy\\', //Single slash
    16                         'howdy\\howdy%howdy_', //The works
    17                 );
    18                 $expected = array(
    19                         "howdy\\%",
    20                         'howdy\\_',
    21                         'howdy\\\\',
    22                         'howdy\\\\howdy\\%howdy\\_'
    23                 );
    24 
    25                 foreach ($inputs as $key => $input) {
    26                         $this->assertEquals($expected[$key], like_escape($input));
    27                 }
    28         }
    29 }