Commit:    7751a6882485de64365661f4e7918535c3992982
Author:    Remi Collet <r...@php.net>         Mon, 26 Nov 2012 12:59:08 +0100
Parents:   289bb339c9e722ff3017ec58fdef7300f39b8e6d
Branches:  PHP-5.4

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=7751a6882485de64365661f4e7918535c3992982

Log:
Related bug #63588 fix length computation + optimize for speed

Following comment from Yoram "The patch looks fine, except of testing
for true value of utf16 in each iteration."
Also fix the length computation during check phase.

Bugs:
https://bugs.php.net/63588

Changed paths:
  M  ext/json/json.c


Diff:
diff --git a/ext/json/json.c b/ext/json/json.c
index 270c7cb..fb01529 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -349,12 +349,13 @@ static int json_utf8_to_utf16(unsigned short *utf16, char 
utf8[], int len) /* {{
        size_t pos = 0, us;
        int j, status;
 
-       for (j=0 ; pos < len ; j++) {
-               us = php_next_utf8_char((const unsigned char *)utf8, len, &pos, 
&status);
-               if (status != SUCCESS) {
-                       return -1;
-               }
-               if (utf16) {
+       if (utf16) {
+               /* really convert the utf8 string */
+               for (j=0 ; pos < len ; j++) {
+                       us = php_next_utf8_char((const unsigned char *)utf8, 
len, &pos, &status);
+                       if (status != SUCCESS) {
+                               return -1;
+                       }
                        /* From http://en.wikipedia.org/wiki/UTF16 */
                        if (us >= 0x10000) {
                                us -= 0x10000;
@@ -364,14 +365,23 @@ static int json_utf8_to_utf16(unsigned short *utf16, char 
utf8[], int len) /* {{
                                utf16[j] = (unsigned short)us;
                        }
                }
+       } else {
+               /* Only check if utf8 string is valid, and compute utf16 lenght 
*/
+               for (j=0 ; pos < len ; j++) {
+                       us = php_next_utf8_char((const unsigned char *)utf8, 
len, &pos, &status);
+                       if (status != SUCCESS) {
+                               return -1;
+                       }
+                       if (us >= 0x10000) {
+                               j++;
+                       }
+               }
        }
        return j;
 }
 /* }}} */
 
 
-#define REVERSE16(us) (((us & 0xf) << 12) | (((us >> 4) & 0xf) << 8) | (((us 
>> 8) & 0xf) << 4) | ((us >> 12) & 0xf))
-
 static void json_escape_string(smart_str *buf, char *s, int len, int options 
TSRMLS_DC) /* {{{ */
 {
        int pos = 0, ulen = 0;
@@ -516,15 +526,10 @@ static void json_escape_string(smart_str *buf, char *s, 
int len, int options TSR
                                        smart_str_appendc(buf, (unsigned char) 
us);
                                } else {
                                        smart_str_appendl(buf, "\\u", 2);
-                                       us = REVERSE16(us);
-
-                                       smart_str_appendc(buf, digits[us & ((1 
<< 4) - 1)]);
-                                       us >>= 4;
-                                       smart_str_appendc(buf, digits[us & ((1 
<< 4) - 1)]);
-                                       us >>= 4;
-                                       smart_str_appendc(buf, digits[us & ((1 
<< 4) - 1)]);
-                                       us >>= 4;
-                                       smart_str_appendc(buf, digits[us & ((1 
<< 4) - 1)]);
+                                       smart_str_appendc(buf, digits[(us & 
0xf000) >> 12]);
+                                       smart_str_appendc(buf, digits[(us & 
0xf00)  >> 8]);
+                                       smart_str_appendc(buf, digits[(us & 
0xf0)   >> 4]);
+                                       smart_str_appendc(buf, digits[(us & 
0xf)]);
                                }
                                break;
                }


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to