fix bug that prevented escaping of quotes in dirty strings when preceeded by an even number of forward slashes

This commit is contained in:
alisdair sullivan 2013-03-06 23:15:19 -08:00
parent 58a9a5110f
commit 292c692191

View file

@ -428,8 +428,6 @@ string(<<90, Rest/binary>>, Handler, Acc, Stack, Config) ->
string(Rest, Handler, acc_seq(Acc, 90), Stack, Config); string(Rest, Handler, acc_seq(Acc, 90), Stack, Config);
string(<<91, Rest/binary>>, Handler, Acc, Stack, Config) -> string(<<91, Rest/binary>>, Handler, Acc, Stack, Config) ->
string(Rest, Handler, acc_seq(Acc, 91), Stack, Config); string(Rest, Handler, acc_seq(Acc, 91), Stack, Config);
string(<<?rsolidus/utf8, Rest/binary>>, Handler, Acc, Stack, Config) ->
unescape(Rest, Handler, Acc, Stack, Config);
string(<<93, Rest/binary>>, Handler, Acc, Stack, Config) -> string(<<93, Rest/binary>>, Handler, Acc, Stack, Config) ->
string(Rest, Handler, acc_seq(Acc, 93), Stack, Config); string(Rest, Handler, acc_seq(Acc, 93), Stack, Config);
string(<<94, Rest/binary>>, Handler, Acc, Stack, Config) -> string(<<94, Rest/binary>>, Handler, Acc, Stack, Config) ->
@ -500,8 +498,18 @@ string(<<126, Rest/binary>>, Handler, Acc, Stack, Config) ->
string(Rest, Handler, acc_seq(Acc, 126), Stack, Config); string(Rest, Handler, acc_seq(Acc, 126), Stack, Config);
string(<<127, Rest/binary>>, Handler, Acc, Stack, Config) -> string(<<127, Rest/binary>>, Handler, Acc, Stack, Config) ->
string(Rest, Handler, acc_seq(Acc, 127), Stack, Config); string(Rest, Handler, acc_seq(Acc, 127), Stack, Config);
string(<<?rsolidus, ?doublequote, Rest/binary>>, Handler, Acc, [single_quote|_] = Stack, Config=#config{dirty_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, [?rsolidus, ?doublequote]), Stack, Config);
string(<<?rsolidus, ?doublequote, Rest/binary>>, Handler, Acc, Stack, Config=#config{dirty_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, ?doublequote), Stack, Config);
string(<<?rsolidus, ?singlequote, Rest/binary>>, Handler, Acc, [single_quote|_] = Stack, Config=#config{dirty_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, ?singlequote), Stack, Config);
string(<<?rsolidus>>, Handler, Acc, Stack, Config=#config{dirty_strings=true}) ->
incomplete(string, <<?rsolidus>>, Handler, Acc, Stack, Config);
string(<<C, Rest/binary>>, Handler, Acc, Stack, Config=#config{dirty_strings=true}) -> string(<<C, Rest/binary>>, Handler, Acc, Stack, Config=#config{dirty_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, C), Stack, Config); string(Rest, Handler, acc_seq(Acc, C), Stack, Config);
string(<<?rsolidus/utf8, Rest/binary>>, Handler, Acc, Stack, Config) ->
unescape(Rest, Handler, Acc, Stack, Config);
string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#20, X < 16#2028 -> string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#20, X < 16#2028 ->
string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X == 16#2028; X == 16#2029 -> string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X == 16#2028; X == 16#2029 ->
@ -613,12 +621,6 @@ strip_continuations(Rest, Handler, Acc, Stack, Config, _) ->
%% this all gets really gross and should probably eventually be folded into %% this all gets really gross and should probably eventually be folded into
%% but for now it fakes being part of string on incompletes and errors %% but for now it fakes being part of string on incompletes and errors
unescape(<<?doublequote, Rest/binary>>, Handler, Acc, Stack, Config=#config{dirty_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, ?doublequote), Stack, Config);
unescape(<<?singlequote, Rest/binary>>, Handler, Acc, Stack, Config=#config{dirty_strings=true, single_quoted_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, ?singlequote), Stack, Config);
unescape(<<C, Rest/binary>>, Handler, Acc, Stack, Config=#config{dirty_strings=true}) ->
string(Rest, Handler, acc_seq(Acc, [?rsolidus, C]), Stack, Config);
unescape(<<$b, Rest/binary>>, Handler, Acc, Stack, Config) -> unescape(<<$b, Rest/binary>>, Handler, Acc, Stack, Config) ->
string(Rest, Handler, acc_seq(Acc, maybe_replace($\b, Config)), Stack, Config); string(Rest, Handler, acc_seq(Acc, maybe_replace($\b, Config)), Stack, Config);
unescape(<<$f, Rest/binary>>, Handler, Acc, Stack, Config) -> unescape(<<$f, Rest/binary>>, Handler, Acc, Stack, Config) ->
@ -1343,29 +1345,33 @@ clean_string_test_() ->
lists:duplicate(length(extended_noncharacters()), [{string, <<16#fffd/utf8>>}, end_json]), lists:duplicate(length(extended_noncharacters()), [{string, <<16#fffd/utf8>>}, end_json]),
lists:map(fun(Codepoint) -> decode(Codepoint, [replaced_bad_utf8]) end, extended_noncharacters()) lists:map(fun(Codepoint) -> decode(Codepoint, [replaced_bad_utf8]) end, extended_noncharacters())
)}, )},
{"dirty strings", ?_assertEqual( {"dirty \\uwxyz", ?_assertEqual(
lists:map( [{string, <<"\\uwxyz">>}, end_json],
fun(Result) -> [{string, Result}, end_json] end, decode(<<34, "\\uwxyz", 34>>, [dirty_strings])
[ )},
<<"\\uwxyz">>, {"dirty \\x23", ?_assertEqual(
<<"\\x23">>, [{string, <<"\\x23">>}, end_json],
<<0>>, decode(<<34, "\\x23", 34>>, [dirty_strings])
<<0, ?doublequote, 0>>, )},
<<237, 160, 128>>, {"dirty 0", ?_assertEqual(
<<244, 143, 191, 191>> [{string, <<0>>}, end_json],
] decode(<<34, 0, 34>>, [dirty_strings])
), )},
lists:map( {"dirty 0\"0", ?_assertEqual(
fun(JSON) -> decode(JSON, [dirty_strings]) end, [{string, <<0, ?doublequote, 0>>}, end_json],
[ decode(<<34, 0, ?rsolidus, ?doublequote, 0, 34>>, [dirty_strings])
<<34, "\\uwxyz", 34>>, )},
<<34, "\\x23", 34>>, {"dirty 0\"0", ?_assertEqual(
<<34, 0, 34>>, [{string, <<0, ?rsolidus, ?doublequote, 0>>}, end_json],
<<34, 0, ?rsolidus, ?doublequote, 0, 34>>, decode(<<34, 0, ?rsolidus, ?rsolidus, ?doublequote, 0, 34>>, [dirty_strings])
<<34, 237, 160, 128, 34>>, )},
<<34, 244, 143, 191, 191, 34>> {"dirty 16#d800", ?_assertEqual(
] [{string, <<237, 160, 128>>}, end_json],
) decode(<<34, 237, 160, 128, 34>>, [dirty_strings])
)},
{"dirty 16#10ffff", ?_assertEqual(
[{string, <<244, 143, 191, 191>>}, end_json],
decode(<<34, 244, 143, 191, 191, 34>>, [dirty_strings])
)} )}
]. ].