Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix quoted-printable encoding for reserved chars, RFC 2047, section 4.2(3) #176

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/mail/encoders/quoted_printable.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Mail.Encoders.QuotedPrintable do

@new_line "=\r\n"
@max_length 76
@reserved_chars [?=, ??, ?_]

@doc """
Encodes a string into a quoted-printable encoded string.
Expand All @@ -23,10 +24,9 @@ defmodule Mail.Encoders.QuotedPrintable do

def encode(<<>>, _, acc, _), do: acc

# Encode ASCII characters in range 0x20..0x3C.
# Encode ASCII characters in range 0x3E..0x7E, except 0x3F (question mark)
# Encode ASCII characters in range 0x20..0x7E, except reserved symbols: 0x3F (question mark), 0x3D (equal sign) and 0x5F (underscore)
def encode(<<char, tail::binary>>, max_length, acc, line_length)
when char in ?!..?< or char in ?@..?~ or char == ?> do
when char in ?!..?~ and char not in @reserved_chars do
if line_length < max_length - 1 do
encode(tail, max_length, acc <> <<char>>, line_length + 1)
else
Expand Down
8 changes: 7 additions & 1 deletion test/mail/encoders/quoted_printable_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ defmodule Mail.Encoders.QuotedPrintableTest do
ascii_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
assert Mail.Encoders.QuotedPrintable.encode(ascii_upper) == ascii_upper

ascii_symbols = "!\"#$%&\'()*+,-./0123456789:;<>@[\\]^_`{|}~"
ascii_symbols = "!\"#$%&\'()*+,-./0123456789:;<>@[\\]^`{|}~"
assert Mail.Encoders.QuotedPrintable.encode(ascii_symbols) == ascii_symbols
end

# RFC 2047, section 4.2(3)
test "encodes reserved characters" do
reserved_characters = "=?_"
assert Mail.Encoders.QuotedPrintable.encode(reserved_characters) == "=3D=3F=5F"
end

test "encodes question mark sign" do
assert Mail.Encoders.QuotedPrintable.encode("hello?goodbye") == "hello=3Fgoodbye"
end
Expand Down
Loading