Skip to content

Commit

Permalink
Quoting of the MIME boundary when it contains special characters.
Browse files Browse the repository at this point in the history
  • Loading branch information
Arjan Scherpenisse committed Jul 26, 2011
1 parent cdc1aec commit a90b869
Showing 1 changed file with 46 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/mimemail.erl
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,31 @@ guess_best_encoding(Body) ->
encode_parameters([[]]) ->
[];
encode_parameters(Parameters) ->
[case binstr:strchr(Y, $\s) of 0 -> [X, "=", Y]; _ -> [X, "=\"", Y, "\""] end || {X, Y} <- Parameters].
lists:map(fun encode_parameter/1, Parameters).

encode_parameter({X, Y}) ->
case escape_tspecial(Y, false, <<>>) of
{true, Special} -> [X, $=, $", Special, $"];
false -> [X, $=, Y]
end.

% See also: http://www.ietf.org/rfc/rfc2045.txt section 5.1
escape_tspecial(<<>>, false, _Acc) ->
false;
escape_tspecial(<<>>, IsSpecial, Acc) ->
{IsSpecial, Acc};
escape_tspecial(<<C, Rest/binary>>, _IsSpecial, Acc) when C =:= $" ->
escape_tspecial(Rest, true, <<Acc/binary, $\\, $">>);
escape_tspecial(<<C, Rest/binary>>, _IsSpecial, Acc) when C =:= $\\ ->
escape_tspecial(Rest, true, <<Acc/binary, $\\, $\\>>);
escape_tspecial(<<C, Rest/binary>>, _IsSpecial, Acc)
when C =:= $(; C =:= $); C =:= $<; C =:= $>; C =:= $@;
C =:= $,; C =:= $;; C =:= $:;
C =:= $/; C =:= $[; C =:= $]; C =:= $?; C =:= $=;
C =:= $\s ->
escape_tspecial(Rest, true, <<Acc/binary, C>>);
escape_tspecial(<<C, Rest/binary>>, IsSpecial, Acc) ->
escape_tspecial(Rest, IsSpecial, <<Acc/binary, C>>).

encode_headers(Headers) ->
encode_headers(Headers, []).
Expand Down Expand Up @@ -1380,6 +1404,27 @@ encode_quoted_printable_test_() ->
}
].

encode_parameter_test_() ->
[
{"Token",
fun() ->
?assertEqual([[<<"a">>, $=, <<"abcdefghijklmnopqrstuvwxyz$%&*#!">>]],
encode_parameters([{<<"a">>, <<"abcdefghijklmnopqrstuvwxyz$%&*#!">>}]))
end
},
{"TSpecial",
fun() ->
Special = " ()<>@,;:/[]?=",
[
?assertEqual([[<<"a">>, $=, $", <<C>>, $"]], encode_parameters([{<<"a">>, <<C>>}]))
|| C <- Special
],
?assertEqual([[<<"a">>, $=, $", <<$\\,$">>, $"]], encode_parameters([{<<"a">>, <<$">>}])),
?assertEqual([[<<"a">>, $=, $", <<$\\,$\\>>, $"]], encode_parameters([{<<"a">>, <<$\\>>}]))
end
}
].

rfc2047_decode_test_() ->
[
{"Simple tests",
Expand Down

0 comments on commit a90b869

Please sign in to comment.