Skip to content

Commit 1385784

Browse files
committed
Fixed performance degradaton introduced in f6ac96b
1 parent b1fedd8 commit 1385784

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

ext/json/json_encoder.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static int php_json_escape_string(
252252
{
253253
int status;
254254
unsigned int us;
255-
size_t prev_pos, pos, checkpoint;
255+
size_t pos, checkpoint;
256256

257257
if (len == 0) {
258258
smart_str_appendl(buf, "\"\"", 2);
@@ -283,27 +283,31 @@ static int php_json_escape_string(
283283
smart_str_appendc(buf, '"');
284284

285285
do {
286-
prev_pos = pos;
287-
us = php_next_utf8_char((unsigned char *)s, len, &pos, &status);
288-
/* check whether UTF8 character is correct */
289-
if (status != SUCCESS) {
290-
if (buf->s) {
291-
ZSTR_LEN(buf->s) = checkpoint;
292-
}
293-
encoder->error_code = PHP_JSON_ERROR_UTF8;
294-
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
295-
smart_str_appendl(buf, "null", 4);
286+
us = (unsigned char)s[pos];
287+
if (us >= 0x80) {
288+
size_t prev_pos = pos;
289+
290+
us = php_next_utf8_char((unsigned char *)s, len, &pos, &status);
291+
292+
/* check whether UTF8 character is correct */
293+
if (status != SUCCESS) {
294+
if (buf->s) {
295+
ZSTR_LEN(buf->s) = checkpoint;
296+
}
297+
encoder->error_code = PHP_JSON_ERROR_UTF8;
298+
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
299+
smart_str_appendl(buf, "null", 4);
300+
}
301+
return FAILURE;
296302
}
297-
return FAILURE;
298-
}
299-
if (us >= 0x80 && (!(options & PHP_JSON_UNESCAPED_UNICODE) || (unsigned char)s[prev_pos] == 0xE2)) {
303+
300304
/* Escape U+2028/U+2029 line terminators, UNLESS both
301305
JSON_UNESCAPED_UNICODE and
302306
JSON_UNESCAPED_LINE_TERMINATORS were provided */
303307
if ((options & PHP_JSON_UNESCAPED_UNICODE)
304-
&& ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS)
308+
&& ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS)
305309
|| us < 0x2028 || us > 0x2029)) {
306-
smart_str_appendl(buf, &s[prev_pos], 3);
310+
smart_str_appendl(buf, s + prev_pos, pos - prev_pos);
307311
continue;
308312
}
309313
/* From http://en.wikipedia.org/wiki/UTF16 */
@@ -325,6 +329,8 @@ static int php_json_escape_string(
325329
smart_str_appendc(buf, digits[(us & 0xf0) >> 4]);
326330
smart_str_appendc(buf, digits[(us & 0xf)]);
327331
} else {
332+
pos++;
333+
328334
switch (us) {
329335
case '"':
330336
if (options & PHP_JSON_HEX_QUOT) {
@@ -400,7 +406,7 @@ static int php_json_escape_string(
400406

401407
default:
402408
if (us >= ' ') {
403-
smart_str_appendl(buf, s + prev_pos, pos - prev_pos);
409+
smart_str_appendc(buf, (unsigned char) us);
404410
} else {
405411
smart_str_appendl(buf, "\\u00", sizeof("\\u00")-1);
406412
smart_str_appendc(buf, digits[(us & 0xf0) >> 4]);

0 commit comments

Comments
 (0)