WordPress.org

Make WordPress Core

Ticket #13590: wp-db-utf8-patch.diff

File wp-db-utf8-patch.diff, 24.1 KB (added by aercolino, 3 years ago)
  • wp-includes/Ando/Utf8.php

    diff -rupN --exclude-from wpdiffexclude.txt wordpress-3.0.4/wp-includes/Ando/Utf8.php wp-db-patched/wp-includes/Ando/Utf8.php
    old new  
     1<?php 
     2/* 
     3Copyright (c) 2011, Andrea Ercolino (http://noteslog.com) 
     4All rights reserved. 
     5 
     6Redistribution and use in source and binary forms, with or without 
     7modification, are permitted provided that the following conditions are met: 
     8    * Redistributions of source code must retain the above copyright 
     9      notice, this list of conditions and the following disclaimer. 
     10    * Redistributions in binary form must reproduce the above copyright 
     11      notice, this list of conditions and the following disclaimer in the 
     12      documentation and/or other materials provided with the distribution. 
     13    * Neither the name of the <organization> nor the 
     14      names of its contributors may be used to endorse or promote products 
     15      derived from this software without specific prior written permission. 
     16 
     17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
     18ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
     19WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
     20DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 
     21DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
     22(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
     23LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
     24ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
     26SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     27*/ 
     28 
     29 
     30 
     31/** 
     32 * @package    Ando_Utf8 
     33 */ 
     34class Ando_Utf8_Exception extends Exception 
     35{} 
     36 
     37 
     38 
     39/** 
     40 * Basic UTF-8 support 
     41 *  
     42 * @link http://noteslog.com/ 
     43 * @link http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
     44 *  
     45 * @package    Ando_Utf8 
     46 */ 
     47class Ando_Utf8 
     48{ 
     49    /** 
     50     * Escape UTF-8 characters using the given options 
     51     *  
     52     * About the write.callback option 
     53     * -- it receives  
     54     * -- -- the given write.arguments  
     55     * -- -- the unicode of the current UTF-8 character 
     56     * -- -- the current (unescaped) UTF-8 character 
     57     * -- it must return the current escaped UTF-8 character 
     58     *  
     59     * @link http://noteslog.com/post/escaping-and-unescaping-utf-8-characters-in-php/ 
     60     *  
     61     * @param  string $value 
     62     * @param  array $options 
     63     *   'escapeControlChars'   => boolean (default: TRUE), 
     64     *   'escapePrintableASCII' => boolean (default: FALSE), 
     65     *   'write'                => array( 
     66     *       'callback'  => callable (default: 'sprintf'), 
     67     *       'arguments' => array    (default: array('\u%04x')), 
     68     *   ), 
     69     *   'extendedUseSurrogate' => boolean (default: true), 
     70     *  
     71     * @throws Ando_Utf8_Exception If the code point of any char in $value is  
     72     *                             not unicode 
     73     * @return string 
     74     */ 
     75    public static function escape($value, array $options = array()) 
     76    { 
     77        $options = array_merge(array( 
     78            'escapeControlChars'   => true, 
     79            'escapePrintableASCII' => false, 
     80            'write'                => array( 
     81                'callback'  => 'sprintf', 
     82                'arguments' => array('\u%04x'), 
     83            ), 
     84            'extendedUseSurrogate' => true, 
     85        ), $options); 
     86        if (! self::isCallable($options['write'])) 
     87        { 
     88            throw new Ando_Utf8_Exception('Expected a valid write handler (callable, array).'); 
     89        } 
     90        if (self::validateFilters($options) && isset($options['filters']['before-write'])) 
     91        { 
     92            $value = self::call($options['filters']['before-write'], $value); 
     93        } 
     94         
     95        $result = ""; 
     96        $length = strlen($value); 
     97        for($i = 0; $i < $length; $i++) { 
     98            $ord_var_c = ord($value[$i]); 
     99             
     100            switch (true) { 
     101                case ($ord_var_c < 0x20): 
     102                    // code points 0x00000000..0x0000001F, mask 0xxxxxxx 
     103                    $utf8Char = $value[$i]; 
     104                    $result .= $options['escapeControlChars'] 
     105                        ? self::call($options['write'], array($ord_var_c, $utf8Char)) 
     106                        : $value[$i]; 
     107                break; 
     108 
     109                case ($ord_var_c < 0x80): 
     110                    // code points 0x00000020..0x0000007F, mask 0xxxxxxx 
     111                    $utf8Char = $value[$i]; 
     112                    $result .= $options['escapePrintableASCII']  
     113                        ? self::call($options['write'], array($ord_var_c, $utf8Char)) 
     114                        : $value[$i]; 
     115                break; 
     116 
     117                case (($ord_var_c & 0xE0) == 0xC0): 
     118                    // code points 0x00000080..0x000007FF, mask 110yyyyy 10xxxxxx 
     119                    $utf8Char = substr($value, $i, 2); $i += 1; 
     120                    $code = self::utf8CharToCodePoint($utf8Char); 
     121                    $result .= self::call($options['write'], array($code, $utf8Char)); 
     122                break; 
     123 
     124                case (($ord_var_c & 0xF0) == 0xE0): 
     125                    // code points 0x00000800..0x0000FFFF, mask 1110zzzz 10yyyyyy 10xxxxxx 
     126                    $utf8Char = substr($value, $i, 3); $i += 2; 
     127                    $code = self::utf8CharToCodePoint($utf8Char); 
     128                    $result .= self::call($options['write'], array($code, $utf8Char)); 
     129                break; 
     130 
     131                case (($ord_var_c & 0xF8) == 0xF0): 
     132                    // code points 0x00010000..0x0010FFFF, mask 11110www 10zzzzzz 10yyyyyy 10xxxxxx 
     133                    $utf8Char = substr($value, $i, 4); $i += 3; 
     134                    if ($options['extendedUseSurrogate']) 
     135                    { 
     136                        list($upper, $lower) = self::utf8CharToSurrogatePair($utf8Char); 
     137                        $result .= self::call($options['write'], array($upper, $utf8Char)); 
     138                        $result .= self::call($options['write'], array($lower, $utf8Char)); 
     139                    } 
     140                    else  
     141                    { 
     142                        $code = self::utf8CharToCodePoint($utf8Char); 
     143                        $result .= self::call($options['write'], array($code, $utf8Char)); 
     144                    } 
     145                break; 
     146 
     147                default: 
     148                    //no more cases in unicode, whose range is 0x00000000..0x0010FFFF 
     149                    throw new Ando_Utf8_Exception('Expected a valid UTF-8 character.'); 
     150                break; 
     151            } 
     152        } 
     153 
     154        return $result; 
     155     } 
     156      
     157    /** 
     158     * Compute the code point of a given UTF-8 character 
     159     * 
     160     * If available, use the multibye string function mb_convert_encoding 
     161     * TODO reject overlong sequences in $utf8Char 
     162     * 
     163     * @link http://noteslog.com/post/escaping-and-unescaping-utf-8-characters-in-php/ 
     164     *  
     165     * @param  string $utf8Char 
     166     * @throws Ando_Utf8_Exception If the code point of $utf8Char is not unicode 
     167     * @return integer 
     168     */ 
     169    public static function utf8CharToCodePoint($utf8Char) 
     170    { 
     171        if (function_exists('mb_convert_encoding'))  
     172        { 
     173            $utf32Char = mb_convert_encoding($utf8Char, 'UTF-32', 'UTF-8'); 
     174        }  
     175        else  
     176        { 
     177            $bytes = array('C*'); 
     178            list(, $utf8Int) = unpack('N', str_repeat(chr(0), 4 - strlen($utf8Char)) . $utf8Char); 
     179            switch (strlen($utf8Char))  
     180            { 
     181                case 1: 
     182                    //Code points U+0000..U+007F 
     183                    //mask   0xxxxxxx (7 bits) 
     184                    //map to 00000000 00000000 00000000 0xxxxxxx 
     185                    $bytes[] = 0; 
     186                    $bytes[] = 0; 
     187                    $bytes[] = 0; 
     188                    $bytes[] = $utf8Int; 
     189                break; 
     190     
     191                case 2: 
     192                    //Code points U+0080..U+07FF 
     193                    //mask   110yyyyy 10xxxxxx (5 + 6 = 11 bits) 
     194                    //map to 00000000 00000000 00000yyy yyxxxxxx 
     195                    $bytes[] = 0; 
     196                    $bytes[] = 0; 
     197                    $bytes[] = $utf8Int >> 10 & 0x07; 
     198                    $bytes[] = $utf8Int >>  2 & 0xC0 | $utf8Int       & 0x3F; 
     199                break; 
     200     
     201                case 3: 
     202                    //Code points U+0800..U+D7FF and U+E000..U+FFFF 
     203                    //mask   1110zzzz 10yyyyyy 10xxxxxx (4 + 6 + 6 = 16 bits) 
     204                    //map to 00000000 00000000 zzzzyyyy yyxxxxxx 
     205                    $bytes[] = 0; 
     206                    $bytes[] = 0; 
     207                    $bytes[] = $utf8Int >> 12 & 0xF0 | $utf8Int >> 10 & 0x0F; 
     208                    $bytes[] = $utf8Int >>  2 & 0xC0 | $utf8Int       & 0x3F; 
     209                break; 
     210                              
     211                case 4: 
     212                    //Code points U+10000..U+10FFFF 
     213                    //mask   11110www 10zzzzzz 10yyyyyy 10xxxxxx (3 + 6 + 6 + 6 = 21 bits) 
     214                    //map to 00000000 000wwwzz zzzzyyyy yyxxxxxx 
     215                    $bytes[] = 0; 
     216                    $bytes[] = $utf8Int >> 22 & 0x1C | $utf8Int >> 20 & 0x03; 
     217                    $bytes[] = $utf8Int >> 12 & 0xF0 | $utf8Int >> 10 & 0x0F; 
     218                    $bytes[] = $utf8Int >>  2 & 0xC0 | $utf8Int       & 0x3F; 
     219                break; 
     220                 
     221                default: 
     222                    //no more cases in unicode, whose range is 0x00000000 - 0x0010FFFF 
     223                    throw new Ando_Utf8_Exception('Expected a valid UTF-8 character.'); 
     224                break; 
     225            } 
     226            $utf32Char = call_user_func_array('pack', $bytes); 
     227        } 
     228        list(, $result) = unpack('N', $utf32Char); //unpack returns an array with base 1 
     229        if (0xD800 <= $result && $result <= 0xDFFF)  
     230        { 
     231            //reserved for UTF-16 surrogates 
     232            throw new Ando_Utf8_Exception('Expected a valid UTF-8 character.'); 
     233        } 
     234        if (0xFFFE == $result || 0xFFFF == $result)  
     235        { 
     236            //reserved 
     237            throw new Ando_Utf8_Exception('Expected a valid UTF-8 character.'); 
     238        } 
     239         
     240        return $result; 
     241    } 
     242     
     243    /** 
     244     * Compute the surrogate pair of a given extended UTF-8 character 
     245     *  
     246     * @link http://noteslog.com/post/escaping-and-unescaping-utf-8-characters-in-php/ 
     247     * @link http://en.wikipedia.org/wiki/UTF-16/UCS-2 
     248     *  
     249     * @param  string $utf8Char 
     250     * @throws Ando_Utf8_Exception If the code point of $utf8Char is not extended unicode 
     251     * @return array 
     252     */ 
     253    public static function utf8CharToSurrogatePair($utf8Char)  
     254    { 
     255        $codePoint = self::utf8CharToCodePoint($utf8Char); 
     256        if ($codePoint < 0x10000)  
     257        { 
     258            throw new Ando_Utf8_Exception('Expected an extended UTF-8 character.'); 
     259        } 
     260        $codePoint -= 0x10000; 
     261        $upperSurrogate = 0xD800 + ($codePoint >> 10); 
     262        $lowerSurrogate = 0xDC00 + ($codePoint & 0x03FF); 
     263        $result = array($upperSurrogate, $lowerSurrogate); 
     264         
     265        return $result; 
     266    } 
     267     
     268        /** 
     269     * Unescape UTF-8 characters from a given escape format 
     270     *  
     271     * About the read.callback option 
     272     * -- it receives  
     273     * -- -- the given read.arguments  
     274     * -- -- the current match of the pattern with all submatches 
     275     * -- it must return the current unicode integer 
     276     *  
     277     * @link http://noteslog.com/post/escaping-and-unescaping-utf-8-characters-in-php/ 
     278     *  
     279     * @param  string $value 
     280     * @param  array $options 
     281     *   'read'                 => array( 
     282     *           'pattern'   => preg     (default: '@\\\\u([0-9A-Fa-f]{4})@'), 
     283     *       'callback'  => callable (default: create_function('$all, $code', 'return hexdec($code);')), 
     284     *       'arguments' => array    (deafult: array()), 
     285     *   ), 
     286     *   'extendedUseSurrogate' => boolean (default: TRUE), 
     287     *  
     288     * @throws Ando_Utf8_Exception If the code point of any char in $value is  
     289     *                             not unicode 
     290     *  
     291     * @return string 
     292     */ 
     293    public static function unescape($value, array $options = array()) 
     294    { 
     295        $options = array_merge(array( 
     296                'read'                 => array( 
     297                'pattern'   => '@\\\\u([0-9A-Fa-f]{4})@', 
     298                'callback'  => create_function('$all, $code', 'return hexdec($code);'), 
     299                'arguments' => array(), 
     300            ), 
     301            'extendedUseSurrogate' => true, 
     302        ), $options); 
     303         
     304        if (! self::isCallable($options['read'])) 
     305        { 
     306            throw new Ando_Utf8_Exception('Expected a valid read handler (callable, array).'); 
     307        } 
     308        $thereAreFilters = self::validateFilters($options); 
     309         
     310        $result = ""; 
     311        while (preg_match($options['read']['pattern'], $value, $matches, PREG_OFFSET_CAPTURE)) 
     312        { 
     313            $unicode = self::eatUpMatches($result, $value, $matches, $options['read']); 
     314            if ($options['extendedUseSurrogate'] && (0xD800 <= $unicode && $unicode < 0xDC00)) 
     315            { 
     316                $upperSurrogate = $unicode; 
     317                if (! preg_match($options['read']['pattern'], $value, $matches, PREG_OFFSET_CAPTURE)) 
     318                { 
     319                    throw new Ando_Utf8_Exception('Expected an extended UTF-8 character.'); 
     320                } 
     321                $unicode = self::eatUpMatches($result, $value, $matches, $options['read']); 
     322                $utf8Char = self::utf8CharFromSurrogatePair(array($upperSurrogate, $unicode)); 
     323            } 
     324            else  
     325            { 
     326                $utf8Char = self::utf8CharFromCodePoint($unicode); 
     327            } 
     328            $result .= $utf8Char; 
     329        } 
     330        $result .= $value; 
     331         
     332        if ($thereAreFilters && isset($options['filters']['after-read'])) 
     333        { 
     334            $result = self::call($options['filters']['after-read'], $result); 
     335        } 
     336         
     337        return $result; 
     338     } 
     339      
     340    /** 
     341     * Compute the UTF-8 character of a given code point 
     342     * 
     343     * If available, use the multibye string function mb_convert_encoding 
     344     * 
     345     * @link http://noteslog.com/post/escaping-and-unescaping-utf-8-characters-in-php/ 
     346     *  
     347     * @param  integer $codePoint 
     348     * @throws Ando_Utf8_Exception if the code point is not unicode 
     349     * @return string 
     350     */ 
     351    public static function utf8CharFromCodePoint($codePoint) 
     352    { 
     353        if (0xD800 <= $codePoint && $codePoint <= 0xDFFF)  
     354        { 
     355            //reserved for UTF-16 surrogates 
     356            throw new Ando_Utf8_Exception('Expected a valid code point.'); 
     357        } 
     358        if (0xFFFE == $codePoint || 0xFFFF == $codePoint)  
     359        { 
     360            //reserved 
     361            throw new Ando_Utf8_Exception('Expected a valid code point.'); 
     362        } 
     363         
     364        if (function_exists('mb_convert_encoding'))  
     365        { 
     366            $utf32Char = pack('N', $codePoint); 
     367            $result = mb_convert_encoding($utf32Char, 'UTF-8', 'UTF-32'); 
     368        }  
     369        else  
     370        { 
     371            $bytes = array('C*'); 
     372            switch (true) 
     373            { 
     374                case ($codePoint < 0x80): 
     375                    //Code points U+0000..U+007F 
     376                    //mask     0xxxxxxx (7 bits) 
     377                    //map from xxxxxxx 
     378                    $bytes[] = $codePoint; 
     379                break; 
     380                 
     381                case ($codePoint < 0x800): 
     382                    //Code points U+0080..U+07FF 
     383                    //mask     110yyyyy 10xxxxxx (5 + 6 = 11 bits) 
     384                    //map from yyy yyxxxxxx 
     385                    $bytes[] = 0xC0 | $codePoint >> 6; 
     386                    $bytes[] = 0x80 | $codePoint       & 0x3F; 
     387                break; 
     388                 
     389                case ($codePoint < 0x10000): 
     390                    //Code points U+0800..U+D7FF and U+E000..U+FFFF 
     391                    //mask     1110zzzz 10yyyyyy 10xxxxxx (4 + 6 + 6 = 16 bits) 
     392                    //map from zzzzyyyy yyxxxxxx 
     393                    $bytes[] = 0xE0 | $codePoint >> 12; 
     394                    $bytes[] = 0x80 | $codePoint >> 6  & 0x3F; 
     395                    $bytes[] = 0x80 | $codePoint       & 0x3F; 
     396                break; 
     397                 
     398                case ($codePoint < 0x110000): 
     399                    //Code points U+10000..U+10FFFF 
     400                    //mask     11110www 10zzzzzz 10yyyyyy 10xxxxxx (3 + 6 + 6 + 6 = 21 bits) 
     401                    //map from wwwzz zzzzyyyy yyxxxxxx 
     402                    $bytes[] = 0xF0 | $codePoint >> 18; 
     403                    $bytes[] = 0x80 | $codePoint >> 12 & 0x3F; 
     404                    $bytes[] = 0x80 | $codePoint >> 6  & 0x3F; 
     405                    $bytes[] = 0x80 | $codePoint       & 0x3F; 
     406                break; 
     407                 
     408                default: 
     409                    throw new Ando_Utf8_Exception('Expected a valid code point.'); 
     410                break; 
     411            } 
     412            $result = call_user_func_array('pack', $bytes); 
     413        } 
     414        return $result; 
     415    } 
     416     
     417    /** 
     418     * Compute the extended UTF-8 character of a given surrogate pair 
     419     *  
     420     * @link   http://noteslog.com/post/escaping-and-unescaping-utf-8-characters-in-php/ 
     421     * @link http://en.wikipedia.org/wiki/UTF-16/UCS-2 
     422     *  
     423     * @param array $surrogatePair 
     424     * @throws Ando_Utf8_Exception If the surrogate pair is not extended unicode 
     425     * @return string 
     426     */ 
     427    public static function utf8CharFromSurrogatePair($surrogatePair)  
     428    { 
     429        list($upperSurrogate, $lowerSurrogate) = $surrogatePair; 
     430        if (! (0xD800 <= $upperSurrogate && $upperSurrogate < 0xDC00)) 
     431        { 
     432            throw new Ando_Utf8_Exception('Expected an extended UTF-8 character.'); 
     433        } 
     434        if (! (0xDC00 <= $lowerSurrogate && $lowerSurrogate < 0xE000)) 
     435        { 
     436            throw new Ando_Utf8_Exception('Expected an extended UTF-8 character.'); 
     437        } 
     438        $codePoint = ($upperSurrogate & 0x03FF) << 10 | ($lowerSurrogate & 0x03FF); 
     439        $codePoint += 0x10000; 
     440        $result = self::utf8CharFromCodePoint($codePoint); 
     441         
     442        return $result; 
     443    } 
     444     
     445    /** 
     446     * Validate filters. If there are filters return true, else false 
     447     *  
     448     * @param array $options 
     449     * @throws Ando_Utf8_Exception If there are malformed filters 
     450     * @return boolean 
     451     */ 
     452    protected static function validateFilters($options) 
     453    { 
     454        if (isset($options['filters'])) 
     455        { 
     456            if (! is_array($options['filters'])) 
     457            { 
     458                throw new Ando_Utf8_Exception('Expected valid filters.'); 
     459            } 
     460            foreach ($options['filters'] as $key => $value) 
     461            { 
     462                if (! self::isCallable($value)) 
     463                { 
     464                    throw new Ando_Utf8_Exception("Expected a valid $key handler."); 
     465                } 
     466            } 
     467            return true; 
     468        } 
     469        return false; 
     470    } 
     471     
     472    /** 
     473     * A little calling interface: validation 
     474     *  
     475     * @param  array  $handler 
     476     * @return boolean 
     477     */ 
     478    private static function isCallable($handler) 
     479    { 
     480        $result = is_callable($handler['callback']) && is_array($handler['arguments']); 
     481        return $result; 
     482    } 
     483     
     484    /** 
     485     * A little calling interface: call 
     486     *  
     487     * @param  array  $handler 
     488     * @param  mixed  $args 
     489     * @return mixed 
     490     */ 
     491    private static function call($handler, $args) 
     492    { 
     493        $args = array_merge($handler['arguments'], is_array($args) ? $args : array($args)); 
     494        $result = call_user_func_array($handler['callback'], $args); 
     495        return $result; 
     496    } 
     497     
     498    /**  
     499     * Return the transposition of the given array 
     500     *  
     501     * @param array $rows  
     502     * @return array 
     503     */  
     504    private static function transpose($rows)  
     505    {  
     506        $result = call_user_func_array('array_map', array_merge(array(null), $rows));  
     507        return $result;  
     508    } 
     509     
     510    /** 
     511     * 1: update $processed with the unmatched substring before $matches 
     512     * 2: update $value with the rest of the substring after $matches 
     513     * 3: return unicode read from the matched substring in $matches 
     514     *  
     515     * @param string $processed 
     516     * @param string $value 
     517     * @param array $matches 
     518     * @param array $handler 
     519     * @return integer 
     520     */ 
     521    private static function eatUpMatches(&$processed, &$value, $matches, $handler) 
     522    { 
     523        $match  = $matches[0][0]; 
     524        $offset = $matches[0][1]; 
     525        $processed .= substr($value, 0, $offset); 
     526        $value = substr($value, $offset + strlen($match)); 
     527         
     528        $matches = self::transpose($matches); 
     529        $args = $matches[0]; 
     530        $result = self::call($handler, $args); 
     531         
     532        return $result; 
     533    } 
     534     
     535} 
  • wp-includes/full-utf8.php

    diff -rupN --exclude-from wpdiffexclude.txt wordpress-3.0.4/wp-includes/full-utf8.php wp-db-patched/wp-includes/full-utf8.php
    old new  
     1<?php 
     2/* 
     3Author: Andrea Ercolino 
     4Author URI: http://noteslog.com 
     5License: New BSD License 
     6*/ 
     7 
     8require( ABSPATH . WPINC . '/Ando/Utf8.php' ); 
     9 
     10function full_utf8_options()  
     11{ 
     12        $result = array( 
     13        'extendedUseSurrogate' => false, 
     14        'write'                => array( 
     15            'callback'  => create_function('$format, $unicode, $utf8Char', 'return $unicode < 0x10000  
     16                ? $utf8Char  
     17                : sprintf($format, $unicode);'), 
     18            'arguments' => array('(#%s#)'), 
     19        ), 
     20        'read'                 => array( 
     21            'pattern'   => '/\(#(\d+)#\)/', 
     22            'callback'  => create_function('$all, $unicode', 'return $unicode;'), 
     23            'arguments' => array(), 
     24        ), 
     25        'filters'              => array( 
     26            'before-write' => array( 
     27                'callback'  => 'preg_replace', 
     28                'arguments' => array('/\(#(\d+#\))/', '(##\1'), 
     29            ), 
     30            'after-read'   => array( 
     31                'callback'  => 'preg_replace', 
     32                'arguments' => array('/\(##(\d+#\))/', '(#\1'), 
     33            ), 
     34        ), 
     35    ); 
     36        return $result; 
     37} 
     38 
     39function full_utf8_escape( &$content )  
     40{ 
     41    if (! is_string($content)) 
     42        { 
     43            return; 
     44        } 
     45        try  
     46        { 
     47            $options = full_utf8_options(); 
     48            $content = Ando_Utf8::escape($content, $options); 
     49        } 
     50        catch (Exception $e) 
     51        {} 
     52} 
     53 
     54function full_utf8_unescape( &$content )  
     55{ 
     56    if (! is_string($content)) 
     57        { 
     58            return; 
     59        } 
     60        try  
     61        { 
     62            $options = full_utf8_options(); 
     63            $content = Ando_Utf8::unescape($content, $options); 
     64        } 
     65        catch (Exception $e) 
     66        {} 
     67} 
  • wp-includes/wp-db.php

    diff -rupN --exclude-from wpdiffexclude.txt wordpress-3.0.4/wp-includes/wp-db.php wp-db-patched/wp-includes/wp-db.php
    old new class wpdb { 
    11081108                        $dbh =& $this->dbh; 
    11091109                        $this->last_db_used = "other/read"; 
    11101110                } 
    1111  
     1111                 
     1112                full_utf8_escape($query); 
    11121113                $this->result = @mysql_query( $query, $dbh ); 
    11131114                $this->num_queries++; 
    11141115 
    class wpdb { 
    11361137                                $i++; 
    11371138                        } 
    11381139                        $num_rows = 0; 
    1139                         while ( $row = @mysql_fetch_object( $this->result ) ) { 
    1140                                 $this->last_result[$num_rows] = $row; 
     1140                        while ( $row = @mysql_fetch_assoc( $this->result ) ) { 
     1141                            array_walk($row, 'full_utf8_unescape'); 
     1142                                $this->last_result[$num_rows] = (object) $row; 
    11411143                                $num_rows++; 
    11421144                        } 
    11431145 
  • wp-settings.php

    diff -rupN --exclude-from wpdiffexclude.txt wordpress-3.0.4/wp-settings.php wp-db-patched/wp-settings.php
    old new wp_set_lang_dir(); 
    6666require( ABSPATH . WPINC . '/compat.php' ); 
    6767require( ABSPATH . WPINC . '/functions.php' ); 
    6868require( ABSPATH . WPINC . '/classes.php' ); 
     69require( ABSPATH . WPINC . '/full-utf8.php' ); 
    6970 
    7071// Include the wpdb class, or a db.php database drop-in if present. 
    7172require_wp_db();