changeset 19657:ea87c511c6c8

lib: Added json_append_escaped_data() to escape non-NUL terminated input.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 28 Jan 2016 15:16:29 +0200
parents 5cc83e9cbfee
children 3cc8fb81e7f9
files src/lib/json-parser.c src/lib/json-parser.h src/lib/test-json-parser.c
diffstat 3 files changed, 58 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/json-parser.c	Thu Jan 28 15:05:38 2016 +0200
+++ b/src/lib/json-parser.c	Thu Jan 28 15:16:29 2016 +0200
@@ -632,37 +632,49 @@
 	return ret;
 }
 
+static void json_append_escaped_char(string_t *dest, unsigned char 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 (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++) {
-		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;
-		}
-	}
+	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]);
+}
--- a/src/lib/json-parser.h	Thu Jan 28 15:05:38 2016 +0200
+++ b/src/lib/json-parser.h	Thu Jan 28 15:16:29 2016 +0200
@@ -38,5 +38,7 @@
 
 /* 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
--- a/src/lib/test-json-parser.c	Thu Jan 28 15:05:38 2016 +0200
+++ b/src/lib/test-json-parser.c	Thu Jan 28 15:16:29 2016 +0200
@@ -173,9 +173,22 @@
 	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();
 }