Make WordPress Core

Ticket #10041: miqro-10041.4.patch

File miqro-10041.4.patch, 29.6 KB (added by miqrogroove, 11 years ago)

Fixed missing wildcards from original patch of query.php

  • 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

     
    599599         *
    600600         * @param int $limit Number of custom fields to retrieve. Default 30.
    601601         */
    602         $limit = (int) apply_filters( 'postmeta_form_limit', 30 );
    603         $keys = $wpdb->get_col( "
    604                 SELECT meta_key
     602        $limit = apply_filters( 'postmeta_form_limit', 30 );
     603        $sql = "SELECT meta_key
    605604                FROM $wpdb->postmeta
    606605                GROUP BY meta_key
    607                 HAVING meta_key NOT LIKE '\_%'
     606                HAVING meta_key NOT LIKE %s
    608607                ORDER BY meta_key
    609                 LIMIT $limit" );
     608                LIMIT %d";
     609        $keys = $wpdb->get_col( $wpdb->prepare( $sql, $wpdb->esc_like( '_' ) . '%', $limit ) );
    610610        if ( $keys ) {
    611611                natcasesort( $keys );
    612612                $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 = 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.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-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-includes/bookmark.php

     
    203203        }
    204204
    205205        if ( ! empty($search) ) {
    206                 $search = esc_sql( like_escape( $search ) );
    207                 $search = " AND ( (link_url LIKE '%$search%') OR (link_name LIKE '%$search%') OR (link_description LIKE '%$search%') ) ";
     206                $like = '%' . $wpdb->esc_like( $search ) . '%';
     207                $search = $wpdb->prepare(" AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ", $like, $like, $like );
    208208        }
    209209
    210210        $category_query = '';
  • src/wp-includes/canonical.php

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

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

     
    450450         * @return string
    451451         */
    452452        function get_search_sql( $string, $cols ) {
    453                 $string = esc_sql( like_escape( $string ) );
     453                global $wpdb;
    454454
    455455                $searches = array();
    456456                foreach ( $cols as $col )
    457                         $searches[] = "$col LIKE '%$string%'";
     457                        $searches[] = $wpdb->prepare( "$col LIKE %s", $wpdb->esc_like( $string ) );
    458458
    459459                return ' AND (' . implode(' OR ', $searches) . ')';
    460460        }
  • src/wp-includes/deprecated.php

     
    34383438        _deprecated_function( __FUNCTION__, '3.9' );
    34393439        return $content;
    34403440}
     3441
     3442/**
     3443 * Formerly used to escape strings before searching the DB. It was poorly documented and never worked as described.
     3444 *
     3445 * @since 2.5.0
     3446 * @deprecated 4.0.0
     3447 * @deprecated Use wpdb::esc_like()
     3448 *
     3449 * @param string $text The text to be escaped.
     3450 * @return string text, safe for inclusion in LIKE query.
     3451 */
     3452function like_escape($text) {
     3453        _deprecated_function( __FUNCTION__, '4.0', 'wpdb::esc_like()' );
     3454        return str_replace(array("%", "_"), array("\\%", "\\_"), $text);
     3455}
  • src/wp-includes/formatting.php

     
    30893089}
    30903090
    30913091/**
    3092  * Escapes text for SQL LIKE special characters % and _.
    3093  *
    3094  * @since 2.5.0
    3095  *
    3096  * @param string $text The text to be escaped.
    3097  * @return string text, safe for inclusion in LIKE query.
    3098  */
    3099 function like_escape($text) {
    3100         return str_replace(array("%", "_"), array("\\%", "\\_"), $text);
    3101 }
    3102 
    3103 /**
    31043092 * Convert full URL paths to absolute paths.
    31053093 *
    31063094 * 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

     
    10401040                        } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) {
    10411041                                $meta_value = array_slice( $meta_value, 0, 2 );
    10421042                                $meta_compare_string = '%s AND %s';
    1043                         } elseif ( 'LIKE' == substr( $meta_compare, -4 ) ) {
    1044                                 $meta_value = '%' . like_escape( $meta_value ) . '%';
     1043                        } elseif ( 'LIKE' == $meta_compare || 'NOT LIKE' == $meta_compare ) ) {
     1044                                $meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%';
    10451045                                $meta_compare_string = '%s';
    10461046                        } else {
    10471047                                $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

     
    46744674
    46754675        if ( ! empty($meta['thumb']) ) {
    46764676                // Don't delete the thumb if another attachment uses it
    4677                 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)) ) {
     4677                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)) ) {
    46784678                        $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
    46794679                        /** This filter is documented in wp-admin/custom-header.php */
    46804680                        $thumbfile = apply_filters( 'wp_delete_file', $thumbfile );
  • src/wp-includes/query.php

     
    19771977                $searchand = '';
    19781978                $q['search_orderby_title'] = array();
    19791979                foreach ( $q['search_terms'] as $term ) {
    1980                         $term = like_escape( esc_sql( $term ) );
    1981                         if ( $n )
    1982                                 $q['search_orderby_title'][] = "$wpdb->posts.post_title LIKE '%$term%'";
     1980                        if ( $n ) {
     1981                                $like = '%' . $wpdb->esc_like( $term ) . '%';
     1982                                $q['search_orderby_title'][] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like );
     1983                        }
    19831984
    1984                         $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
     1985                        $like = $n . $wpdb->esc_like( $term ) . $n;
     1986                        $search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title LIKE %s) OR ($wpdb->posts.post_content LIKE %s))", $like, $like );
    19851987                        $searchand = ' AND ';
    19861988                }
    19871989
     
    20802082
    20812083                if ( $q['search_terms_count'] > 1 ) {
    20822084                        $num_terms = count( $q['search_orderby_title'] );
    2083                         $search_orderby_s = like_escape( esc_sql( $q['s'] ) );
     2085                        $like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
    20842086
    20852087                        $search_orderby = '(CASE ';
    20862088                        // sentence match in 'post_title'
    2087                         $search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";
     2089                        $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like );
    20882090
    20892091                        // sanity limit, sort as sentence when more than 6 terms
    20902092                        // (few searches are longer than 6 terms and most titles are not)
     
    20972099                        }
    20982100
    20992101                        // sentence match in 'post_content'
    2100                         $search_orderby .= "WHEN $wpdb->posts.post_content LIKE '%{$search_orderby_s}%' THEN 4 ";
     2102                        $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 4 ", $like );
    21012103                        $search_orderby .= 'ELSE 5 END)';
    21022104                } else {
    21032105                        // single word or sentence search
  • src/wp-includes/taxonomy.php

     
    14531453        }
    14541454
    14551455        if ( !empty($name__like) ) {
    1456                 $name__like = like_escape( $name__like );
    1457                 $where .= $wpdb->prepare( " AND t.name LIKE %s", '%' . $name__like . '%' );
     1456                $where .= $wpdb->prepare( " AND t.name LIKE %s", '%' . $wpdb->esc_like( $name__like ) . '%' );
    14581457        }
    14591458
    14601459        if ( ! empty( $description__like ) ) {
    1461                 $description__like = like_escape( $description__like );
    1462                 $where .= $wpdb->prepare( " AND tt.description LIKE %s", '%' . $description__like . '%' );
     1460                $where .= $wpdb->prepare( " AND tt.description LIKE %s", '%' . $wpdb->esc_like( $description__like ) . '%' );
    14631461        }
    14641462
    14651463        if ( '' !== $parent ) {
     
    14841482        }
    14851483
    14861484        if ( ! empty( $search ) ) {
    1487                 $search = like_escape( $search );
    1488                 $where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', '%' . $search . '%', '%' . $search . '%' );
     1485                $like = '%' . $wpdb->esc_like( $search ) . '%';
     1486                $where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like );
    14891487        }
    14901488
    14911489        $selects = array();
     
    39313929                wp_update_term( $loop_member, $taxonomy, array( 'parent' => 0 ) );
    39323930
    39333931        return $parent;
    3934 }
    3935  No newline at end of file
     3932}
  • src/wp-includes/user.php

     
    797797         * @return string
    798798         */
    799799        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) . ')';
     
    10921092                // Build a CPU-intensive query that will return concise information.
    10931093                $select_count = array();
    10941094                foreach ( $avail_roles as $this_role => $name ) {
    1095                         $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%\"" . like_escape( $this_role ) . "\"%', false))";
     1095                        $select_count[] = $wpdb->prepare( "COUNT(NULLIF(`meta_value` LIKE %s, false))", '%' . $wpdb->esc_like( '"' . $this_role . '"' ) . '%');
    10961096                }
    10971097                $select_count = implode(', ', $select_count);
    10981098
  • 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

     
    226226                $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = $id", $id );
    227227                $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0", $prepared );
    228228        }
     229
     230        /**
     231         * @ticket 10041
     232         */
     233        function test_esc_like() {
     234                global $wpdb;
     235
     236                $inputs = array(
     237                        'howdy%', //Single Percent
     238                        'howdy_', //Single Underscore
     239                        'howdy\\', //Single slash
     240                        'howdy\\howdy%howdy_', //The works
     241                );
     242                $expected = array(
     243                        'howdy\\%',
     244                        'howdy\\_',
     245                        'howdy\\\\',
     246                        'howdy\\\\howdy\\%howdy\\_'
     247                );
     248
     249                foreach ($inputs as $key => $input) {
     250                        $this->assertEquals($expected[$key], $wpdb->esc_like($input));
     251                }
     252        }
     253
     254        /**
     255         * Test LIKE Queries
     256         *
     257         * Make sure $wpdb is fully compatible with esc_like() by testing the identity of various strings.
     258         * When escaped properly, a string literal is always LIKE itself (1)
     259         * and never LIKE any other string literal (0) no matter how crazy the SQL looks.
     260         *
     261         * @ticket 10041
     262         * @dataProvider data_like_query
     263         * @param $data string The haystack, raw.
     264         * @param $like string The like phrase, raw.
     265         * @param $result string The expected comparison result; '1' = true, '0' = false
     266         */
     267        function test_like_query( $data, $like, $result ) {
     268                global $wpdb;
     269                return $this->assertEquals( $result, $wpdb->get_var( $wpdb->prepare( "SELECT %s LIKE %s", $data, $wpdb->esc_like( $like ) ) ) );
     270        }
     271
     272        function data_like_query() {
     273                return array(
     274                        array(
     275                                'aaa',
     276                                'aaa',
     277                                '1',
     278                        ),
     279                        array(
     280                                'a\\aa', // SELECT 'a\\aa'  # This represents a\aa in both languages.
     281                                'a\\aa', // LIKE 'a\\\\aa'
     282                                '1',
     283                        ),
     284                        array(
     285                                'a%aa',
     286                                'a%aa',
     287                                '1',
     288                        ),
     289                        array(
     290                                'aaaa',
     291                                'a%aa',
     292                                '0',
     293                        ),
     294                        array(
     295                                'a\\%aa', // SELECT 'a\\%aa'
     296                                'a\\%aa', // LIKE 'a\\\\\\%aa' # The PHP literal would be "LIKE 'a\\\\\\\\\\\\%aa'".  This is why we need reliable escape functions!
     297                                '1',
     298                        ),
     299                        array(
     300                                'a%aa',
     301                                'a\\%aa',
     302                                '0',
     303                        ),
     304                        array(
     305                                'a\\%aa',
     306                                'a%aa',
     307                                '0',
     308                        ),
     309                        array(
     310                                'a_aa',
     311                                'a_aa',
     312                                '1',
     313                        ),
     314                        array(
     315                                'aaaa',
     316                                'a_aa',
     317                                '0',
     318                        ),
     319                );
     320        }
    229321}
  • 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 }