63 lines
2.4 KiB
Diff
63 lines
2.4 KiB
Diff
|
|
From 973769d74433de3c56c4ffdf4f343cb35d98e4f7 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Aki Tuomi <aki.tuomi@open-xchange.com>
|
||
|
|
Date: Tue, 2 Apr 2019 13:09:48 +0300
|
||
|
|
Subject: [PATCH] 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 677091d649..e7846a329f 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 bae6fb202b..9ce1e489ba 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();
|
||
|
|
}
|