diff --git a/lib/mail/encoders/eight_bit.ex b/lib/mail/encoders/eight_bit.ex
index cee5812..e6f4e45 100644
--- a/lib/mail/encoders/eight_bit.ex
+++ b/lib/mail/encoders/eight_bit.ex
@@ -37,14 +37,19 @@ defmodule Mail.Encoders.EightBit do
@doc """
Decodes an 8-bit encoded string.
"""
- def decode(string), do: do_decode(string, "")
- defp do_decode(<<>>, acc), do: acc
+ def decode(encoded_string), do: do_decode(encoded_string, "", 0)
- defp do_decode(<
>, acc) do
- {decoded, tail} = decode_char(head, tail)
- do_decode(tail, acc <> decoded)
+ defp do_decode(<<>>, acc, _line_length), do: acc
+
+ defp do_decode(<<"\r\n", tail::binary>>, acc, 998) do
+ do_decode(tail, acc, 0)
+ end
+
+ defp do_decode(<>, acc, line_length) do
+ {decoded, tail, length} = decode_char(head, tail)
+ do_decode(tail, acc <> decoded, line_length + length)
end
- defp decode_char(?\r, <\n, tail::binary>>), do: {"", tail}
- defp decode_char(char, <>), do: {<>, tail}
+ defp decode_char(?\0, _tail), do: raise(ArgumentError, message: "illegal NUL character")
+ defp decode_char(char, <>), do: {<>, tail, 1}
end
diff --git a/test/mail/encoders/eight_bit_test.exs b/test/mail/encoders/eight_bit_test.exs
index d596f54..836ccb5 100644
--- a/test/mail/encoders/eight_bit_test.exs
+++ b/test/mail/encoders/eight_bit_test.exs
@@ -23,8 +23,21 @@ defmodule Mail.Encoders.EightBitTest do
assert Mail.Encoders.EightBit.decode("") == ""
end
- test "decode removes pairs" do
+ test "decode preserves pairs" do
message = "This is a \r\ntest\r\n"
- assert Mail.Encoders.EightBit.decode(message) == "This is a test"
+ assert Mail.Encoders.EightBit.decode(message) == "This is a \r\ntest\r\n"
+ end
+
+ test "decode removes crlf wrapping characters" do
+ message = String.duplicate("-", 1000)
+ encoded = Mail.Encoders.EightBit.encode(message)
+ assert binary_part(encoded, 998, 2) == "\r\n"
+ assert message == Mail.Encoders.EightBit.decode(encoded)
+ end
+
+ test "decode raises if any character is " do
+ assert_raise ArgumentError, fn ->
+ Mail.Encoders.EightBit.decode("\0")
+ end
end
end