From 8cbd3cde98df5f20794ec055df3fedb988d5c1ce Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 3 Jun 2021 07:50:41 -0700 Subject: json: fix quasiquote print-read consistency issue * lib.c (out_json_rec): When printing keys that might be potentially quasiquoted symbols that look like ~abc, we must avoid the condensed {~abc:~def} style. This is because abd:~def looks like a single symbol, where abc is a package qualifier. To be safe and readable at the same time, we add spaces whenever either the key or the value are conses, indicating non-JSON syntax. Spaces are added on both sides of the colon, and also after the preceding comma, if there is a previous item. --- lib.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/lib.c b/lib.c index d3ae1425..a34b16fa 100644 --- a/lib.c +++ b/lib.c @@ -12701,11 +12701,18 @@ static void out_json_rec(val obj, val out, struct strm_ctx *ctx) save_indent = inc_indent(out, zero); for (iter = cddr(obj), next = nil; iter; iter = next) { val pair = car(iter); - next = cdr(iter); - out_json_rec(car(pair), out, ctx); - put_char(chr(':'), out); - out_json_rec(cadr(pair), out, ctx); - if (next) { + val k = car(pair), v = cadr(pair); + if (consp(k) || consp(v)) { + if (next) + put_char(chr(' '), out); + out_json_rec(k, out, ctx); + put_string(lit(" : "), out); + } else { + out_json_rec(k, out, ctx); + put_char(chr(':'), out); + } + out_json_rec(v, out, ctx); + if ((next = cdr(iter)) != 0) { put_char(chr(','), out); if (width_check(out, nil)) force_br = 1; @@ -12791,11 +12798,18 @@ static void out_json_rec(val obj, val out, struct strm_ctx *ctx) put_char(chr('{'), out); save_indent = inc_indent(out, zero); for (next = nil, cell = hash_iter_next(&hi); cell; cell = next) { - next = hash_iter_next(&hi); - out_json_rec(car(cell), out, ctx); - put_char(chr(':'), out); - out_json_rec(cdr(cell), out, ctx); - if (next) { + val k = car(cell), v = cdr(cell); + if (consp(k) || consp(v)) { + if (next) + put_char(chr(' '), out); + out_json_rec(k, out, ctx); + put_string(lit(" : "), out); + } else { + out_json_rec(k, out, ctx); + put_char(chr(':'), out); + } + out_json_rec(v, out, ctx); + if ((next = hash_iter_next(&hi)) != 0) { put_char(chr(','), out); if (width_check(out, nil)) force_br = 1; -- cgit v1.2.3