]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 28 Jan 2016 13:16:29 +0000 (15:16 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 28 Jan 2016 13:16:29 +0000 (15:16 +0200)
src/lib/json-parser.c
src/lib/json-parser.h
src/lib/test-json-parser.c

index 53d7973261ce4b176d1bca19dcd46cafad5ba1ec..cf0eeaa119fa1060ac1dd15c06784a1a4855af9f 100644 (file)
@@ -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]);
+}
index d78501d6a48f163f2fc65d23edb20efa237bce1d..e16f5e1b329e4cdf2156ad0ee909ccdda4e19de2 100644 (file)
@@ -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
index 8f2edb83774b9f88d7698cb81beb67f1c5bf690d..d2b78ec377aaa4200f568f4f85f67cc34b861e27 100644 (file)
@@ -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();
 }