WordPress.org

Make WordPress Core

Ticket #11608: 11608-rev3.patch

File 11608-rev3.patch, 7.3 KB (added by hakre, 8 years ago)
  • wp-includes/wp-db.php

     
    503503         * @param string|array $data
    504504         * @return string query safe string
    505505         */
    506         function escape($data) {
    507                 if ( is_array($data) ) {
    508                         foreach ( (array) $data as $k => $v ) {
    509                                 if ( is_array($v) )
    510                                         $data[$k] = $this->escape( $v );
    511                                 else
    512                                         $data[$k] = $this->_weak_escape( $v );
    513                         }
    514                 } else {
    515                         $data = $this->_weak_escape( $data );
    516                 }
    517 
    518                 return $data;
     506        function escape($data) {               
     507                if ( is_array($data) )
     508                         return array_map( array( &$this, 'escape' ), $data );
     509               
     510                return addslashes( $data );
    519511        }
    520512
    521513        /**
     
    530522        }
    531523
    532524        /**
    533          * Prepares a SQL query for safe execution.  Uses sprintf()-like syntax.
     525         * Prepare
    534526         *
    535          * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string).
    536          * Does not support sign, padding, alignment, width or precision specifiers.
    537          * Does not support argument numbering/swapping.
     527         * Mimicks a prepare of a SQL query for safer execution. 
     528         *
     529         * The following directives can be used in the query format string:
     530         *
     531         *   %d (decimal number)
     532         *   %s (string)
     533         *   %% (literal percentage sign - no argument needed)
    538534         *
    539          * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
     535         * Both %d and %s are to be left unquoted in the query string and
     536         * they need an argument passed for them.
     537         * Literals (%) as parts of the query must be properly written
     538         * as %%.
    540539         *
    541          * Both %d and %s should be left unquoted in the query string.
    542          *
    543540         * <code>
    544          * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
     541         * $wpdb->prepare( 'SELECT * FROM `table` WHERE `column` = %s AND `field` = %d', 'foo', 1337 );
     542         * $wpdb->prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
    545543         * </code>
     544         *
     545         * NOTE: Do not mix with prepared statements, it's more a rudimentary
     546         *       implementation of a sort of emulated prepares.
    546547         *
    547          * @link http://php.net/sprintf Description of syntax.
     548         * Uses sprintf() / vsprintf()-like syntax.
     549         *
     550         * This function only supports a small subset of the sprintf format
     551         * syntax; it only supports %d (decimal number), %s (string) and
     552         * %% (literal percentage character). It does not support any other
     553         * feature.
     554         *
     555         * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
     556         *
     557         * @link http://php.net/sprintf Description of format.
    548558         * @since 2.3.0
    549559         *
    550          * @param string $query Query statement with sprintf()-like placeholders
    551          * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
    552          * @param mixed $args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
    553          * @return null|string Sanitized query string
     560         * @param  string $query     (optional) Query statement with wpdb->prepare directives (%%, %d, $s)
     561         * @param  array|mixed $args (optional) array or actual value to be used for directives like in {@link http://php.net/vsprintf vsprintf()}, or {@link http://php.net/sprintf sprintf()}.
     562         * @param  mixed $args,...   further values to be used.
     563         * @return false|string      Processed query with values applied according the directives
    554564         */
    555         function prepare($query = null) { // ( $query, *$args )
     565        function prepare( $query = null ) { // ( $query, *$args )
     566
    556567                if ( is_null( $query ) )
    557                         return;
     568                        return false;
     569
    558570                $args = func_get_args();
    559571                array_shift($args);
    560                 // If args were passed as an array (as in vsprintf), move them up
    561                 if ( isset($args[0]) && is_array($args[0]) )
    562                         $args = $args[0];
    563                 $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
    564                 $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
    565                 $query = str_replace('%s', "'%s'", $query); // quote the strings
    566                 array_walk($args, array(&$this, 'escape_by_ref'));
    567                 return @vsprintf($query, $args);
     572                if ( isset( $args[0] ) && is_array( $args[0] ) )
     573                        $args = $args[0]; # re-assign args passed as array like in vsprintf                                                     
     574                       
     575                if ( false === ( $query_quoted = $this->_prepare_quote_lits($query, true, count($args) ) ) ) {                 
     576                        $this->last_query = null;                       
     577                        $this->print_error( sprintf( /*WP_I18N_DB_PREPARE_ERROR*/" \$db->prepare(string query, *args) -- Prepare '%s' is not syntactically correct for %d arguments."/*/WP_I18N_DB_PREPARE_ERROR*/, $query, count($args) ) );                   
     578                        return false;                           
     579                } else {
     580                        $query_quoted = str_replace( array( "''%s''", "\"'%'\"" ), "'%s'", $query_quoted ); # in case someone mistakenly already single/double quoted it
     581                        array_walk( $args, array( &$this, 'escape_by_ref' ) );
     582                        return vsprintf( $query_quoted, $args );                                               
     583                }
    568584        }
    569585
    570586        /**
     587         * helper function for prepare()
     588         *
     589         * will quote %s tokens with single quotes
     590         * allowed tokens are: %%, %d and %s
     591         *
     592         * can do strict parsing and return false if the query is 
     593         * not valid.
     594         *
     595         * @access private
     596         * @param  string $query  wpdb prepare-pattern that needs to be single-quoted to %s
     597         * @param  bool   $strict (optional) wether or not do strict parsing of the query
     598         * @param  int    $argc   (optional) number of arguments for pattern (strict mode)
     599         * @return string pattern with single quotes added around %s literals
     600         * @return bool   false on syntax error if $strict param is true
     601         */
     602        function _prepare_quote_lits( $query, $strict = false, $argc = -1 ) {                                           
     603                $m     = strlen( $query = (string) $query );
     604                $args  = 0;             
     605                for ( $i = 0; $i < $m; $i++) {                 
     606                        if ( '%' == $query[$i] ) {
     607                                $c = ( ++$i < $m ) ? $query[$i] : '' ;                 
     608                                switch ( $c ) {
     609                                        case 's':                                                                                               
     610                                                $query = substr( $query, 0, $i-1 ) . "'%s'" . substr( $query, ++$i );
     611                                                $i++;
     612                                                $m+=2;
     613                                        case 'd':
     614                                                $args++;
     615                                        case '%':                                               
     616                                                break;
     617                                        default: # invalid pattern
     618                                                if ( $strict ) return false;
     619                                }
     620                        }
     621                }               
     622                if ( $strict && $argc != -1 && $args != $argc )
     623                        return false;           
     624                return $query;
     625        }
     626
     627        /**
    571628         * Print SQL/DB error.
    572629         *
    573630         * @since 0.71
     
    605662                if ( !$this->show_errors )
    606663                        return false;
    607664
    608                 $str = htmlspecialchars($str, ENT_QUOTES);
    609                 $query = htmlspecialchars($this->last_query, ENT_QUOTES);
     665                $str   = htmlspecialchars( $str,              ENT_QUOTES );
     666                $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
     667                $query = $query ? sprintf( '<code>%s</code>', $query ) : '' ;                   
    610668
    611                 // If there is an error then take note of it
    612                 print "<div id='error'>
    613                 <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
    614                 <code>$query</code></p>
    615                 </div>";
     669                printf('<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [%s]<br />%s</p>', $str, $query);
    616670        }
    617671
    618672        /**
     
    911965                for ( $i=0; $i < count($this->last_result); $i++ ) {
    912966                        $new_array[$i] = $this->get_var(null, $x, $i);
    913967                }
     968               
    914969                return $new_array;
    915970        }
    916971