From e6238bc7f652d8550fe2c128574c3d6909bc4785 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 17 Dec 2012 07:48:10 -0700 Subject: [PATCH] Fix the bogus '=' at the end of some quoted-printable messages. Trailing CRLF is significant in Quoted-Printable transfer encoding. Stripping trailing whitespace corrupts the encoding, resulting in odd '=' chars showing up at the end of decoded emails. Fixed by only stripping leading whitespace. Closes #440 --- lib/mail/header.rb | 2 +- lib/mail/message.rb | 4 ++-- spec/mail/example_emails_spec.rb | 2 +- spec/mail/message_spec.rb | 12 ++++++++---- spec/mail/round_tripping_spec.rb | 4 ++-- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/mail/header.rb b/lib/mail/header.rb index c702ab843..50c12c7bf 100644 --- a/lib/mail/header.rb +++ b/lib/mail/header.rb @@ -50,7 +50,7 @@ def self.maximum_amount=(value) def initialize(header_text = nil, charset = nil) @errors = [] @charset = charset - self.raw_source = header_text.to_crlf + self.raw_source = header_text.to_crlf.lstrip split_header if header_text end diff --git a/lib/mail/message.rb b/lib/mail/message.rb index 187cfca2c..ab0f79135 100644 --- a/lib/mail/message.rb +++ b/lib/mail/message.rb @@ -122,7 +122,7 @@ def initialize(*args, &block) if args.flatten.first.respond_to?(:each_pair) init_with_hash(args.flatten.first) else - init_with_string(args.flatten[0].to_s.strip) + init_with_string(args.flatten[0].to_s) end if block_given? @@ -1875,7 +1875,7 @@ def text? # Additionally, I allow for the case where someone might have put whitespace # on the "gap line" def parse_message - header_part, body_part = raw_source.split(/#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/m, 2) + header_part, body_part = raw_source.lstrip.split(/#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/m, 2) self.header = header_part self.body = body_part end diff --git a/spec/mail/example_emails_spec.rb b/spec/mail/example_emails_spec.rb index 7533bb288..18fcf7a0f 100644 --- a/spec/mail/example_emails_spec.rb +++ b/spec/mail/example_emails_spec.rb @@ -254,7 +254,7 @@ mail.from.should eq ["atsushi@example.com"] mail.subject.should eq "Re: TEST テストテスト" mail.message_id.should eq '0CC5E11ED2C1D@example.com' - mail.body.should eq "Hello" + mail.body.decoded.should eq "Hello\n" end end diff --git a/spec/mail/message_spec.rb b/spec/mail/message_spec.rb index d6d82aac7..676ed0eaa 100644 --- a/spec/mail/message_spec.rb +++ b/spec/mail/message_spec.rb @@ -237,7 +237,7 @@ def basic_email it "should set a raw source instance variable to equal the passed in message" do mail = Mail::Message.new(basic_email) - mail.raw_source.should eq basic_email.strip + mail.raw_source.should eq basic_email end it "should set the raw source instance variable to '' if no message is passed in" do @@ -259,7 +259,7 @@ def basic_email it "should give the body class the body to parse" do body = Mail::Body.new("email message") - Mail::Body.should_receive(:new).with("email message").and_return(body) + Mail::Body.should_receive(:new).with("email message\r\n").and_return(body) mail = Mail::Message.new(basic_email) mail.body #body calculates now lazy so need to ask for it end @@ -290,8 +290,8 @@ def basic_email it "should allow for whitespace at the start of the email" do mail = Mail.new("\r\n\r\nFrom: mikel\r\n\r\nThis is the body") - mail.from.should eq ['mikel'] mail.body.to_s.should eq 'This is the body' + mail.from.should eq ['mikel'] end it "should read in an email message with the word 'From' in it multiple times and parse it" do @@ -303,7 +303,7 @@ def basic_email it "should parse non-UTF8 sources" do mail = Mail::Message.new(File.read(fixture('emails', 'multi_charset', 'japanese_shiftjis.eml'))) mail.to.should eq ["raasdnil@gmail.com"] - mail.decoded.should eq "すみません。" + mail.decoded.should eq "すみません。\n\n" end end @@ -1254,6 +1254,10 @@ def basic_email mail.body.encoded.should eq "VGhlIGJvZHk=\r\n" end + it 'should not strip the raw mail source in case the trailing \r\n is meaningful' do + Mail.new("Content-Transfer-Encoding: quoted-printable;\r\n\r\nfoo=\r\nbar=\r\nbaz=\r\n").decoded.should eq 'foobarbaz' + end + end end diff --git a/spec/mail/round_tripping_spec.rb b/spec/mail/round_tripping_spec.rb index b8bcd59cc..2e5c9e7a5 100644 --- a/spec/mail/round_tripping_spec.rb +++ b/spec/mail/round_tripping_spec.rb @@ -24,8 +24,8 @@ parsed_mail.mime_type.should eq 'multipart/alternative' parsed_mail.boundary.should eq mail.boundary parsed_mail.parts.length.should eq 2 - parsed_mail.parts[0].body.to_s.should eq "This is Text" - parsed_mail.parts[1].body.to_s.should eq "This is HTML" + parsed_mail.parts[0].body.to_s.should eq "This is Text\n\n" + parsed_mail.parts[1].body.to_s.should eq "This is HTML\n\n" end it "should round trip an email" do