Make WordPress Core

Ticket #11608: 11608.4.patch

File 11608.4.patch, 5.4 KB (added by hakre, 15 years ago)

Code is notice-free now, fixes in print_error in case there was no last_query.

  • 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         * Mimicks a prepare of a SQL query for execution. 
     534         *
     535         * The following placeholders can be used for values:
     536         *
     537         *   %d (decimal number)
     538         *   %s (string)
     539         *   %% (%)
     540         *   
     541         * Both %d and %s should be left unquoted in the query string.
    534542         *
     543         * <code>
     544         * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
     545         * </code>
     546         *
     547         * NOTE: This has nothing to do with prepared statements your database might support.
     548         * 
     549         * More technical information:
     550         *
     551         * Uses sprintf()-like syntax.
     552         *
    535553         * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string).
    536554         * Does not support sign, padding, alignment, width or precision specifiers.
    537555         * Does not support argument numbering/swapping.
    538556         *
    539557         * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
    540558         *
    541          * Both %d and %s should be left unquoted in the query string.
    542          *
    543          * <code>
    544          * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
    545          * </code>
    546          *
    547559         * @link http://php.net/sprintf Description of syntax.
    548560         * @since 2.3.0
    549561         *
    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()}.
     562         * @param string $query Query statement with wpdb->prepare placeholders (%%, %d, $s)
     563         * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called compareable to {@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()}.
     564         * @param mixed $args,... further variables to substitute.
    553565         * @return null|string Sanitized query string
    554566         */
    555567        function prepare($query = null) { // ( $query, *$args )
     
    560572                // If args were passed as an array (as in vsprintf), move them up
    561573                if ( isset($args[0]) && is_array($args[0]) )
    562574                        $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
     575
     576                $check = $this->_prepare_quote_lits($query, true); //quote %s in query-pattern syntax check
     577                if ( false === $check ) {
     578                        $this->last_query = null;                       
     579                        $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 ) );                 
     580                }
     581
     582                $query = $this->_prepare_quote_lits($query); //quote %s in query-pattern                               
     583                $query = str_replace( array( "''%s''", "\"'%'\"" ), "'%s'", $query ); // in case someone mistakenly already single/double quoted it
     584
    566585                array_walk($args, array(&$this, 'escape_by_ref'));
    567586                return @vsprintf($query, $args);
    568587        }
    569588
    570589        /**
     590         * helper function for prepare()
     591         *
     592         * will quote %s tokens with single quotes
     593         * allowed tokens are: %%, %d and %s
     594         *
     595         * can do strict parsing and return false if the query is 
     596         * not valid.
     597         *
     598         * @access private
     599         * @param  string $query  wpdb prepare-pattern that needs to be single-quoted to %s
     600         * @param  bool   $strict (optional) wether or not do strict parsing of the query
     601         * @return string pattern with single quotes added around %s literals
     602         * @return bool   false on syntax error if $strict param is true
     603         */
     604        function _prepare_quote_lits( $query, $strict = false ) {
     605                $query = (string) $query;                               
     606                $m     = strlen( $query );             
     607                for ( $i = 0; $i < $m; $i++) {                 
     608                        if ( '%' == $query[$i] ) {
     609                                $c = ( ++$i < $m ) ? $query[$i] : '' ;                 
     610                                switch ( $c ) {
     611                                        case 's':                                                                                               
     612                                                $query = substr( $query, 0, $i-1) . "'%s'" . substr( $query, ++$i );
     613                                                $i++;
     614                                        case '%':
     615                                        case 'd':                                               
     616                                                break;
     617                                        default: # illegal pattern
     618                                                if ( $strict ) return false;
     619                                }
     620                        }
     621                }
     622                return $query;
     623        }
     624
     625        /**
    571626         * Print SQL/DB error.
    572627         *
    573628         * @since 0.71
     
    605660                if ( !$this->show_errors )
    606661                        return false;
    607662
    608                 $str = htmlspecialchars($str, ENT_QUOTES);
    609                 $query = htmlspecialchars($this->last_query, ENT_QUOTES);
     663                $str   = htmlspecialchars( $str,              ENT_QUOTES );
     664                $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
     665                $query = $query ? sprintf( '<code>%s</code>', $query ) : '' ;                   
    610666
    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>";
     667                printf('<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [%s]<br />%s</p>', $str, $query);
    616668        }
    617669
    618670        /**