[njs] Fixed njs_json_append_string().
Dmitry Volyntsev
xeioex at nginx.com
Tue Feb 18 15:56:38 UTC 2020
details: https://hg.nginx.org/njs/rev/9b70f038abfa
branches:
changeset: 1331:9b70f038abfa
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Feb 18 18:42:37 2020 +0300
description:
Fixed njs_json_append_string().
diffstat:
src/njs_json.c | 91 ++++++++++++++++++++++++++-------------------------------
1 files changed, 42 insertions(+), 49 deletions(-)
diffs (128 lines):
diff -r aa9ac79f7fd9 -r 9b70f038abfa src/njs_json.c
--- a/src/njs_json.c Tue Feb 18 18:41:38 2020 +0300
+++ b/src/njs_json.c Tue Feb 18 18:42:37 2020 +0300
@@ -1545,37 +1545,50 @@ njs_json_append_value(njs_chb_t *chain,
static void
njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, char quote)
{
+ size_t size;
u_char c, *dst, *dst_end;
- size_t length;
+ njs_bool_t utf8;
const u_char *p, *end;
- njs_string_prop_t str;
-
- static char hex2char[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
- (void) njs_string_prop(&str, value);
-
- p = str.start;
- end = p + str.size;
- length = str.length;
-
- dst = njs_chb_reserve(chain, length + 2);
+ njs_string_prop_t string;
+
+ static char hex2char[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ (void) njs_string_prop(&string, value);
+
+ p = string.start;
+ end = p + string.size;
+ utf8 = (string.length != 0 && string.length != string.size);
+
+ size = njs_max(string.size + 2, 7);
+ dst = njs_chb_reserve(chain, string.size + 2);
if (njs_slow_path(dst == NULL)) {
return;
}
- dst_end = dst + length + 2;
+ dst_end = dst + size;
*dst++ = quote;
+ njs_chb_written(chain, 1);
while (p < end) {
-
- if (*p < ' '
- || *p == '\\'
- || (*p == '\"' && quote == '\"'))
+ if (njs_slow_path(dst_end <= dst + njs_length("\\uXXXX"))) {
+ size = njs_max(end - p + 1, 6);
+ dst = njs_chb_reserve(chain, size);
+ if (njs_slow_path(dst == NULL)) {
+ return;
+ }
+
+ dst_end = dst + size;
+ }
+
+ if (njs_slow_path(*p < ' '
+ || *p == '\\'
+ || (*p == '\"' && quote == '\"')))
{
c = (u_char) *p++;
*dst++ = '\\';
+ njs_chb_written(chain, 2);
switch (c) {
case '\\':
@@ -1605,44 +1618,24 @@ njs_json_append_string(njs_chb_t *chain,
*dst++ = '0';
*dst++ = hex2char[(c & 0xf0) >> 4];
*dst++ = hex2char[c & 0x0f];
- }
- }
-
- /*
- * Control characters less than space are encoded using 6 bytes
- * "\uXXXX". Checking there is at least 6 bytes of destination storage
- * space.
- */
-
- while (p < end && (dst_end - dst) > 6) {
- if (*p < ' ' || (*p == '\"' && quote == '\"') || *p == '\\') {
- break;
+ njs_chb_written(chain, 4);
}
- if (length != 0) {
- /* UTF-8 or ASCII string. */
- dst = njs_utf8_copy(dst, &p, end);
-
- } else {
- /* Byte string. */
- *dst++ = *p++;
- }
+ continue;
}
- if (dst_end - dst <= 6) {
- njs_chb_written(chain, dst - chain->last->pos);
-
- dst = njs_chb_reserve(chain, 64);
- if (njs_slow_path(dst == NULL)) {
- return;
- }
-
- dst_end = dst + 64;
+ if (utf8) {
+ /* UTF-8 string. */
+ dst = njs_utf8_copy(dst, &p, end);
+
+ } else {
+ /* Byte or ASCII string. */
+ *dst++ = *p++;
}
+
+ njs_chb_written(chain, dst - chain->last->pos);
}
- njs_chb_written(chain, dst - chain->last->pos);
-
njs_chb_append(chain, "e, 1);
}
More information about the nginx-devel
mailing list