From 973769d74433de3c56c4ffdf4f343cb35d98e4f7 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Tue, 2 Apr 2019 13:09:48 +0300 Subject: [PATCH 1/2] lib: json - Escape invalid UTF-8 as unicode bytes This prevents dovecot from crashing if invalid UTF-8 input is given. --- src/lib/json-parser.c | 12 ++++++++---- src/lib/test-json-parser.c | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lib/json-parser.c b/src/lib/json-parser.c index 677091d64..e7846a329 100644 --- a/src/lib/json-parser.c +++ b/src/lib/json-parser.c @@ -803,9 +803,13 @@ void json_append_escaped_data(string_t *dest, const unsigned char *src, size_t s for (i = 0; i < size;) { bytes = uni_utf8_get_char_n(src+i, size-i, &chr); - /* refuse to add invalid data */ - i_assert(bytes > 0 && uni_is_valid_ucs4(chr)); - json_append_escaped_ucs4(dest, chr); - i += bytes; + if (bytes > 0 && uni_is_valid_ucs4(chr)) { + json_append_escaped_ucs4(dest, chr); + i += bytes; + } else { + str_append_data(dest, UNICODE_REPLACEMENT_CHAR_UTF8, + UTF8_REPLACEMENT_CHAR_LEN); + i++; + } } } diff --git a/src/lib/test-json-parser.c b/src/lib/test-json-parser.c index bae6fb202..9ce1e489b 100644 --- a/src/lib/test-json-parser.c +++ b/src/lib/test-json-parser.c @@ -267,20 +267,20 @@ static void test_json_append_escaped(void) string_t *str = t_str_new(32); test_begin("json_append_escaped()"); - json_append_escaped(str, "\b\f\r\n\t\"\\\001\002-\xC3\xA4\xf0\x90\x90\xb7"); - test_assert(strcmp(str_c(str), "\\b\\f\\r\\n\\t\\\"\\\\\\u0001\\u0002-\\u00e4\\ud801\\udc37") == 0); + json_append_escaped(str, "\b\f\r\n\t\"\\\001\002-\xC3\xA4\xf0\x90\x90\xb7\xff"); + test_assert(strcmp(str_c(str), "\\b\\f\\r\\n\\t\\\"\\\\\\u0001\\u0002-\\u00e4\\ud801\\udc37" UNICODE_REPLACEMENT_CHAR_UTF8) == 0); 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\xf0\x90\x90\xb7"; + "\b\f\r\n\t\"\\\000\001\002-\xC3\xA4\xf0\x90\x90\xb7\xff"; 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-\\u00e4\\ud801\\udc37") == 0); + test_assert(strcmp(str_c(str), "\\b\\f\\r\\n\\t\\\"\\\\\\u0000\\u0001\\u0002-\\u00e4\\ud801\\udc37" UNICODE_REPLACEMENT_CHAR_UTF8) == 0); test_end(); } -- 2.11.0