summaryrefslogtreecommitdiff
path: root/ext/json/json_encoder.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-06-13 12:20:14 +0300
committerDmitry Stogov <dmitry@zend.com>2017-06-13 12:20:14 +0300
commit1385784f54de9b620c82fd881f563b99ccff0956 (patch)
treefd86ff859a862290749793d7afa7511e3af3463a /ext/json/json_encoder.c
parentb1fedd88db1de8a57e12e0f474e875efc9f1dec1 (diff)
downloadphp-git-1385784f54de9b620c82fd881f563b99ccff0956.tar.gz
Fixed performance degradaton introduced in f6ac96b
Diffstat (limited to 'ext/json/json_encoder.c')
-rw-r--r--ext/json/json_encoder.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c
index 6b55a83ca1..f0d02bfbd0 100644
--- a/ext/json/json_encoder.c
+++ b/ext/json/json_encoder.c
@@ -252,7 +252,7 @@ static int php_json_escape_string(
{
int status;
unsigned int us;
- size_t prev_pos, pos, checkpoint;
+ size_t pos, checkpoint;
if (len == 0) {
smart_str_appendl(buf, "\"\"", 2);
@@ -283,27 +283,31 @@ static int php_json_escape_string(
smart_str_appendc(buf, '"');
do {
- prev_pos = pos;
- us = php_next_utf8_char((unsigned char *)s, len, &pos, &status);
- /* check whether UTF8 character is correct */
- if (status != SUCCESS) {
- if (buf->s) {
- ZSTR_LEN(buf->s) = checkpoint;
- }
- encoder->error_code = PHP_JSON_ERROR_UTF8;
- if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
- smart_str_appendl(buf, "null", 4);
+ us = (unsigned char)s[pos];
+ if (us >= 0x80) {
+ size_t prev_pos = pos;
+
+ us = php_next_utf8_char((unsigned char *)s, len, &pos, &status);
+
+ /* check whether UTF8 character is correct */
+ if (status != SUCCESS) {
+ if (buf->s) {
+ ZSTR_LEN(buf->s) = checkpoint;
+ }
+ encoder->error_code = PHP_JSON_ERROR_UTF8;
+ if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
+ smart_str_appendl(buf, "null", 4);
+ }
+ return FAILURE;
}
- return FAILURE;
- }
- if (us >= 0x80 && (!(options & PHP_JSON_UNESCAPED_UNICODE) || (unsigned char)s[prev_pos] == 0xE2)) {
+
/* Escape U+2028/U+2029 line terminators, UNLESS both
JSON_UNESCAPED_UNICODE and
JSON_UNESCAPED_LINE_TERMINATORS were provided */
if ((options & PHP_JSON_UNESCAPED_UNICODE)
- && ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS)
+ && ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS)
|| us < 0x2028 || us > 0x2029)) {
- smart_str_appendl(buf, &s[prev_pos], 3);
+ smart_str_appendl(buf, s + prev_pos, pos - prev_pos);
continue;
}
/* From http://en.wikipedia.org/wiki/UTF16 */
@@ -325,6 +329,8 @@ static int php_json_escape_string(
smart_str_appendc(buf, digits[(us & 0xf0) >> 4]);
smart_str_appendc(buf, digits[(us & 0xf)]);
} else {
+ pos++;
+
switch (us) {
case '"':
if (options & PHP_JSON_HEX_QUOT) {
@@ -400,7 +406,7 @@ static int php_json_escape_string(
default:
if (us >= ' ') {
- smart_str_appendl(buf, s + prev_pos, pos - prev_pos);
+ smart_str_appendc(buf, (unsigned char) us);
} else {
smart_str_appendl(buf, "\\u00", sizeof("\\u00")-1);
smart_str_appendc(buf, digits[(us & 0xf0) >> 4]);