mail 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mail might be problematic. Click here for more details.
- data/CHANGELOG.rdoc +15 -17
- data/Rakefile +1 -1
- data/VERSION.yml +5 -0
- data/lib/mail/core_extensions/string.rb +0 -12
- data/lib/mail/encodings.rb +18 -30
- data/lib/mail/fields/common/common_address.rb +4 -4
- data/lib/mail/fields/common/parameter_hash.rb +1 -1
- data/lib/mail/fields/content_disposition_field.rb +1 -1
- data/lib/mail/fields/content_type_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +45 -58
- data/lib/mail/message.rb +0 -2
- data/lib/mail/version.rb +10 -4
- metadata +6 -5
data/CHANGELOG.rdoc
CHANGED
@@ -1,20 +1,18 @@
|
|
1
|
-
==
|
2
|
-
|
3
|
-
*
|
4
|
-
*
|
5
|
-
*
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
* Adding #inline_content_id for attachments and parts (mikel)
|
17
|
-
* Updating readme (mikel)
|
1
|
+
== Mon Jun 7 18:00:39 UTC 2010 Mikel Lindsaar <mikel@rubyx.com>
|
2
|
+
|
3
|
+
* Updating versioning so we only have one source, VERSION.yml (mikel)
|
4
|
+
* Changed activesupport dependency to 2.3.6 to fix #53, #64, and def #67. (Artem Titoulenko)
|
5
|
+
* Fixing typo in break_down_to.rb. (mikel)
|
6
|
+
|
7
|
+
== Mon Jun 7 18:07:16 UTC 2010 Mikel Lindsaar <mikel@rubyx.com>
|
8
|
+
|
9
|
+
* fixing a typo when generating docs. (Andrew Bloom)
|
10
|
+
* Changing \r\n\t to \r\n\s throughout mail (mikel)
|
11
|
+
* Handle multiple quoted words in Encodings.unquote_and_convert_to (Eric Kidd)
|
12
|
+
* Ruby 1.9: mark source encoding so it's usable with -Ks, -Ke, etc (Jeremy Kemper)
|
13
|
+
* Add #include? to mail body for convenience (Maxim Chernyak)
|
14
|
+
* Use Mail::TestMailer.deliveries in README example (John Trupiano)
|
15
|
+
* Allow bundler to automatically build a gem directly from git (Eric Kidd)
|
18
16
|
|
19
17
|
== Sun Apr 11 07:49:15 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
|
20
18
|
|
data/Rakefile
CHANGED
@@ -33,7 +33,7 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
33
33
|
rdoc.rdoc_dir = 'rdoc'
|
34
34
|
rdoc.title = 'Mail'
|
35
35
|
rdoc.options << '--line-numbers' << '--inline-source'
|
36
|
-
rdoc.rdoc_files.include('README')
|
36
|
+
rdoc.rdoc_files.include('README.rdoc')
|
37
37
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
38
38
|
end
|
39
39
|
|
data/VERSION.yml
ADDED
data/lib/mail/encodings.rb
CHANGED
@@ -7,7 +7,6 @@ module Mail
|
|
7
7
|
|
8
8
|
module Encodings
|
9
9
|
|
10
|
-
require "enumerator"
|
11
10
|
include Mail::Patterns
|
12
11
|
extend Mail::Utilities
|
13
12
|
|
@@ -114,34 +113,24 @@ module Mail
|
|
114
113
|
#
|
115
114
|
# String has to be of the format =?<encoding>?[QB]?<string>?=
|
116
115
|
def Encodings.value_decode(str)
|
117
|
-
# Optimization: If there's no encoded-words in the string, just return it
|
118
|
-
return str unless str.index("=?")
|
119
|
-
|
120
116
|
str = str.gsub(/\?=(\s*)=\?/, '?==?') # Remove whitespaces between 'encoded-word's
|
121
117
|
|
122
|
-
#
|
123
|
-
str.
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
text.gsub!(/\?\=\=\?.+?\?[Qq]\?/m, '') if text =~ /\?==\?/
|
129
|
-
|
130
|
-
# Separate encoded-words with a space, so we can treat them one by one
|
131
|
-
text.gsub!(/\?\=\=\?/, '?= =?')
|
118
|
+
# Join QP encoded-words that are adjacent to avoid decoding partial chars
|
119
|
+
str.gsub!( /=\?==\?.+?\?[Qq]\?/m, '' ) if str =~ /\?==\?/
|
120
|
+
|
121
|
+
str.gsub(/(.*?)(=\?.*?\?.\?.*?\?=)|$/m) do # Grab the insides of each encoded-word
|
122
|
+
before = $1.to_s
|
123
|
+
text = $2.to_s
|
132
124
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
word.to_str
|
141
|
-
end
|
142
|
-
end
|
125
|
+
case
|
126
|
+
when text.to_str =~ /=\?.+\?[Bb]\?/m
|
127
|
+
before + b_value_decode(text)
|
128
|
+
when text.to_str =~ /=\?.+\?[Qq]\?/m
|
129
|
+
before + q_value_decode(text)
|
130
|
+
else
|
131
|
+
before + text
|
143
132
|
end
|
144
|
-
end
|
133
|
+
end
|
145
134
|
end
|
146
135
|
|
147
136
|
# Takes an encoded string of the format =?<encoding>?[QB]?<string>?=
|
@@ -187,8 +176,7 @@ module Mail
|
|
187
176
|
address.gsub!(/(".*?[^#{us_ascii}].+?")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
|
188
177
|
# Then loop through all remaining items and encode as needed
|
189
178
|
tokens = address.split(/\s/)
|
190
|
-
|
191
|
-
tokens.enum_for(:each_with_index).map do |word, i|
|
179
|
+
tokens.each_with_index.map do |word, i|
|
192
180
|
if word.ascii_only?
|
193
181
|
word
|
194
182
|
else
|
@@ -211,7 +199,7 @@ module Mail
|
|
211
199
|
def Encodings.b_value_encode(str, encoding = nil)
|
212
200
|
return str if str.to_s.ascii_only?
|
213
201
|
string, encoding = RubyVer.b_value_encode(str, encoding)
|
214
|
-
string.
|
202
|
+
string.each_line.map do |str|
|
215
203
|
"=?#{encoding}?B?#{str.chomp}?="
|
216
204
|
end.join(" ")
|
217
205
|
end
|
@@ -226,8 +214,8 @@ module Mail
|
|
226
214
|
def Encodings.q_value_encode(str, encoding = nil)
|
227
215
|
return str if str.to_s.ascii_only?
|
228
216
|
string, encoding = RubyVer.q_value_encode(str, encoding)
|
229
|
-
string.gsub!("=\r\n", '') # We already have limited the string to the length we want
|
230
|
-
string.
|
217
|
+
string.gsub!("=\r\n=", '=') # We already have limited the string to the length we want
|
218
|
+
string.each_line.map do |str|
|
231
219
|
"=?#{encoding}?Q?#{str.chomp.gsub(/ /, '_')}?="
|
232
220
|
end.join(" ")
|
233
221
|
end
|
@@ -90,11 +90,11 @@ module Mail
|
|
90
90
|
def do_encode(field_name)
|
91
91
|
return '' if value.blank?
|
92
92
|
address_array = tree.addresses.reject { |a| group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
|
93
|
-
address_text = address_array.join(", \r\n\
|
94
|
-
group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.encoded }.join(", \r\n\
|
95
|
-
group_text = group_array.join(" \r\n\
|
93
|
+
address_text = address_array.join(", \r\n\s")
|
94
|
+
group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.encoded }.join(", \r\n\s")};" }
|
95
|
+
group_text = group_array.join(" \r\n\s")
|
96
96
|
return_array = [address_text, group_text].reject { |a| a.blank? }
|
97
|
-
"#{field_name}: #{return_array.join(", \r\n\
|
97
|
+
"#{field_name}: #{return_array.join(", \r\n\s")}\r\n"
|
98
98
|
end
|
99
99
|
|
100
100
|
def do_decode
|
@@ -109,7 +109,7 @@ module Mail
|
|
109
109
|
# TODO: Fix this up
|
110
110
|
def encoded
|
111
111
|
if parameters.length > 0
|
112
|
-
p = ";\r\n\
|
112
|
+
p = ";\r\n\s#{parameters.encoded}\r\n"
|
113
113
|
else
|
114
114
|
p = ""
|
115
115
|
end
|
@@ -160,7 +160,7 @@ module Mail
|
|
160
160
|
type = $1
|
161
161
|
# Handles misquoted param values
|
162
162
|
# e.g: application/octet-stream; name=archiveshelp1[1].htm
|
163
|
-
# and: audio/x-midi;\r\n\
|
163
|
+
# and: audio/x-midi;\r\n\sname=Part .exe
|
164
164
|
params = $2.to_s.split(/\s+/)
|
165
165
|
params = params.map { |i| i.to_s.chomp.strip }
|
166
166
|
params = params.map { |i| i.split(/\s*\=\s*/) }
|
@@ -102,77 +102,64 @@ module Mail
|
|
102
102
|
# it is allowed elsewhere.
|
103
103
|
def wrapped_value # :nodoc:
|
104
104
|
@folded_line = []
|
105
|
-
@unfolded_line = decoded.to_s.
|
105
|
+
@unfolded_line = decoded.to_s.clone
|
106
106
|
fold("#{name}: ".length)
|
107
107
|
wrap_lines(name, @folded_line)
|
108
108
|
end
|
109
|
-
|
110
|
-
# 6.2. Display of 'encoded-word's
|
111
|
-
#
|
112
|
-
# When displaying a particular header field that contains multiple
|
113
|
-
# 'encoded-word's, any 'linear-white-space' that separates a pair of
|
114
|
-
# adjacent 'encoded-word's is ignored. (This is to allow the use of
|
115
|
-
# multiple 'encoded-word's to represent long strings of unencoded text,
|
116
|
-
# without having to separate 'encoded-word's where spaces occur in the
|
117
|
-
# unencoded text.)
|
109
|
+
|
118
110
|
def wrap_lines(name, folded_lines)
|
119
111
|
result = []
|
120
112
|
index = 0
|
121
113
|
result[index] = "#{name}: #{folded_lines.shift}"
|
122
|
-
|
123
|
-
|
114
|
+
folded_lines.each do |line|
|
115
|
+
if (result[index] + line).length < 77
|
116
|
+
result[index] << " " + line
|
117
|
+
else
|
118
|
+
result[index] << "\r\n\s"
|
119
|
+
index += 1
|
120
|
+
result[index] = line
|
121
|
+
end
|
122
|
+
end
|
123
|
+
result.join
|
124
124
|
end
|
125
125
|
|
126
126
|
def fold(prepend = 0) # :nodoc:
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
# Add leading whitespace if both this and the last line were encoded, because whitespace between two encoded-words is ignored when decoding
|
157
|
-
line = " " + line if encoded && @folded_line.last && @folded_line.last.index('=?') == 0
|
158
|
-
# Encode the line if necessary
|
159
|
-
line = "=?#{encoding}?Q?#{line.gsub(/ /, '_')}?=" if encoded
|
160
|
-
# Add the line to the output and reset the prepend
|
161
|
-
@folded_line << line
|
162
|
-
prepend = 0
|
127
|
+
# Get the last whitespace character, OR we'll just choose
|
128
|
+
# 78 if there is no whitespace, or 23 for non ascii:
|
129
|
+
# Each QP byte is 6 chars (=0A)
|
130
|
+
# Plus 18 for the =?encoding?Q?= ... ?=
|
131
|
+
# Plus 2 for the \r\n and 1 for the \s
|
132
|
+
# 80 - 2 - 1 - 18 = 59 / 6 ~= 10
|
133
|
+
@unfolded_line.ascii_only? ? (limit = 78 - prepend) : (limit = 10 - prepend)
|
134
|
+
# find the last white space character within the limit
|
135
|
+
if wspp = @unfolded_line.mb_chars.slice(0..limit) =~ /[ \t][^ \t]*$/
|
136
|
+
wrap = true
|
137
|
+
wspp = limit if wspp == 0
|
138
|
+
@folded_line << encode(@unfolded_line.mb_chars.slice!(0...wspp).strip.to_str)
|
139
|
+
@folded_line.flatten!
|
140
|
+
# if no last whitespace before the limit, find the first
|
141
|
+
elsif wspp = @unfolded_line.mb_chars =~ /[ \t][^ \t]/
|
142
|
+
wrap = true
|
143
|
+
wspp = limit if wspp == 0
|
144
|
+
@folded_line << encode(@unfolded_line.mb_chars.slice!(0...wspp).strip.to_str)
|
145
|
+
@folded_line.flatten!
|
146
|
+
# if no whitespace, don't wrap
|
147
|
+
else
|
148
|
+
wrap = false
|
149
|
+
end
|
150
|
+
|
151
|
+
if wrap && @unfolded_line.length > limit
|
152
|
+
fold
|
153
|
+
else
|
154
|
+
@folded_line << encode(@unfolded_line)
|
155
|
+
@folded_line.flatten!
|
163
156
|
end
|
164
157
|
end
|
165
|
-
|
158
|
+
|
166
159
|
def encode(value)
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
def encoded_word_safify!(value)
|
171
|
-
value.gsub!(/"/, '=22')
|
172
|
-
value.gsub!(/\(/, '=28')
|
173
|
-
value.gsub!(/\)/, '=29')
|
174
|
-
value.gsub!(/\?/, '=3F')
|
175
|
-
value.gsub!(/_/, '=5F')
|
160
|
+
value.gsub!("\r", "=0D")
|
161
|
+
value.gsub!("\n", "=0A")
|
162
|
+
Encodings.q_value_encode(value, @charset).split(" ")
|
176
163
|
end
|
177
164
|
|
178
165
|
end
|
data/lib/mail/message.rb
CHANGED
data/lib/mail/version.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mail
|
3
3
|
module VERSION
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
|
5
|
+
def self.version
|
6
|
+
YAML.load_file(File.join(File.dirname(__FILE__), '../../', 'VERSION.yml'))
|
7
|
+
end
|
8
|
+
|
9
|
+
MAJOR = version[:major]
|
10
|
+
MINOR = version[:minor]
|
11
|
+
PATCH = version[:patch]
|
12
|
+
BUILD = version[:build]
|
7
13
|
|
8
|
-
STRING = [MAJOR, MINOR,
|
14
|
+
STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
|
9
15
|
end
|
10
16
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 2.2.
|
8
|
+
- 2
|
9
|
+
version: 2.2.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mikel Lindsaar
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-06-07 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -27,8 +27,8 @@ dependencies:
|
|
27
27
|
segments:
|
28
28
|
- 2
|
29
29
|
- 3
|
30
|
-
-
|
31
|
-
version: 2.3.
|
30
|
+
- 6
|
31
|
+
version: 2.3.6
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
34
|
- !ruby/object:Gem::Dependency
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- README.rdoc
|
72
72
|
- Rakefile
|
73
73
|
- TODO.rdoc
|
74
|
+
- VERSION.yml
|
74
75
|
- lib/mail/attachments_list.rb
|
75
76
|
- lib/mail/body.rb
|
76
77
|
- lib/mail/configuration.rb
|