From dcfbf5ea8cc522126d868632e392886cf990cc0b Mon Sep 17 00:00:00 2001 From: Paul Arthur Date: Thu, 10 May 2018 14:41:49 +0000 Subject: [PATCH] [Fix] Fix vertical tab handling in libucl 626c7a170f73eb17efb084be49da3b30fe773a61 is an incomplete fix and emits invalid JSON. The vertical tab has a short escape in C but not JSON, so we should emit the long escape. (libucl won't choke on \v in UCL input but it doesn't properly round-trip: 'foo\vbar' will be parsed into 'foovbar'.) libucl has an option to escape strings during parsing, so I modified that in a similar fashion to 626c7a17. --- contrib/libucl/ucl_emitter_utils.c | 2 +- contrib/libucl/ucl_util.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/contrib/libucl/ucl_emitter_utils.c b/contrib/libucl/ucl_emitter_utils.c index 0831b3bf9..0447a53f7 100644 --- a/contrib/libucl/ucl_emitter_utils.c +++ b/contrib/libucl/ucl_emitter_utils.c @@ -125,7 +125,7 @@ ucl_elt_string_write_json (const char *str, size_t size, func->ucl_emitter_append_len ("\\f", 2, func->ud); break; case '\v': - func->ucl_emitter_append_len ("\\v", 2, func->ud); + func->ucl_emitter_append_len ("\\u000B", 6, func->ud); break; case '\\': func->ucl_emitter_append_len ("\\\\", 2, func->ud); diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c index 95878109b..1a3b34293 100644 --- a/contrib/libucl/ucl_util.c +++ b/contrib/libucl/ucl_util.c @@ -2208,14 +2208,23 @@ ucl_object_fromstring_common (const char *str, size_t len, enum ucl_string_flags obj->type = UCL_STRING; if (flags & UCL_STRING_ESCAPE) { for (p = start, escaped_len = 0; p < end; p ++, escaped_len ++) { - if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE)) { - escaped_len ++; + if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_WHITESPACE_UNSAFE)) { + switch (*p) { + case '\v': + escaped_len += 5; + break; + case ' ': + break; + default: + escaped_len ++; + break; + } } } dst = malloc (escaped_len + 1); if (dst != NULL) { for (p = start, d = dst; p < end; p ++, d ++) { - if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE)) { + if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_WHITESPACE_UNSAFE)) { switch (*p) { case '\n': *d++ = '\\'; @@ -2237,10 +2246,21 @@ ucl_object_fromstring_common (const char *str, size_t len, enum ucl_string_flags *d++ = '\\'; *d = 'f'; break; + case '\v': + *d++ = '\\'; + *d++ = 'u'; + *d++ = '0'; + *d++ = '0'; + *d++ = '0'; + *d = 'B'; + break; case '\\': *d++ = '\\'; *d = '\\'; break; + case ' ': + *d = ' '; + break; case '"': *d++ = '\\'; *d = '"'; -- 2.39.5