Commit a6137e4d authored by ng's avatar ng

rework how pseudo headers are created

parent f94bc27d
......@@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
* New option for lists to include their public keys in the headers of outgoing emails (conforming with Autocrypt, https://autocrypt.org/). Defaults to true. (#335)
* Add visual separator (78 dashes) to the end of the 'pseudoheaders' block: This should help users of Apple Mail, which jams this block and the body together. Hopefully, this change makes it easier to dinstiguish both parts from each other. (#348)
* `deliver_selfsent` per-list option to control whether subscribers get a copy of mail they sent themselves. (#365)
* Wrap pseudo headers if longer than 78 characters.
### Fixed
......
......@@ -17,6 +17,7 @@ module Mail
attr_accessor :original_message
attr_accessor :list
attr_accessor :protected_headers_subject
attr_writer :dynamic_pseudoheaders
# TODO: This should be in initialize(), but I couldn't understand the
# strange errors about wrong number of arguments when overriding
......@@ -44,9 +45,7 @@ module Mail
# might be gone (e.g. request-keywords that delete subscriptions or
# keys).
new.signer
self.dynamic_pseudoheaders.each do |str|
new.add_pseudoheader(str)
end
new.dynamic_pseudoheaders = self.dynamic_pseudoheaders.dup
# Store previously protected subject for later access.
# mail-gpg pulls headers from the decrypted mime parts "up" into the main
......@@ -270,20 +269,17 @@ module Mail
end
def add_pseudoheader(string_or_key, value=nil)
@dynamic_pseudoheaders ||= []
if value.present?
@dynamic_pseudoheaders << make_pseudoheader(string_or_key, value)
else
@dynamic_pseudoheaders << string_or_key.to_s
end
dynamic_pseudoheaders << make_pseudoheader(string_or_key, value)
end
def make_pseudoheader(key, value)
"#{key.to_s.camelize}: #{value.to_s}"
output = "#{key.to_s.camelize}: #{value.to_s}"
# wrap lines after 76 with 2 indents
output.gsub(/(.{1,76})( +|$)\n?/, " \\1\n").chomp.lstrip
end
def dynamic_pseudoheaders
@dynamic_pseudoheaders || []
@dynamic_pseudoheaders ||= []
end
def signature_state
......
......@@ -108,7 +108,7 @@ describe "running filters" do
expect(htmlmail.to).to eql(["admin@example.org"])
signed_parts = htmlmail.parts[0].parts
expect(signed_parts[0].body.to_s).to include("Note: This message included an alternating HTML-part that contained PGP-data. The HTML-part was removed to enable parsing the message more properly.")
expect(signed_parts[0].body.to_s).to include("Note: This message included an alternating HTML-part that contained\n PGP-data. The HTML-part was removed to enable parsing the message more\n properly.\n")
# why is this double wrapped?
expect(signed_parts[1].parts[0][:content_type].content_type).to eql("text/plain")
expect(signed_parts[1].parts[0].body.to_s).to eql("blabla\n")
......
......@@ -39,7 +39,7 @@ describe Schleuder::Filters do
expect(mail[:content_type].content_type).to eql("multipart/mixed")
expect(mail.parts.size).to be(1)
expect(mail.parts.first[:content_type].content_type).to eql("text/plain")
expect(mail.dynamic_pseudoheaders).to include("Note: This message included an alternating HTML-part that contained PGP-data. The HTML-part was removed to enable parsing the message more properly.")
expect(mail.dynamic_pseudoheaders).to include("Note: This message included an alternating HTML-part that contained\n PGP-data. The HTML-part was removed to enable parsing the message more\n properly.")
end
it "does NOT strip HTML-part from multipart/alternative-message that does NOT contain ascii-armored PGP-data" do
......@@ -91,7 +91,7 @@ describe Schleuder::Filters do
expect(mail[:content_type].content_type).to eql('multipart/mixed')
expect(mail.parts.size).to be(1)
expect(mail.parts.first[:content_type].content_type).to eql('text/plain')
expect(mail.dynamic_pseudoheaders).to include('Note: This message included keywords and an alternating HTML-part. The HTML-part was removed to prevent the disclosure of these keywords to third parties.')
expect(mail.dynamic_pseudoheaders).to include("Note: This message included keywords and an alternating HTML-part. The\n HTML-part was removed to prevent the disclosure of these keywords to third\n parties.")
end
it 'does NOT strip HTML-part from multipart/alternative-message that does NOT contain keywords' do
......
......@@ -149,5 +149,63 @@ describe Mail::Message do
expect(mail.parts.last.body.to_s).to eql(footer)
end
context "makes a pseudo header" do
it "with key / value" do
mail = Mail.new
ph = mail.make_pseudoheader('notice','some value')
expect(ph).to eql('Notice: some value')
end
it "without value" do
mail = Mail.new
ph = mail.make_pseudoheader(:key,nil)
expect(ph).to eql('Key: ')
end
it "with empty value" do
mail = Mail.new
ph = mail.make_pseudoheader(:key,'')
expect(ph).to eql('Key: ')
end
it "that is getting wrapped" do
mail = Mail.new
ph = mail.make_pseudoheader('notice','adds list#public_footer as last mime-part without changing its value adds list#public_footer as last mime-part without changing its value')
expect(ph).to eql("Notice: adds list#public_footer as last mime-part without changing its value\n adds list#public_footer as last mime-part without changing its value")
expect(ph.split("\n")).to all( satisfy{|l| l.length <= 78 })
end
it "that multiline are getting wrapped" do
mail = Mail.new
ph = mail.make_pseudoheader('notice',"adds list#public_footer as last mime-part\nwithout changing its value adds list#public_footer as last mime-part without changing its value")
expect(ph).to eql("Notice: adds list#public_footer as last mime-part\n without changing its value adds list#public_footer as last mime-part without\n changing its value")
expect(ph.split("\n")).to all( satisfy{|l| l.length <= 78 })
end
it "that single multiline are getting indented" do
mail = Mail.new
ph = mail.make_pseudoheader('notice',"on line 1\non line 2 but indented")
expect(ph).to eql("Notice: on line 1\n on line 2 but indented")
expect(ph.split("\n")).to all( satisfy{|l| l.length <= 78 })
end
it "that a line with less than 76 gets wrapped" do
mail = Mail.new
ph = mail.make_pseudoheader('keylongerthan8', 'afafa afafaf' * 6) # message is 72 long
expect(ph).to eql("Keylongerthan8: afafa afafafafafa afafafafafa afafafafafa afafafafafa\n afafafafafa afafaf")
expect(ph.split("\n")).to all( satisfy{|l| l.length <= 78 })
end
it "that a multiline with less than 76 get wrapped correctly on the first line" do
mail = Mail.new
ph = mail.make_pseudoheader('keylongerthan8', ('afafa afafaf' * 6)+"\nbla bla newline")
expect(ph).to eql("Keylongerthan8: afafa afafafafafa afafafafafa afafafafafa afafafafafa\n afafafafafa afafaf\n bla bla newline")
expect(ph.split("\n")).to all( satisfy{|l| l.length <= 78 })
end
it "that a multiline with less than 76 get wrapped correctly on the first line and the followint lines" do
mail = Mail.new
ph = mail.make_pseudoheader('keylongerthan8', ('afafa afafaf' * 6)+"\nbla bla newline"+('afafa afafaf' * 6))
expect(ph).to eql("Keylongerthan8: afafa afafafafafa afafafafafa afafafafafa afafafafafa\n afafafafafa afafaf\n bla bla newlineafafa afafafafafa afafafafafa afafafafafa afafafafafa\n afafafafafa afafaf")
expect(ph.split("\n")).to all( satisfy{|l| l.length <= 78 })
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment