Browse Source

Escape control characters

Takeru Ohta 8 years ago
parent
commit
7d4041ad2b
2 changed files with 13 additions and 1 deletions
  1. 5 1
      src/jsone_encode.erl
  2. 8 0
      test/jsone_encode_tests.erl

+ 5 - 1
src/jsone_encode.erl

@@ -187,7 +187,11 @@ escape_string(<<$\f, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, N
 escape_string(<<$\n, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $n>>, Opt);
 escape_string(<<$\r, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $r>>, Opt);
 escape_string(<<$\t, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $t>>, Opt);
-escape_string(<<0:1, C:7, Str/binary>>, Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, C>>, Opt);
+escape_string(<<0:1, C:7, Str/binary>>, Nexts, Buf, Opt) ->
+    case C < 16#20 of
+        true  -> escape_string(Str, Nexts, <<Buf/binary, "\\u00", ?H8(C)>>, Opt);
+        false -> escape_string(Str, Nexts, <<Buf/binary, C>>, Opt)
+    end;
 escape_string(<<Ch/utf8, Str/binary>>,  Nexts, Buf, Opt = ?OPT{native_utf8 = false}) ->
     NewBuf = if
                  Ch =< 16#FFFF -> <<Buf/binary, $\\, $u, ?H16(Ch)>>;

+ 8 - 0
test/jsone_encode_tests.erl

@@ -82,6 +82,14 @@ encode_test_() ->
               ?assertEqual({ok, Expected}, jsone_encode:encode(Input)),
               ?assertEqual({ok, Expected}, jsone_encode:encode(Input, [native_utf8]))
       end},
+     {"string: contains control characters",
+      fun () ->
+              Ctrls    = lists:seq(16#00, 16#1F) -- [$\b, $\f, $\n, $\r, $\t],
+              Input    = list_to_binary(Ctrls),
+              Expected = list_to_binary([$", [io_lib:format("\\u00~2.16.0b", [C]) || C <- Ctrls], $"]),
+              ?assertEqual({ok, Expected}, jsone_encode:encode(Input)),
+              ?assertEqual({ok, Expected}, jsone_encode:encode(Input, [native_utf8]))
+      end},
      {"string: contains multi-byte (UTF-8 encoded) characters",
       fun () ->
               %% japanese