mail 2.4.4 → 2.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +140 -1
- data/CONTRIBUTING.md +4 -4
- data/Gemfile +14 -8
- data/MIT-LICENSE +20 -0
- data/README.md +24 -23
- data/Rakefile +3 -22
- data/lib/VERSION +2 -2
- data/lib/load_parsers.rb +35 -0
- data/lib/mail/attachments_list.rb +2 -2
- data/lib/mail/body.rb +5 -5
- data/lib/mail/check_delivery_params.rb +57 -0
- data/lib/mail/configuration.rb +1 -1
- data/lib/mail/core_extensions/nil.rb +4 -2
- data/lib/mail/core_extensions/object.rb +8 -8
- data/lib/mail/core_extensions/smtp.rb +12 -13
- data/lib/mail/core_extensions/string.rb +4 -4
- data/lib/mail/elements/address.rb +13 -5
- data/lib/mail/elements/envelope_from_element.rb +15 -2
- data/lib/mail/elements.rb +12 -12
- data/lib/mail/encodings/quoted_printable.rb +4 -3
- data/lib/mail/encodings.rb +66 -35
- data/lib/mail/field.rb +76 -99
- data/lib/mail/fields/bcc_field.rb +2 -2
- data/lib/mail/fields/cc_field.rb +2 -2
- data/lib/mail/fields/comments_field.rb +1 -1
- data/lib/mail/fields/common/common_address.rb +19 -4
- data/lib/mail/fields/common/common_field.rb +8 -2
- data/lib/mail/fields/common/common_message_id.rb +9 -5
- data/lib/mail/fields/content_disposition_field.rb +1 -0
- data/lib/mail/fields/content_id_field.rb +1 -2
- data/lib/mail/fields/content_transfer_encoding_field.rb +2 -2
- data/lib/mail/fields/content_type_field.rb +5 -2
- data/lib/mail/fields/date_field.rb +14 -14
- data/lib/mail/fields/from_field.rb +2 -2
- data/lib/mail/fields/in_reply_to_field.rb +2 -1
- data/lib/mail/fields/keywords_field.rb +1 -1
- data/lib/mail/fields/message_id_field.rb +2 -3
- data/lib/mail/fields/references_field.rb +2 -1
- data/lib/mail/fields/reply_to_field.rb +2 -2
- data/lib/mail/fields/resent_bcc_field.rb +2 -2
- data/lib/mail/fields/resent_cc_field.rb +2 -2
- data/lib/mail/fields/resent_from_field.rb +2 -2
- data/lib/mail/fields/resent_sender_field.rb +2 -2
- data/lib/mail/fields/resent_to_field.rb +2 -2
- data/lib/mail/fields/sender_field.rb +7 -7
- data/lib/mail/fields/to_field.rb +2 -2
- data/lib/mail/fields/unstructured_field.rb +34 -27
- data/lib/mail/fields.rb +32 -32
- data/lib/mail/header.rb +37 -14
- data/lib/mail/message.rb +140 -45
- data/lib/mail/multibyte/chars.rb +4 -4
- data/lib/mail/multibyte/unicode.rb +8 -0
- data/lib/mail/network/delivery_methods/exim.rb +6 -11
- data/lib/mail/network/delivery_methods/file_delivery.rb +7 -6
- data/lib/mail/network/delivery_methods/sendmail.rb +40 -11
- data/lib/mail/network/delivery_methods/smtp.rb +33 -47
- data/lib/mail/network/delivery_methods/smtp_connection.rb +7 -24
- data/lib/mail/network/delivery_methods/test_mailer.rb +9 -8
- data/lib/mail/network/retriever_methods/imap.rb +14 -6
- data/lib/mail/network/retriever_methods/pop3.rb +2 -2
- data/lib/mail/network/retriever_methods/test_retriever.rb +11 -15
- data/lib/mail/network.rb +9 -9
- data/lib/mail/parsers/content_transfer_encoding.rb +81 -42
- data/lib/mail/parsers/content_transfer_encoding.treetop +4 -6
- data/lib/mail/parsers/content_type.rb +16 -12
- data/lib/mail/parsers/content_type.treetop +2 -2
- data/lib/mail/parsers/rfc2045.rb +12 -55
- data/lib/mail/parsers/rfc2045.treetop +1 -2
- data/lib/mail/parsers/rfc2822.rb +127 -71
- data/lib/mail/parsers/rfc2822.treetop +22 -24
- data/lib/mail/part.rb +6 -2
- data/lib/mail/parts_list.rb +1 -1
- data/lib/mail/patterns.rb +1 -1
- data/lib/mail/utilities.rb +25 -17
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version_specific/ruby_1_8.rb +23 -2
- data/lib/mail/version_specific/ruby_1_9.rb +55 -21
- data/lib/mail.rb +18 -18
- metadata +89 -37
- data/Gemfile.lock +0 -36
- data/lib/mail/core_extensions/shell_escape.rb +0 -56
data/lib/mail/parsers/rfc2045.rb
CHANGED
@@ -216,64 +216,21 @@ module Mail
|
|
216
216
|
return cached
|
217
217
|
end
|
218
218
|
|
219
|
-
i0 = index
|
220
|
-
|
221
|
-
r1 =
|
222
|
-
|
223
|
-
|
224
|
-
terminal_parse_failure("7bit")
|
225
|
-
r1 = nil
|
226
|
-
end
|
227
|
-
if r1
|
228
|
-
r0 = r1
|
229
|
-
else
|
230
|
-
if has_terminal?("8bit", false, index)
|
231
|
-
r2 = instantiate_node(SyntaxNode,input, index...(index + 4))
|
232
|
-
@index += 4
|
233
|
-
else
|
234
|
-
terminal_parse_failure("8bit")
|
235
|
-
r2 = nil
|
236
|
-
end
|
237
|
-
if r2
|
238
|
-
r0 = r2
|
219
|
+
s0, i0 = [], index
|
220
|
+
loop do
|
221
|
+
r1 = _nt_token
|
222
|
+
if r1
|
223
|
+
s0 << r1
|
239
224
|
else
|
240
|
-
|
241
|
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
242
|
-
@index += 6
|
243
|
-
else
|
244
|
-
terminal_parse_failure("binary")
|
245
|
-
r3 = nil
|
246
|
-
end
|
247
|
-
if r3
|
248
|
-
r0 = r3
|
249
|
-
else
|
250
|
-
if has_terminal?("quoted-printable", false, index)
|
251
|
-
r4 = instantiate_node(SyntaxNode,input, index...(index + 16))
|
252
|
-
@index += 16
|
253
|
-
else
|
254
|
-
terminal_parse_failure("quoted-printable")
|
255
|
-
r4 = nil
|
256
|
-
end
|
257
|
-
if r4
|
258
|
-
r0 = r4
|
259
|
-
else
|
260
|
-
if has_terminal?("base64", false, index)
|
261
|
-
r5 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
262
|
-
@index += 6
|
263
|
-
else
|
264
|
-
terminal_parse_failure("base64")
|
265
|
-
r5 = nil
|
266
|
-
end
|
267
|
-
if r5
|
268
|
-
r0 = r5
|
269
|
-
else
|
270
|
-
@index = i0
|
271
|
-
r0 = nil
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
225
|
+
break
|
275
226
|
end
|
276
227
|
end
|
228
|
+
if s0.empty?
|
229
|
+
@index = i0
|
230
|
+
r0 = nil
|
231
|
+
else
|
232
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
233
|
+
end
|
277
234
|
|
278
235
|
node_cache[:ietf_token][start_index] = r0
|
279
236
|
|
data/lib/mail/parsers/rfc2822.rb
CHANGED
@@ -1321,6 +1321,7 @@ module Mail
|
|
1321
1321
|
def domain_text
|
1322
1322
|
elements[1]
|
1323
1323
|
end
|
1324
|
+
|
1324
1325
|
end
|
1325
1326
|
|
1326
1327
|
def _nt_local_dot_atom_text
|
@@ -1357,6 +1358,25 @@ module Mail
|
|
1357
1358
|
if r2
|
1358
1359
|
r4 = _nt_domain_text
|
1359
1360
|
s1 << r4
|
1361
|
+
if r4
|
1362
|
+
s5, i5 = [], index
|
1363
|
+
loop do
|
1364
|
+
if has_terminal?(".", false, index)
|
1365
|
+
r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
1366
|
+
@index += 1
|
1367
|
+
else
|
1368
|
+
terminal_parse_failure(".")
|
1369
|
+
r6 = nil
|
1370
|
+
end
|
1371
|
+
if r6
|
1372
|
+
s5 << r6
|
1373
|
+
else
|
1374
|
+
break
|
1375
|
+
end
|
1376
|
+
end
|
1377
|
+
r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
|
1378
|
+
s1 << r5
|
1379
|
+
end
|
1360
1380
|
end
|
1361
1381
|
if s1.last
|
1362
1382
|
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
|
@@ -2369,12 +2389,7 @@ module Mail
|
|
2369
2389
|
break
|
2370
2390
|
end
|
2371
2391
|
end
|
2372
|
-
|
2373
|
-
@index = i4
|
2374
|
-
r4 = nil
|
2375
|
-
else
|
2376
|
-
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
2377
|
-
end
|
2392
|
+
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
2378
2393
|
s0 << r4
|
2379
2394
|
if r4
|
2380
2395
|
r10 = _nt_FWS
|
@@ -2714,17 +2729,35 @@ module Mail
|
|
2714
2729
|
s3, i3 = [], index
|
2715
2730
|
loop do
|
2716
2731
|
i4, s4 = index, []
|
2732
|
+
i5 = index
|
2717
2733
|
if has_terminal?(",", false, index)
|
2718
|
-
|
2734
|
+
r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
2719
2735
|
@index += 1
|
2720
2736
|
else
|
2721
2737
|
terminal_parse_failure(",")
|
2722
|
-
|
2738
|
+
r6 = nil
|
2739
|
+
end
|
2740
|
+
if r6
|
2741
|
+
r5 = r6
|
2742
|
+
else
|
2743
|
+
if has_terminal?(";", false, index)
|
2744
|
+
r7 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
2745
|
+
@index += 1
|
2746
|
+
else
|
2747
|
+
terminal_parse_failure(";")
|
2748
|
+
r7 = nil
|
2749
|
+
end
|
2750
|
+
if r7
|
2751
|
+
r5 = r7
|
2752
|
+
else
|
2753
|
+
@index = i5
|
2754
|
+
r5 = nil
|
2755
|
+
end
|
2723
2756
|
end
|
2724
2757
|
s4 << r5
|
2725
2758
|
if r5
|
2726
|
-
|
2727
|
-
s4 <<
|
2759
|
+
r8 = _nt_mailbox
|
2760
|
+
s4 << r8
|
2728
2761
|
end
|
2729
2762
|
if s4.last
|
2730
2763
|
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
@@ -2752,9 +2785,9 @@ module Mail
|
|
2752
2785
|
if r1
|
2753
2786
|
r0 = r1
|
2754
2787
|
else
|
2755
|
-
|
2756
|
-
if
|
2757
|
-
r0 =
|
2788
|
+
r9 = _nt_obs_mbox_list
|
2789
|
+
if r9
|
2790
|
+
r0 = r9
|
2758
2791
|
else
|
2759
2792
|
@index = i0
|
2760
2793
|
r0 = nil
|
@@ -2766,6 +2799,23 @@ module Mail
|
|
2766
2799
|
r0
|
2767
2800
|
end
|
2768
2801
|
|
2802
|
+
module Mailbox0
|
2803
|
+
def dig_comments(comments, elements)
|
2804
|
+
elements.each { |elem|
|
2805
|
+
if elem.respond_to?(:comment)
|
2806
|
+
comments << elem.comment
|
2807
|
+
end
|
2808
|
+
dig_comments(comments, elem.elements) if elem.elements
|
2809
|
+
}
|
2810
|
+
end
|
2811
|
+
|
2812
|
+
def comments
|
2813
|
+
comments = []
|
2814
|
+
dig_comments(comments, elements)
|
2815
|
+
comments
|
2816
|
+
end
|
2817
|
+
end
|
2818
|
+
|
2769
2819
|
def _nt_mailbox
|
2770
2820
|
start_index = index
|
2771
2821
|
if node_cache[:mailbox].has_key?(index)
|
@@ -2781,10 +2831,12 @@ module Mail
|
|
2781
2831
|
r1 = _nt_name_addr
|
2782
2832
|
if r1
|
2783
2833
|
r0 = r1
|
2834
|
+
r0.extend(Mailbox0)
|
2784
2835
|
else
|
2785
2836
|
r2 = _nt_addr_spec
|
2786
2837
|
if r2
|
2787
2838
|
r0 = r2
|
2839
|
+
r0.extend(Mailbox0)
|
2788
2840
|
else
|
2789
2841
|
@index = i0
|
2790
2842
|
r0 = nil
|
@@ -2814,24 +2866,6 @@ module Mail
|
|
2814
2866
|
end
|
2815
2867
|
end
|
2816
2868
|
|
2817
|
-
module Address1
|
2818
|
-
|
2819
|
-
def dig_comments(comments, elements)
|
2820
|
-
elements.each { |elem|
|
2821
|
-
if elem.respond_to?(:comment)
|
2822
|
-
comments << elem.comment
|
2823
|
-
end
|
2824
|
-
dig_comments(comments, elem.elements) if elem.elements
|
2825
|
-
}
|
2826
|
-
end
|
2827
|
-
|
2828
|
-
def comments
|
2829
|
-
comments = []
|
2830
|
-
dig_comments(comments, elements)
|
2831
|
-
comments
|
2832
|
-
end
|
2833
|
-
end
|
2834
|
-
|
2835
2869
|
def _nt_address
|
2836
2870
|
start_index = index
|
2837
2871
|
if node_cache[:address].has_key?(index)
|
@@ -2850,7 +2884,6 @@ module Mail
|
|
2850
2884
|
r0 = r1
|
2851
2885
|
else
|
2852
2886
|
r2 = _nt_mailbox
|
2853
|
-
r2.extend(Address1)
|
2854
2887
|
if r2
|
2855
2888
|
r0 = r2
|
2856
2889
|
else
|
@@ -2915,34 +2948,52 @@ module Mail
|
|
2915
2948
|
r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
|
2916
2949
|
s4 << r5
|
2917
2950
|
if r5
|
2951
|
+
i7 = index
|
2918
2952
|
if has_terminal?(",", false, index)
|
2919
|
-
|
2953
|
+
r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
2920
2954
|
@index += 1
|
2921
2955
|
else
|
2922
2956
|
terminal_parse_failure(",")
|
2923
|
-
|
2957
|
+
r8 = nil
|
2958
|
+
end
|
2959
|
+
if r8
|
2960
|
+
r7 = r8
|
2961
|
+
else
|
2962
|
+
if has_terminal?(";", false, index)
|
2963
|
+
r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
2964
|
+
@index += 1
|
2965
|
+
else
|
2966
|
+
terminal_parse_failure(";")
|
2967
|
+
r9 = nil
|
2968
|
+
end
|
2969
|
+
if r9
|
2970
|
+
r7 = r9
|
2971
|
+
else
|
2972
|
+
@index = i7
|
2973
|
+
r7 = nil
|
2974
|
+
end
|
2924
2975
|
end
|
2925
2976
|
s4 << r7
|
2926
2977
|
if r7
|
2927
|
-
|
2978
|
+
s10, i10 = [], index
|
2928
2979
|
loop do
|
2929
|
-
|
2930
|
-
if
|
2931
|
-
|
2980
|
+
r11 = _nt_FWS
|
2981
|
+
if r11
|
2982
|
+
s10 << r11
|
2932
2983
|
else
|
2933
2984
|
break
|
2934
2985
|
end
|
2935
2986
|
end
|
2936
|
-
|
2937
|
-
s4 <<
|
2938
|
-
if
|
2939
|
-
|
2940
|
-
if
|
2941
|
-
|
2987
|
+
r10 = instantiate_node(SyntaxNode,input, i10...index, s10)
|
2988
|
+
s4 << r10
|
2989
|
+
if r10
|
2990
|
+
r13 = _nt_address
|
2991
|
+
if r13
|
2992
|
+
r12 = r13
|
2942
2993
|
else
|
2943
|
-
|
2994
|
+
r12 = instantiate_node(SyntaxNode,input, index...index)
|
2944
2995
|
end
|
2945
|
-
s4 <<
|
2996
|
+
s4 << r12
|
2946
2997
|
end
|
2947
2998
|
end
|
2948
2999
|
end
|
@@ -4243,41 +4294,46 @@ module Mail
|
|
4243
4294
|
end
|
4244
4295
|
s0 << r1
|
4245
4296
|
if r1
|
4246
|
-
|
4247
|
-
|
4248
|
-
|
4249
|
-
if
|
4250
|
-
|
4297
|
+
i4, s4 = index, []
|
4298
|
+
r5 = _nt_name_val_pair
|
4299
|
+
s4 << r5
|
4300
|
+
if r5
|
4301
|
+
s6, i6 = [], index
|
4251
4302
|
loop do
|
4252
|
-
|
4253
|
-
|
4254
|
-
|
4255
|
-
if
|
4256
|
-
|
4257
|
-
|
4303
|
+
i7, s7 = index, []
|
4304
|
+
r8 = _nt_CFWS
|
4305
|
+
s7 << r8
|
4306
|
+
if r8
|
4307
|
+
r9 = _nt_name_val_pair
|
4308
|
+
s7 << r9
|
4258
4309
|
end
|
4259
|
-
if
|
4260
|
-
|
4261
|
-
|
4310
|
+
if s7.last
|
4311
|
+
r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
|
4312
|
+
r7.extend(NameValList0)
|
4262
4313
|
else
|
4263
|
-
@index =
|
4264
|
-
|
4314
|
+
@index = i7
|
4315
|
+
r7 = nil
|
4265
4316
|
end
|
4266
|
-
if
|
4267
|
-
|
4317
|
+
if r7
|
4318
|
+
s6 << r7
|
4268
4319
|
else
|
4269
4320
|
break
|
4270
4321
|
end
|
4271
4322
|
end
|
4272
|
-
|
4273
|
-
|
4323
|
+
r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
|
4324
|
+
s4 << r6
|
4274
4325
|
end
|
4275
|
-
if
|
4276
|
-
|
4277
|
-
|
4326
|
+
if s4.last
|
4327
|
+
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
4328
|
+
r4.extend(NameValList1)
|
4278
4329
|
else
|
4279
|
-
@index =
|
4280
|
-
|
4330
|
+
@index = i4
|
4331
|
+
r4 = nil
|
4332
|
+
end
|
4333
|
+
if r4
|
4334
|
+
r3 = r4
|
4335
|
+
else
|
4336
|
+
r3 = instantiate_node(SyntaxNode,input, index...index)
|
4281
4337
|
end
|
4282
4338
|
s0 << r3
|
4283
4339
|
end
|
@@ -110,7 +110,7 @@ module Mail
|
|
110
110
|
end
|
111
111
|
|
112
112
|
rule local_dot_atom_text
|
113
|
-
("."
|
113
|
+
("."* domain_text "."*)+
|
114
114
|
end
|
115
115
|
|
116
116
|
rule domain_text
|
@@ -184,7 +184,7 @@ module Mail
|
|
184
184
|
end
|
185
185
|
|
186
186
|
rule quoted_string
|
187
|
-
CFWS? DQUOTE quoted_content:(FWS? qcontent)
|
187
|
+
CFWS? DQUOTE quoted_content:(FWS? qcontent)* FWS? DQUOTE CFWS?
|
188
188
|
end
|
189
189
|
|
190
190
|
rule qcontent
|
@@ -218,11 +218,26 @@ module Mail
|
|
218
218
|
end
|
219
219
|
|
220
220
|
rule mailbox_list
|
221
|
-
(first_addr:mailbox other_addr:("," addr_value:mailbox)*) / obs_mbox_list
|
221
|
+
(first_addr:mailbox other_addr:(("," / ";") addr_value:mailbox)*) / obs_mbox_list
|
222
222
|
end
|
223
223
|
|
224
224
|
rule mailbox
|
225
|
-
name_addr / addr_spec
|
225
|
+
(name_addr / addr_spec) {
|
226
|
+
def dig_comments(comments, elements)
|
227
|
+
elements.each { |elem|
|
228
|
+
if elem.respond_to?(:comment)
|
229
|
+
comments << elem.comment
|
230
|
+
end
|
231
|
+
dig_comments(comments, elem.elements) if elem.elements
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
def comments
|
236
|
+
comments = []
|
237
|
+
dig_comments(comments, elements)
|
238
|
+
comments
|
239
|
+
end
|
240
|
+
}
|
226
241
|
end
|
227
242
|
|
228
243
|
rule address
|
@@ -244,28 +259,11 @@ module Mail
|
|
244
259
|
end
|
245
260
|
|
246
261
|
} /
|
247
|
-
mailbox
|
248
|
-
|
249
|
-
def dig_comments(comments, elements)
|
250
|
-
elements.each { |elem|
|
251
|
-
if elem.respond_to?(:comment)
|
252
|
-
comments << elem.comment
|
253
|
-
end
|
254
|
-
dig_comments(comments, elem.elements) if elem.elements
|
255
|
-
}
|
256
|
-
end
|
257
|
-
|
258
|
-
def comments
|
259
|
-
comments = []
|
260
|
-
dig_comments(comments, elements)
|
261
|
-
comments
|
262
|
-
end
|
263
|
-
|
264
|
-
}
|
262
|
+
mailbox
|
265
263
|
end
|
266
264
|
|
267
265
|
rule address_list
|
268
|
-
first_addr:address? other_addr:(FWS* "," FWS* addr_value:address?)*
|
266
|
+
first_addr:address? other_addr:(FWS* ("," / ";") FWS* addr_value:address?)*
|
269
267
|
end
|
270
268
|
|
271
269
|
rule date_time
|
@@ -340,7 +338,7 @@ module Mail
|
|
340
338
|
end
|
341
339
|
|
342
340
|
rule name_val_list
|
343
|
-
(CFWS)? (name_val_pair (CFWS name_val_pair)*)
|
341
|
+
(CFWS)? (name_val_pair (CFWS name_val_pair)*)?
|
344
342
|
end
|
345
343
|
|
346
344
|
rule name_val_pair
|
data/lib/mail/part.rb
CHANGED
@@ -38,8 +38,12 @@ module Mail
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def add_required_fields
|
41
|
-
add_content_id unless has_content_id?
|
42
41
|
super
|
42
|
+
add_content_id if !has_content_id? && inline?
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_required_message_fields
|
46
|
+
# Override so we don't add Date, MIME-Version, or Message-ID.
|
43
47
|
end
|
44
48
|
|
45
49
|
def delivery_status_report_part?
|
@@ -113,4 +117,4 @@ module Mail
|
|
113
117
|
|
114
118
|
end
|
115
119
|
|
116
|
-
end
|
120
|
+
end
|
data/lib/mail/parts_list.rb
CHANGED
data/lib/mail/patterns.rb
CHANGED
@@ -8,7 +8,6 @@ module Mail
|
|
8
8
|
|
9
9
|
aspecial = %Q|()<>[]:;@\\,."| # RFC5322
|
10
10
|
tspecial = %Q|()<>@,;:\\"/[]?=| # RFC2045
|
11
|
-
lwsp = %Q| \t\r\n|
|
12
11
|
sp = %Q| |
|
13
12
|
control = %Q|\x00-\x1f\x7f-\xff|
|
14
13
|
|
@@ -23,6 +22,7 @@ module Mail
|
|
23
22
|
FIELD_NAME = /[#{field_name}]+/
|
24
23
|
FIELD_BODY = /.+/
|
25
24
|
FIELD_LINE = /^[#{field_name}]+:\s*.+$/
|
25
|
+
FIELD_SPLIT = /^(#{FIELD_NAME})\s*:\s*(#{FIELD_BODY})?$/
|
26
26
|
HEADER_LINE = /^([#{field_name}]+:\s*.+)$/
|
27
27
|
|
28
28
|
QP_UNSAFE = /[^#{qp_safe}]/
|
data/lib/mail/utilities.rb
CHANGED
@@ -41,28 +41,36 @@ module Mail
|
|
41
41
|
token_safe?( str ) ? str : dquote(str)
|
42
42
|
end
|
43
43
|
|
44
|
-
# Wraps supplied string in double quotes
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
44
|
+
# Wraps supplied string in double quotes and applies \-escaping as necessary,
|
45
|
+
# unless it is already wrapped.
|
46
|
+
#
|
47
|
+
# Example:
|
48
|
+
#
|
49
|
+
# string = 'This is a string'
|
50
|
+
# dquote(string) #=> '"This is a string"'
|
51
|
+
#
|
52
|
+
# string = 'This is "a string"'
|
53
|
+
# dquote(string #=> '"This is \"a string\"'
|
48
54
|
def dquote( str )
|
49
|
-
|
50
|
-
str = match[1] if match
|
51
|
-
# First remove all escaped double quotes:
|
52
|
-
str = str.gsub(/\\"/, '"')
|
53
|
-
# Then wrap and re-escape all double quotes
|
54
|
-
'"' + str.gsub(/["]/n) {|s| '\\' + s } + '"'
|
55
|
+
'"' + unquote(str).gsub(/[\\"]/n) {|s| '\\' + s } + '"'
|
55
56
|
end
|
56
|
-
|
57
|
-
# Unwraps supplied string from inside double quotes
|
58
|
-
#
|
57
|
+
|
58
|
+
# Unwraps supplied string from inside double quotes and
|
59
|
+
# removes any \-escaping.
|
60
|
+
#
|
59
61
|
# Example:
|
60
|
-
#
|
62
|
+
#
|
61
63
|
# string = '"This is a string"'
|
62
64
|
# unquote(string) #=> 'This is a string'
|
65
|
+
#
|
66
|
+
# string = '"This is \"a string\""'
|
67
|
+
# unqoute(string) #=> 'This is "a string"'
|
63
68
|
def unquote( str )
|
64
|
-
|
65
|
-
|
69
|
+
if str =~ /^"(.*?)"$/
|
70
|
+
$1.gsub(/\\(.)/, '\1')
|
71
|
+
else
|
72
|
+
str
|
73
|
+
end
|
66
74
|
end
|
67
75
|
|
68
76
|
# Wraps a string in parenthesis and escapes any that are in the string itself.
|
@@ -135,7 +143,7 @@ module Mail
|
|
135
143
|
# obj1 = :this_IS_an_object
|
136
144
|
# match_to_s( obj1, obj2 ) #=> true
|
137
145
|
def match_to_s( obj1, obj2 )
|
138
|
-
obj1.to_s.
|
146
|
+
obj1.to_s.casecmp(obj2.to_s) == 0
|
139
147
|
end
|
140
148
|
|
141
149
|
# Capitalizes a string that is joined by hyphens correctly.
|
Binary file
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module Mail
|
4
4
|
class Ruby18
|
5
5
|
require 'base64'
|
6
|
+
require 'iconv'
|
6
7
|
|
7
8
|
# Escapes any parenthesis in a string that are unescaped. This can't
|
8
9
|
# use the Ruby 1.9.1 regexp feature of negative look behind so we have
|
@@ -57,7 +58,7 @@ module Mail
|
|
57
58
|
# Ruby 1.8 requires an encoding to work
|
58
59
|
raise ArgumentError, "Must supply an encoding" if encoding.nil?
|
59
60
|
encoding = encoding.to_s.upcase.gsub('_', '-')
|
60
|
-
[Encodings::Base64.encode(str), encoding]
|
61
|
+
[Encodings::Base64.encode(str), fix_encoding(encoding)]
|
61
62
|
end
|
62
63
|
|
63
64
|
def Ruby18.b_value_decode(str)
|
@@ -65,6 +66,7 @@ module Mail
|
|
65
66
|
if match
|
66
67
|
encoding = match[1]
|
67
68
|
str = Ruby18.decode_base64(match[2])
|
69
|
+
str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
|
68
70
|
end
|
69
71
|
str
|
70
72
|
end
|
@@ -80,7 +82,11 @@ module Mail
|
|
80
82
|
match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
|
81
83
|
if match
|
82
84
|
encoding = match[1]
|
83
|
-
|
85
|
+
string = match[2].gsub(/_/, '=20')
|
86
|
+
# Remove trailing = if it exists in a Q encoding
|
87
|
+
string = string.sub(/\=$/, '')
|
88
|
+
str = Encodings::QuotedPrintable.decode(string)
|
89
|
+
str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
|
84
90
|
end
|
85
91
|
str
|
86
92
|
end
|
@@ -94,5 +100,20 @@ module Mail
|
|
94
100
|
language = Configuration.instance.param_encode_language
|
95
101
|
"#{encoding}'#{language}'#{URI.escape(str)}"
|
96
102
|
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def Ruby18.fix_encoding(encoding)
|
107
|
+
case encoding.upcase
|
108
|
+
when 'UTF8'
|
109
|
+
'UTF-8'
|
110
|
+
when 'UTF16', 'UTF-16'
|
111
|
+
'UTF-16BE'
|
112
|
+
when 'UTF32', 'UTF-32'
|
113
|
+
'UTF-32BE'
|
114
|
+
else
|
115
|
+
encoding
|
116
|
+
end
|
117
|
+
end
|
97
118
|
end
|
98
119
|
end
|