From 302fba9cbb31ffc523bf10a1ce705040194c289d Mon Sep 17 00:00:00 2001 From: Krzysztof Gabis Date: Mon, 26 Nov 2018 20:12:16 +0100 Subject: [PATCH] Makes escaping slashes when serializing JSON optional (adds json_set_escape_slashes() function) Issues #20 #34 #90 --- parson.c | 14 +++++++++++++- parson.h | 4 ++++ tests.c | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/parson.c b/parson.c index afbfd2d..ca1652b 100644 --- a/parson.c +++ b/parson.c @@ -62,6 +62,8 @@ static JSON_Malloc_Function parson_malloc = malloc; static JSON_Free_Function parson_free = free; +static int parson_escape_slashes = 1; + #define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */ /* Type definitions */ @@ -1018,7 +1020,6 @@ static int json_serialize_string(const char *string, char *buf) { switch (c) { case '\"': APPEND_STRING("\\\""); break; case '\\': APPEND_STRING("\\\\"); break; - case '/': APPEND_STRING("\\/"); break; /* to make json embeddable in xml\/html */ case '\b': APPEND_STRING("\\b"); break; case '\f': APPEND_STRING("\\f"); break; case '\n': APPEND_STRING("\\n"); break; @@ -1056,6 +1057,13 @@ static int json_serialize_string(const char *string, char *buf) { case '\x1d': APPEND_STRING("\\u001d"); break; case '\x1e': APPEND_STRING("\\u001e"); break; case '\x1f': APPEND_STRING("\\u001f"); break; + case '/': + if (parson_escape_slashes) { + APPEND_STRING("\\/"); /* to make json embeddable in xml\/html */ + } else { + APPEND_STRING("/"); + } + break; default: if (buf != NULL) { buf[0] = c; @@ -2044,3 +2052,7 @@ void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Fu parson_malloc = malloc_fun; parson_free = free_fun; } + +void json_set_escape_slashes(int escape_slashes) { + parson_escape_slashes = escape_slashes; +} diff --git a/parson.h b/parson.h index f97f711..25cb00e 100644 --- a/parson.h +++ b/parson.h @@ -60,6 +60,10 @@ typedef void (*JSON_Free_Function)(void *); from stdlib will be used for all allocations */ void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun); +/* Sets if slashes should be escaped or not when serializing JSON. By default slashes are escaped. + This function sets a global setting and is not thread safe. */ +void json_set_escape_slashes(int escape_slashes); + /* Parses first JSON value in a file, returns NULL in case of error */ JSON_Value * json_parse_file(const char *filename); diff --git a/tests.c b/tests.c index 3f4f8c2..ec9bfa2 100644 --- a/tests.c +++ b/tests.c @@ -49,6 +49,7 @@ void test_suite_7(void); /* Test schema validation */ void test_suite_8(void); /* Test serialization */ void test_suite_9(void); /* Test serialization (pretty) */ void test_suite_10(void); /* Testing for memory leaks */ +void test_suite_11(void); /* Additional things that require testing */ void print_commits_info(const char *username, const char *repo); void persistence_example(void); @@ -80,6 +81,8 @@ int main() { test_suite_8(); test_suite_9(); test_suite_10(); + test_suite_11(); + printf("Tests failed: %d\n", tests_failed); printf("Tests passed: %d\n", tests_passed); return 0; @@ -538,6 +541,24 @@ void test_suite_10(void) { TEST(malloc_count == 0); } +void test_suite_11() { + const char * array_with_slashes = "[\"a/b/c\"]"; + const char * array_with_escaped_slashes = "[\"a\\/b\\/c\"]"; + char *serialized = NULL; + JSON_Value *value = json_parse_string(array_with_slashes); + + serialized = json_serialize_to_string(value); + TEST(STREQ(array_with_escaped_slashes, serialized)); + + json_set_escape_slashes(0); + serialized = json_serialize_to_string(value); + TEST(STREQ(array_with_slashes, serialized)); + + json_set_escape_slashes(1); + serialized = json_serialize_to_string(value); + TEST(STREQ(array_with_escaped_slashes, serialized)); +} + void print_commits_info(const char *username, const char *repo) { JSON_Value *root_value; JSON_Array *commits;