Skip to content

Commit e3baa23

Browse files
committed
wip1
1 parent ef72f33 commit e3baa23

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

ext/json/json_encoder.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -602,17 +602,23 @@ zend_result php_json_escape_string(
602602
pos++;
603603
len--;
604604
} else {
605-
if (pos) {
606-
smart_str_appendl(buf, s, pos);
607-
s += pos;
608-
pos = 0;
609-
}
610605
if (UNEXPECTED(us >= 0x80)) {
611606
zend_result status;
612-
us = php_next_utf8_char((unsigned char *)s, len, &pos, &status);
607+
size_t pos_old = pos;
608+
const char *cur = s+pos;
609+
pos = 0;
610+
us = php_next_utf8_char((unsigned char *)cur, len, &pos, &status);
611+
pos += pos_old;
612+
len -= pos - pos_old;
613613

614614
/* check whether UTF8 character is correct */
615615
if (UNEXPECTED(status != SUCCESS)) {
616+
if (pos_old && (options & (PHP_JSON_INVALID_UTF8_IGNORE|PHP_JSON_INVALID_UTF8_SUBSTITUTE))) {
617+
smart_str_appendl(buf, s, pos_old);
618+
s += pos;
619+
pos = 0;
620+
}
621+
616622
if (options & PHP_JSON_INVALID_UTF8_IGNORE) {
617623
/* ignore invalid UTF8 character */
618624
} else if (options & PHP_JSON_INVALID_UTF8_SUBSTITUTE) {
@@ -637,8 +643,14 @@ zend_result php_json_escape_string(
637643
} else if ((options & PHP_JSON_UNESCAPED_UNICODE)
638644
&& ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS)
639645
|| us < 0x2028 || us > 0x2029)) {
640-
smart_str_appendl(buf, s, pos);
646+
/* No need to emit any bytes, just move the cursor. */
641647
} else {
648+
if (pos_old) {
649+
smart_str_appendl(buf, s, pos_old);
650+
}
651+
s += pos;
652+
pos = 0;
653+
642654
/* From http://en.wikipedia.org/wiki/UTF16 */
643655
if (us >= 0x10000) {
644656
unsigned int next_us;
@@ -663,10 +675,12 @@ zend_result php_json_escape_string(
663675
dst[4] = digits[(us >> 4) & 0xf];
664676
dst[5] = digits[us & 0xf];
665677
}
666-
s += pos;
667-
len -= pos;
668-
pos = 0;
669678
} else {
679+
if (pos) {
680+
smart_str_appendl(buf, s, pos);
681+
s += pos;
682+
pos = 0;
683+
}
670684
s++;
671685
switch (us) {
672686
case '\b':

0 commit comments

Comments
 (0)