escape strings and keys in the encoder

This commit is contained in:
alisdair sullivan 2012-03-15 22:56:21 -07:00
parent 97a7d295f1
commit 8dafdb32b3
2 changed files with 25 additions and 10 deletions

View file

@ -53,8 +53,8 @@ start(Term, {Handler, State}, Opts) ->
Handler:handle_event(end_json, value(Term, {Handler, State}, Opts)). Handler:handle_event(end_json, value(Term, {Handler, State}, Opts)).
value(String, {Handler, State}, _Opts) when is_binary(String) -> value(String, {Handler, State}, Opts) when is_binary(String) ->
Handler:handle_event({string, String}, State); Handler:handle_event({string, escape(String, {Handler, State}, Opts)}, State);
value(Float, {Handler, State}, _Opts) when is_float(Float) -> value(Float, {Handler, State}, _Opts) when is_float(Float) ->
Handler:handle_event({float, Float}, State); Handler:handle_event({float, Float}, State);
value(Int, {Handler, State}, _Opts) when is_integer(Int) -> value(Int, {Handler, State}, _Opts) when is_integer(Int) ->
@ -78,9 +78,18 @@ list_or_object(List, {Handler, State}, Opts) ->
object([{Key, Value}|Rest], {Handler, State}, Opts) -> object([{Key, Value}|Rest], {Handler, State}, Opts) ->
object(Rest, {Handler, object(
value(Value, {Handler, Handler:handle_event({key, fix_key(Key)}, State)}, Opts) Rest,
}, Opts); {
Handler,
value(
Value,
{Handler, Handler:handle_event({key, escape(fix_key(Key), {Handler, State}, Opts)}, State)},
Opts
)
},
Opts
);
object([], {Handler, State}, _Opts) -> Handler:handle_event(end_object, State); object([], {Handler, State}, _Opts) -> Handler:handle_event(end_object, State);
object(Term, Handler, Opts) -> ?error([Term, Handler, Opts]). object(Term, Handler, Opts) -> ?error([Term, Handler, Opts]).
@ -91,8 +100,14 @@ list([], {Handler, State}, _Opts) -> Handler:handle_event(end_array, State);
list(Term, Handler, Opts) -> ?error([Term, Handler, Opts]). list(Term, Handler, Opts) -> ?error([Term, Handler, Opts]).
fix_key(Key) when is_binary(Key) -> Key; fix_key(Key) when is_atom(Key) -> fix_key(atom_to_binary(Key, utf8));
fix_key(Key) when is_atom(Key) -> atom_to_binary(Key, utf8). fix_key(Key) when is_binary(Key) -> Key.
escape(String, Handler, Opts) ->
try jsx_utils:json_escape(String, Opts)
catch error:badarg -> erlang:error(badarg, [String, Handler, Opts])
end.
-ifdef(TEST). -ifdef(TEST).

View file

@ -97,7 +97,7 @@ json_escape(<<$\t, Rest/binary>>, Opts, Acc) ->
json_escape(<<C/utf8, Rest/binary>>, Opts, Acc) when C >= 0, C < $\s -> json_escape(<<C/utf8, Rest/binary>>, Opts, Acc) when C >= 0, C < $\s ->
json_escape(Rest, json_escape(Rest,
Opts, Opts,
<<Acc/binary, (unicode:characters_to_binary(json_escape_sequence(C)))/binary>> <<Acc/binary, (json_escape_sequence(C))/binary>>
); );
%% escape forward slashes -- optionally -- to faciliate microsoft's retarded %% escape forward slashes -- optionally -- to faciliate microsoft's retarded
%% date format %% date format
@ -108,7 +108,7 @@ json_escape(<<C/utf8, Rest/binary>>, Opts, Acc)
when C == 16#2028; C == 16#2029 -> when C == 16#2028; C == 16#2029 ->
json_escape(Rest, json_escape(Rest,
Opts, Opts,
<<Acc/binary, (unicode:characters_to_binary(json_escape_sequence(C)))/binary>> <<Acc/binary, (json_escape_sequence(C))/binary>>
); );
%% any other legal codepoint %% any other legal codepoint
json_escape(<<C/utf8, Rest/binary>>, Opts, Acc) -> json_escape(<<C/utf8, Rest/binary>>, Opts, Acc) ->
@ -122,7 +122,7 @@ json_escape(Rest, Opts, Acc) ->
%% convert a codepoint to it's \uXXXX equiv. %% convert a codepoint to it's \uXXXX equiv.
json_escape_sequence(X) -> json_escape_sequence(X) ->
<<A:4, B:4, C:4, D:4>> = <<X:16>>, <<A:4, B:4, C:4, D:4>> = <<X:16>>,
[$\\, $u, (to_hex(A)), (to_hex(B)), (to_hex(C)), (to_hex(D))]. unicode:characters_to_binary([$\\, $u, (to_hex(A)), (to_hex(B)), (to_hex(C)), (to_hex(D))]).
to_hex(10) -> $a; to_hex(10) -> $a;