]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Fix vertical tab handling in libucl
authorPaul Arthur <paul.arthur@flowerysong.com>
Thu, 10 May 2018 14:41:49 +0000 (14:41 +0000)
committerPaul Arthur <paul.arthur@flowerysong.com>
Thu, 10 May 2018 16:44:28 +0000 (16:44 +0000)
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
contrib/libucl/ucl_util.c

index 0831b3bf9859b58b5e157499cd57cba04e8b2195..0447a53f71899ead5f7eea95873902d2ca04cab8 100644 (file)
@@ -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);
index 95878109b6364425baece253c4ac086002828667..1a3b34293dd436ee04ab7132b7544d003741e027 100644 (file)
@@ -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 = '"';