WordPress.org

Make WordPress Core

Ticket #11608: 11608.4.patch

File 11608.4.patch, 5.4 KB (added by hakre, 4 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        /**