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