Permalink
Browse files

Quoting of the MIME boundary when it contains special characters.

  • Loading branch information...
arjan committed Jul 26, 2011
1 parent cdc1aec commit a90b86929895b9cdf1a45795a262ca9fec1f3338
Showing with 46 additions and 1 deletion.
  1. +46 −1 src/mimemail.erl
View
@@ -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, []).
@@ -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",

0 comments on commit a90b869

Please sign in to comment.