diff options
author | Remi Collet <remi@php.net> | 2012-11-26 12:59:08 +0100 |
---|---|---|
committer | Remi Collet <remi@php.net> | 2012-11-26 12:59:08 +0100 |
commit | 7751a6882485de64365661f4e7918535c3992982 (patch) | |
tree | d6c5dcbd4da6b0f10a60d968bea4bc40ca38593b | |
parent | 289bb339c9e722ff3017ec58fdef7300f39b8e6d (diff) | |
download | php-git-7751a6882485de64365661f4e7918535c3992982.tar.gz |
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.
-rw-r--r-- | ext/json/json.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/ext/json/json.c b/ext/json/json.c index 270c7cb346..fb01529711 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; } |