]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: json - Escape invalid UTF-8 as unicode bytes
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 2 Apr 2019 10:09:48 +0000 (13:09 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 5 Apr 2019 07:36:41 +0000 (10:36 +0300)
This prevents dovecot from crashing if invalid UTF-8 input
is given.

src/lib/json-parser.c
src/lib/test-json-parser.c

index 9e0a871325ae7009b1de5944058ad75605505a3e..7a14a0bc8789b8e29f2ab518e558b5159f441d12 100644 (file)
@@ -821,9 +821,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++;
+               }
        }
 }
index d130d79f4db49624ab3bb7e341d968b458d67639..199be39e773f0e4d0077a15cb313907b65febdbd 100644 (file)
@@ -374,20 +374,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();
 }