Skip to content

Commit ccd0c69

Browse files
committed
bsb watcher serialiser: handle non-printable control characters when escaping JSON
1 parent 775f077 commit ccd0c69

File tree

1 file changed

+21
-42
lines changed

1 file changed

+21
-42
lines changed

compiler/ext/ext_json_noloc.ml

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,48 +33,27 @@ type t =
3333
| Obj of t Map_string.t
3434

3535
(** poor man's serialization *)
36-
let naive_escaped (unmodified_input : string) : string =
37-
let n = ref 0 in
38-
let len = String.length unmodified_input in
39-
for i = 0 to len - 1 do
40-
n :=
41-
!n
42-
+
43-
match String.unsafe_get unmodified_input i with
44-
| '\"' | '\\' | '\n' | '\t' | '\r' | '\b' -> 2
45-
| _ -> 1
46-
done;
47-
if !n = len then unmodified_input
48-
else
49-
let result = Bytes.create !n in
50-
n := 0;
51-
for i = 0 to len - 1 do
52-
let open Bytes in
53-
(match String.unsafe_get unmodified_input i with
54-
| ('\"' | '\\') as c ->
55-
unsafe_set result !n '\\';
56-
incr n;
57-
unsafe_set result !n c
58-
| '\n' ->
59-
unsafe_set result !n '\\';
60-
incr n;
61-
unsafe_set result !n 'n'
62-
| '\t' ->
63-
unsafe_set result !n '\\';
64-
incr n;
65-
unsafe_set result !n 't'
66-
| '\r' ->
67-
unsafe_set result !n '\\';
68-
incr n;
69-
unsafe_set result !n 'r'
70-
| '\b' ->
71-
unsafe_set result !n '\\';
72-
incr n;
73-
unsafe_set result !n 'b'
74-
| c -> unsafe_set result !n c);
75-
incr n
76-
done;
77-
Bytes.unsafe_to_string result
36+
let naive_escaped (text : string) : string =
37+
let ln = String.length text in
38+
let buf = Buffer.create ln in
39+
let rec loop i =
40+
if i < ln then (
41+
(match text.[i] with
42+
| '\012' -> Buffer.add_string buf "\\f"
43+
| '\\' -> Buffer.add_string buf "\\\\"
44+
| '"' -> Buffer.add_string buf "\\\""
45+
| '\n' -> Buffer.add_string buf "\\n"
46+
| '\b' -> Buffer.add_string buf "\\b"
47+
| '\r' -> Buffer.add_string buf "\\r"
48+
| '\t' -> Buffer.add_string buf "\\t"
49+
| c ->
50+
let code = Char.code c in
51+
if code < 0x20 then Printf.bprintf buf "\\u%04x" code
52+
else Buffer.add_char buf c);
53+
loop (i + 1))
54+
in
55+
loop 0;
56+
Buffer.contents buf
7857

7958
let quot x = "\"" ^ naive_escaped x ^ "\""
8059

0 commit comments

Comments
 (0)