WordPress.org

Make WordPress Core

Ticket #11608: 11608-rev2.patch

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

    ### Eclipse Workspace Patch 1.0
    #P wordpress-trunk
     
    530530        }
    531531
    532532        /**
    533          * Prepares a SQL query for safe execution.  Uses sprintf()-like syntax.
     533         * Prepare
    534534         *
    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.
     535         * Mimicks a prepare of a SQL query for safer execution. 
     536         *
     537         * The following directives can be used in the query format string:
     538         *
     539         *   %d (decimal number)
     540         *   %s (string)
     541         *   %% (literal percentage sign - no argument needed)
    538542         *
    539          * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
     543         * Both %d and %s are to be left unquoted in the query string and
     544         * they need an argument passed for them.
     545         * Literals (%) as parts of the query must be properly written
     546         * as %%.
    540547         *
    541          * Both %d and %s should be left unquoted in the query string.
    542          *
    543548         * <code>
    544          * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
     549         * $wpdb->prepare( 'SELECT * FROM `table` WHERE `column` = %s AND `field` = %d', 'foo', 1337 );
     550         * $wpdb->prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
    545551         * </code>
     552         *
     553         * NOTE: Do not mix with prepared statements, it's more a rudimentary
     554         *       implementation of a sort of emulated prepares.
    546555         *
    547          * @link http://php.net/sprintf Description of syntax.
     556         * Uses sprintf() / vsprintf()-like syntax.
     557         *
     558         * This function only supports a small subset of the sprintf format
     559         * syntax; it only supports %d (decimal number), %s (string) and
     560         * %% (literal percentage character). It does not support any other
     561         * feature.
     562         *
     563         * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
     564         *
     565         * @link http://php.net/sprintf Description of format.
    548566         * @since 2.3.0
    549567         *
    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
     568         * @param  string $query     (optional) Query statement with wpdb->prepare directives (%%, %d, $s)
     569         * @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()}.
     570         * @param  mixed $args,...   further values to be used.
     571         * @return false|string      Processed query with values applied according the directives
    554572         */
    555         function prepare($query = null) { // ( $query, *$args )
     573        function prepare( $query = null ) { // ( $query, *$args )
     574
    556575                if ( is_null( $query ) )
    557                         return;
    558                 $args = func_get_args();
    559                 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);
     576                        return false;
     577                       
     578                if ( false === ( $query_quoted = $this->_prepare_quote_lits($query, $check = true) ) ) {                       
     579                        $this->last_query = null;                       
     580                        $this->print_error( sprintf( /*WP_I18N_DB_PREPARE_ERROR*/" \$db->prepare(string query, *args) -- Prepare '%s' is not syntactically correct."/*/WP_I18N_DB_PREPARE_ERROR*/, $query ) );                 
     581                        return false;                           
     582                } else {
     583                        $query_quoted = str_replace( array( "''%s''", "\"'%'\"" ), "'%s'", $query_quoted ); # in case someone mistakenly already single/double quoted it                       
     584                       
     585                        $args = func_get_args();
     586                        array_shift($args);
     587                        // re-assign args passed as array like in vsprintf
     588                        if ( isset( $args[0] ) && is_array( $args[0] ) )
     589                                $args = $args[0];                                                       
     590                        array_walk( $args, array( &$this, 'escape_by_ref' ) );
     591                       
     592                        return @vsprintf( $query_quoted, $args );                                               
     593                } // else/if
    568594        }
    569595
    570596        /**
     597         * helper function for prepare()
     598         *
     599         * will quote %s tokens with single quotes
     600         * allowed tokens are: %%, %d and %s
     601         *
     602         * can do strict parsing and return false if the query is 
     603         * not valid.
     604         *
     605         * @access private
     606         * @param  string $query  wpdb prepare-pattern that needs to be single-quoted to %s
     607         * @param  bool   $strict (optional) wether or not do strict parsing of the query
     608         * @return string pattern with single quotes added around %s literals
     609         * @return bool   false on syntax error if $strict param is true
     610         */
     611        function _prepare_quote_lits( $query, $strict = false ) {
     612                $query = (string) $query;                               
     613                $m     = strlen( $query );             
     614                for ( $i = 0; $i < $m; $i++) {                 
     615                        if ( '%' == $query[$i] ) {
     616                                $c = ( ++$i < $m ) ? $query[$i] : '' ;                 
     617                                switch ( $c ) {
     618                                        case 's':                                                                                               
     619                                                $query = substr( $query, 0, $i-1 ) . "'%s'" . substr( $query, ++$i );
     620                                                $i++;
     621                                        case '%':
     622                                        case 'd':                                               
     623                                                break;
     624                                        default: # illegal pattern
     625                                                if ( $strict ) return false;
     626                                }
     627                        }
     628                }
     629                return $query;
     630        }
     631
     632        /**
    571633         * Print SQL/DB error.
    572634         *
    573635         * @since 0.71
     
    605667                if ( !$this->show_errors )
    606668                        return false;
    607669
    608                 $str = htmlspecialchars($str, ENT_QUOTES);
    609                 $query = htmlspecialchars($this->last_query, ENT_QUOTES);
     670                $str   = htmlspecialchars( $str,              ENT_QUOTES );
     671                $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
     672                $query = $query ? sprintf( '<code>%s</code>', $query ) : '' ;                   
    610673
    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>";
     674                printf('<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [%s]<br />%s</p>', $str, $query);
    616675        }
    617676
    618677        /**