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.
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);
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++ = '\\';
*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 = '"';