summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemi Collet <remi@php.net>2012-11-26 12:59:08 +0100
committerRemi Collet <remi@php.net>2012-11-26 12:59:08 +0100
commit7751a6882485de64365661f4e7918535c3992982 (patch)
treed6c5dcbd4da6b0f10a60d968bea4bc40ca38593b
parent289bb339c9e722ff3017ec58fdef7300f39b8e6d (diff)
downloadphp-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.c39
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;
}