From: Timo Sirainen Date: Thu, 28 Jan 2016 13:16:29 +0000 (+0200) Subject: lib: Added json_append_escaped_data() to escape non-NUL terminated input. X-Git-Tag: 2.2.22.rc1~263 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bb869cc24b24a8df84a43154c628785d6aee784c;p=thirdparty%2Fdovecot%2Fcore.git lib: Added json_append_escaped_data() to escape non-NUL terminated input. --- diff --git a/src/lib/json-parser.c b/src/lib/json-parser.c index 53d7973261..cf0eeaa119 100644 --- a/src/lib/json-parser.c +++ b/src/lib/json-parser.c @@ -632,37 +632,49 @@ int json_parse_next_stream(struct json_parser *parser, return ret; } -void json_append_escaped(string_t *dest, const char *src) +static void json_append_escaped_char(string_t *dest, unsigned char src) { - for (; *src != '\0'; src++) { - switch (*src) { - case '\b': - str_append(dest, "\\b"); - break; - case '\f': - str_append(dest, "\\f"); - break; - case '\n': - str_append(dest, "\\n"); - break; - case '\r': - str_append(dest, "\\r"); - break; - case '\t': - str_append(dest, "\\t"); - break; - case '"': - str_append(dest, "\\\""); - break; - case '\\': - str_append(dest, "\\\\"); - break; - default: - if ((unsigned char)*src < 32) - str_printfa(dest, "\\u%04x", *src); - else - str_append_c(dest, *src); - break; - } + switch (src) { + case '\b': + str_append(dest, "\\b"); + break; + case '\f': + str_append(dest, "\\f"); + break; + case '\n': + str_append(dest, "\\n"); + break; + case '\r': + str_append(dest, "\\r"); + break; + case '\t': + str_append(dest, "\\t"); + break; + case '"': + str_append(dest, "\\\""); + break; + case '\\': + str_append(dest, "\\\\"); + break; + default: + if (src < 32) + str_printfa(dest, "\\u%04x", src); + else + str_append_c(dest, src); + break; } } + +void json_append_escaped(string_t *dest, const char *src) +{ + for (; *src != '\0'; src++) + json_append_escaped_char(dest, *src); +} + +void json_append_escaped_data(string_t *dest, const unsigned char *src, size_t size) +{ + unsigned int i; + + for (i = 0; i < size; i++) + json_append_escaped_char(dest, src[i]); +} diff --git a/src/lib/json-parser.h b/src/lib/json-parser.h index d78501d6a4..e16f5e1b32 100644 --- a/src/lib/json-parser.h +++ b/src/lib/json-parser.h @@ -38,5 +38,7 @@ int json_parse_next_stream(struct json_parser *parser, /* Append data to already opened JSON string. src should be valid UTF-8 data. */ void json_append_escaped(string_t *dest, const char *src); +/* Same as json_append_escaped(), but append non-\0 terminated input. */ +void json_append_escaped_data(string_t *dest, const unsigned char *src, size_t size); #endif diff --git a/src/lib/test-json-parser.c b/src/lib/test-json-parser.c index 8f2edb8377..d2b78ec377 100644 --- a/src/lib/test-json-parser.c +++ b/src/lib/test-json-parser.c @@ -173,9 +173,22 @@ static void test_json_append_escaped(void) test_end(); } +static void test_json_append_escaped_data(void) +{ + static const unsigned char test_input[] = + "\b\f\r\n\t\"\\\000\001\002-\xC3\xA4"; + string_t *str = t_str_new(32); + + test_begin("json_append_escaped()"); + json_append_escaped_data(str, test_input, sizeof(test_input)-1); + test_assert(strcmp(str_c(str), "\\b\\f\\r\\n\\t\\\"\\\\\\u0000\\u0001\\u0002-\xC3\xA4") == 0); + test_end(); +} + void test_json_parser(void) { test_json_parser_success(TRUE); test_json_parser_success(FALSE); test_json_append_escaped(); + test_json_append_escaped_data(); }