mail 2.6.1 → 2.8.1
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 +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +150 -107
- data/lib/mail/attachments_list.rb +13 -10
- data/lib/mail/body.rb +104 -90
- data/lib/mail/check_delivery_params.rb +55 -10
- data/lib/mail/configuration.rb +3 -0
- data/lib/mail/constants.rb +79 -0
- data/lib/mail/elements/address.rb +96 -108
- data/lib/mail/elements/address_list.rb +13 -30
- data/lib/mail/elements/content_disposition_element.rb +10 -16
- data/lib/mail/elements/content_location_element.rb +9 -13
- data/lib/mail/elements/content_transfer_encoding_element.rb +7 -11
- data/lib/mail/elements/content_type_element.rb +17 -23
- data/lib/mail/elements/date_time_element.rb +8 -15
- data/lib/mail/elements/envelope_from_element.rb +23 -23
- data/lib/mail/elements/message_ids_element.rb +22 -15
- data/lib/mail/elements/mime_version_element.rb +8 -15
- data/lib/mail/elements/phrase_list.rb +13 -10
- data/lib/mail/elements/received_element.rb +28 -19
- data/lib/mail/elements.rb +1 -0
- data/lib/mail/encodings/7bit.rb +10 -14
- data/lib/mail/encodings/8bit.rb +5 -18
- data/lib/mail/encodings/base64.rb +15 -10
- data/lib/mail/encodings/binary.rb +4 -22
- data/lib/mail/encodings/identity.rb +24 -0
- data/lib/mail/encodings/quoted_printable.rb +13 -7
- data/lib/mail/encodings/transfer_encoding.rb +47 -28
- data/lib/mail/encodings/unix_to_unix.rb +20 -0
- data/lib/mail/encodings.rb +102 -92
- data/lib/mail/envelope.rb +12 -14
- data/lib/mail/field.rb +121 -85
- data/lib/mail/field_list.rb +62 -8
- data/lib/mail/fields/bcc_field.rb +42 -48
- data/lib/mail/fields/cc_field.rb +29 -50
- data/lib/mail/fields/comments_field.rb +28 -37
- data/lib/mail/fields/common_address_field.rb +170 -0
- data/lib/mail/fields/common_date_field.rb +58 -0
- data/lib/mail/fields/common_field.rb +77 -0
- data/lib/mail/fields/common_message_id_field.rb +42 -0
- data/lib/mail/fields/content_description_field.rb +8 -14
- data/lib/mail/fields/content_disposition_field.rb +20 -44
- data/lib/mail/fields/content_id_field.rb +25 -51
- data/lib/mail/fields/content_location_field.rb +12 -25
- data/lib/mail/fields/content_transfer_encoding_field.rb +32 -31
- data/lib/mail/fields/content_type_field.rb +51 -80
- data/lib/mail/fields/date_field.rb +24 -52
- data/lib/mail/fields/from_field.rb +29 -50
- data/lib/mail/fields/in_reply_to_field.rb +39 -49
- data/lib/mail/fields/keywords_field.rb +19 -32
- data/lib/mail/fields/message_id_field.rb +26 -71
- data/lib/mail/fields/mime_version_field.rb +20 -30
- data/lib/mail/fields/named_structured_field.rb +11 -0
- data/lib/mail/fields/named_unstructured_field.rb +11 -0
- data/lib/mail/fields/optional_field.rb +10 -7
- data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +16 -13
- data/lib/mail/fields/received_field.rb +44 -57
- data/lib/mail/fields/references_field.rb +36 -49
- data/lib/mail/fields/reply_to_field.rb +29 -50
- data/lib/mail/fields/resent_bcc_field.rb +29 -50
- data/lib/mail/fields/resent_cc_field.rb +29 -50
- data/lib/mail/fields/resent_date_field.rb +6 -30
- data/lib/mail/fields/resent_from_field.rb +29 -50
- data/lib/mail/fields/resent_message_id_field.rb +6 -29
- data/lib/mail/fields/resent_sender_field.rb +28 -57
- data/lib/mail/fields/resent_to_field.rb +29 -50
- data/lib/mail/fields/return_path_field.rb +51 -55
- data/lib/mail/fields/sender_field.rb +35 -56
- data/lib/mail/fields/structured_field.rb +4 -30
- data/lib/mail/fields/subject_field.rb +10 -11
- data/lib/mail/fields/to_field.rb +29 -50
- data/lib/mail/fields/unstructured_field.rb +36 -50
- data/lib/mail/fields.rb +1 -0
- data/lib/mail/header.rb +73 -110
- data/lib/mail/indifferent_hash.rb +1 -0
- data/lib/mail/mail.rb +6 -11
- data/lib/mail/matchers/attachment_matchers.rb +44 -0
- data/lib/mail/matchers/has_sent_mail.rb +53 -9
- data/lib/mail/message.rb +132 -136
- data/lib/mail/multibyte/chars.rb +24 -180
- data/lib/mail/multibyte/unicode.rb +31 -26
- data/lib/mail/multibyte/utils.rb +27 -43
- data/lib/mail/multibyte.rb +56 -16
- data/lib/mail/network/delivery_methods/exim.rb +9 -11
- data/lib/mail/network/delivery_methods/file_delivery.rb +14 -16
- data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +68 -24
- data/lib/mail/network/delivery_methods/smtp.rb +77 -54
- data/lib/mail/network/delivery_methods/smtp_connection.rb +5 -9
- data/lib/mail/network/delivery_methods/test_mailer.rb +9 -9
- data/lib/mail/network/retriever_methods/base.rb +9 -8
- data/lib/mail/network/retriever_methods/imap.rb +21 -7
- data/lib/mail/network/retriever_methods/pop3.rb +6 -3
- data/lib/mail/network/retriever_methods/test_retriever.rb +4 -2
- data/lib/mail/network.rb +2 -0
- data/lib/mail/parser_tools.rb +15 -0
- data/lib/mail/parsers/address_lists_parser.rb +33226 -116
- data/lib/mail/parsers/address_lists_parser.rl +179 -0
- data/lib/mail/parsers/content_disposition_parser.rb +883 -49
- data/lib/mail/parsers/content_disposition_parser.rl +89 -0
- data/lib/mail/parsers/content_location_parser.rb +810 -23
- data/lib/mail/parsers/content_location_parser.rl +78 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +510 -21
- data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
- data/lib/mail/parsers/content_type_parser.rb +1031 -47
- data/lib/mail/parsers/content_type_parser.rl +90 -0
- data/lib/mail/parsers/date_time_parser.rb +879 -24
- data/lib/mail/parsers/date_time_parser.rl +69 -0
- data/lib/mail/parsers/envelope_from_parser.rb +3670 -40
- data/lib/mail/parsers/envelope_from_parser.rl +89 -0
- data/lib/mail/parsers/message_ids_parser.rb +5147 -25
- data/lib/mail/parsers/message_ids_parser.rl +93 -0
- data/lib/mail/parsers/mime_version_parser.rb +498 -26
- data/lib/mail/parsers/mime_version_parser.rl +68 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +872 -21
- data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
- data/lib/mail/parsers/received_parser.rb +8777 -42
- data/lib/mail/parsers/received_parser.rl +91 -0
- data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
- data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
- data/lib/mail/parsers/rfc2045_mime.rl +16 -0
- data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
- data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
- data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
- data/lib/mail/parsers/rfc5322.rl +74 -0
- data/lib/mail/parsers/rfc5322_address.rl +72 -0
- data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
- data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
- data/lib/mail/parsers.rb +12 -25
- data/lib/mail/part.rb +11 -12
- data/lib/mail/parts_list.rb +88 -14
- data/lib/mail/smtp_envelope.rb +57 -0
- data/lib/mail/utilities.rb +377 -40
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +8 -15
- data/lib/mail/yaml.rb +30 -0
- data/lib/mail.rb +9 -32
- metadata +138 -94
- data/CHANGELOG.rdoc +0 -752
- data/CONTRIBUTING.md +0 -60
- data/Dependencies.txt +0 -2
- data/Gemfile +0 -15
- data/Rakefile +0 -29
- data/TODO.rdoc +0 -9
- data/VERSION +0 -4
- data/lib/mail/core_extensions/nil.rb +0 -19
- data/lib/mail/core_extensions/object.rb +0 -13
- data/lib/mail/core_extensions/smtp.rb +0 -24
- data/lib/mail/core_extensions/string/access.rb +0 -145
- data/lib/mail/core_extensions/string/multibyte.rb +0 -78
- data/lib/mail/core_extensions/string.rb +0 -43
- data/lib/mail/fields/common/address_container.rb +0 -16
- data/lib/mail/fields/common/common_address.rb +0 -135
- data/lib/mail/fields/common/common_date.rb +0 -35
- data/lib/mail/fields/common/common_field.rb +0 -57
- data/lib/mail/fields/common/common_message_id.rb +0 -48
- data/lib/mail/multibyte/exceptions.rb +0 -8
- data/lib/mail/parsers/ragel/common.rl +0 -184
- data/lib/mail/parsers/ragel/parser_info.rb +0 -61
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2129
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
- data/lib/mail/parsers/ragel/ruby.rb +0 -39
- data/lib/mail/parsers/ragel.rb +0 -17
- data/lib/mail/patterns.rb +0 -37
- data/lib/mail/version_specific/ruby_1_8.rb +0 -119
- data/lib/mail/version_specific/ruby_1_9.rb +0 -159
@@ -1,37 +0,0 @@
|
|
1
|
-
%%{
|
2
|
-
machine received;
|
3
|
-
|
4
|
-
include rb_actions "rb_actions.rl";
|
5
|
-
include common "../../common.rl";
|
6
|
-
|
7
|
-
getkey data_unpacked[p];
|
8
|
-
|
9
|
-
main := received;
|
10
|
-
}%%
|
11
|
-
|
12
|
-
module Mail
|
13
|
-
module Parsers
|
14
|
-
module Ragel
|
15
|
-
module ReceivedMachine
|
16
|
-
%%write data;
|
17
|
-
|
18
|
-
def self.parse(data)
|
19
|
-
p = 0
|
20
|
-
eof = data.length
|
21
|
-
stack = []
|
22
|
-
|
23
|
-
actions = []
|
24
|
-
data_unpacked = data.bytes.to_a
|
25
|
-
%%write init;
|
26
|
-
%%write exec;
|
27
|
-
|
28
|
-
if p == eof && cs >= %%{ write first_final; }%%
|
29
|
-
return actions, nil
|
30
|
-
else
|
31
|
-
return [], "Only able to parse up to #{data[0..p]}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
%%{
|
2
|
-
machine <%= parser_name %>;
|
3
|
-
|
4
|
-
include rb_actions "rb_actions.rl";
|
5
|
-
include common "../../common.rl";
|
6
|
-
|
7
|
-
getkey data_unpacked[p];
|
8
|
-
|
9
|
-
main := <%= parser_name %>;
|
10
|
-
}%%
|
11
|
-
|
12
|
-
module Mail
|
13
|
-
module Parsers
|
14
|
-
module Ragel
|
15
|
-
module <%= parser_name_cc %>
|
16
|
-
%%write data;
|
17
|
-
|
18
|
-
def self.parse(data)
|
19
|
-
p = 0
|
20
|
-
eof = data.length
|
21
|
-
stack = []
|
22
|
-
|
23
|
-
actions = []
|
24
|
-
data_unpacked = data.bytes.to_a
|
25
|
-
%%write init;
|
26
|
-
%%write exec;
|
27
|
-
|
28
|
-
if p == eof && cs >= %%{ write first_final; }%%
|
29
|
-
return actions, nil
|
30
|
-
else
|
31
|
-
return [], "Only able to parse up to #{data[0..p]}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Mail
|
2
|
-
module Parsers
|
3
|
-
module Ragel
|
4
|
-
module Ruby
|
5
|
-
def self.silence_warnings
|
6
|
-
original_verbose = $VERBOSE
|
7
|
-
$VERBOSE = nil
|
8
|
-
yield
|
9
|
-
$VERBOSE = original_verbose
|
10
|
-
end
|
11
|
-
# Ragel-generated parsers give a lot of warnings
|
12
|
-
# and may cause logs to balloon in size
|
13
|
-
silence_warnings do
|
14
|
-
Mail::Parsers::Ragel::FIELD_PARSERS.each do |field_parser|
|
15
|
-
require "mail/parsers/ragel/ruby/machines/#{field_parser}_machine"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
MACHINE_LIST = {
|
20
|
-
:address_lists => AddressListsMachine,
|
21
|
-
:phrase_lists => PhraseListsMachine,
|
22
|
-
:date_time => DateTimeMachine,
|
23
|
-
:received => ReceivedMachine,
|
24
|
-
:message_ids => MessageIdsMachine,
|
25
|
-
:envelope_from => EnvelopeFromMachine,
|
26
|
-
:mime_version => MimeVersionMachine,
|
27
|
-
:content_type => ContentTypeMachine,
|
28
|
-
:content_disposition => ContentDispositionMachine,
|
29
|
-
:content_transfer_encoding => ContentTransferEncodingMachine,
|
30
|
-
:content_location => ContentLocationMachine
|
31
|
-
}
|
32
|
-
|
33
|
-
def self.parse(machine, string)
|
34
|
-
MACHINE_LIST[machine].parse(string)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/mail/parsers/ragel.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module Mail
|
2
|
-
module Parsers
|
3
|
-
module Ragel
|
4
|
-
require 'mail/parsers/ragel/parser_info'
|
5
|
-
require "mail/parsers/ragel/ruby"
|
6
|
-
|
7
|
-
def self.parse(machine, string)
|
8
|
-
@machine_module ||= Ruby
|
9
|
-
@machine_module.parse(machine, string)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.machine_module=(m)
|
13
|
-
@machine_module = m
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/mail/patterns.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# encoding: us-ascii
|
2
|
-
module Mail
|
3
|
-
module Patterns
|
4
|
-
white_space = %Q|\x9\x20|
|
5
|
-
text = %Q|\x1-\x8\xB\xC\xE-\x7f|
|
6
|
-
field_name = %Q|\x21-\x39\x3b-\x7e|
|
7
|
-
qp_safe = %Q|\x20-\x3c\x3e-\x7e|
|
8
|
-
|
9
|
-
aspecial = %Q|()<>[]:;@\\,."| # RFC5322
|
10
|
-
tspecial = %Q|()<>@,;:\\"/[]?=| # RFC2045
|
11
|
-
sp = %Q| |
|
12
|
-
control = %Q|\x00-\x1f\x7f-\xff|
|
13
|
-
|
14
|
-
if control.respond_to?(:force_encoding)
|
15
|
-
control = control.force_encoding(Encoding::BINARY)
|
16
|
-
end
|
17
|
-
|
18
|
-
CRLF = /\r\n/
|
19
|
-
WSP = /[#{white_space}]/
|
20
|
-
FWS = /#{CRLF}#{WSP}*/
|
21
|
-
TEXT = /[#{text}]/ # + obs-text
|
22
|
-
FIELD_NAME = /[#{field_name}]+/
|
23
|
-
FIELD_PREFIX = /\A(#{FIELD_NAME})/
|
24
|
-
FIELD_BODY = /.+/m
|
25
|
-
FIELD_LINE = /^[#{field_name}]+:\s*.+$/
|
26
|
-
FIELD_SPLIT = /^(#{FIELD_NAME})\s*:\s*(#{FIELD_BODY})?$/
|
27
|
-
HEADER_LINE = /^([#{field_name}]+:\s*.+)$/
|
28
|
-
HEADER_SPLIT = /#{CRLF}(?!#{WSP})/
|
29
|
-
|
30
|
-
QP_UNSAFE = /[^#{qp_safe}]/
|
31
|
-
QP_SAFE = /[#{qp_safe}]/
|
32
|
-
CONTROL_CHAR = /[#{control}]/n
|
33
|
-
ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{sp}]/n
|
34
|
-
PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n
|
35
|
-
TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{sp}]/n
|
36
|
-
end
|
37
|
-
end
|
@@ -1,119 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Mail
|
4
|
-
class Ruby18
|
5
|
-
require 'base64'
|
6
|
-
require 'iconv'
|
7
|
-
|
8
|
-
# Escapes any parenthesis in a string that are unescaped. This can't
|
9
|
-
# use the Ruby 1.9.1 regexp feature of negative look behind so we have
|
10
|
-
# to do two replacement, first unescape everything, then re-escape it
|
11
|
-
def Ruby18.escape_paren( str )
|
12
|
-
re = /\\\)/
|
13
|
-
str = str.gsub(re) { |s| ')'}
|
14
|
-
re = /\\\(/
|
15
|
-
str = str.gsub(re) { |s| '('}
|
16
|
-
re = /([\(\)])/ # Only match unescaped parens
|
17
|
-
str.gsub(re) { |s| '\\' + s }
|
18
|
-
end
|
19
|
-
|
20
|
-
def Ruby18.paren( str )
|
21
|
-
str = $1 if str =~ /^\((.*)?\)$/
|
22
|
-
str = escape_paren( str )
|
23
|
-
'(' + str + ')'
|
24
|
-
end
|
25
|
-
|
26
|
-
def Ruby18.escape_bracket( str )
|
27
|
-
re = /\\\>/
|
28
|
-
str = str.gsub(re) { |s| '>'}
|
29
|
-
re = /\\\</
|
30
|
-
str = str.gsub(re) { |s| '<'}
|
31
|
-
re = /([\<\>])/ # Only match unescaped parens
|
32
|
-
str.gsub(re) { |s| '\\' + s }
|
33
|
-
end
|
34
|
-
|
35
|
-
def Ruby18.bracket( str )
|
36
|
-
str = $1 if str =~ /^\<(.*)?\>$/
|
37
|
-
str = escape_bracket( str )
|
38
|
-
'<' + str + '>'
|
39
|
-
end
|
40
|
-
|
41
|
-
def Ruby18.decode_base64(str)
|
42
|
-
Base64.decode64(str) if str
|
43
|
-
end
|
44
|
-
|
45
|
-
def Ruby18.encode_base64(str)
|
46
|
-
Base64.encode64(str)
|
47
|
-
end
|
48
|
-
|
49
|
-
def Ruby18.has_constant?(klass, string)
|
50
|
-
klass.constants.include?( string )
|
51
|
-
end
|
52
|
-
|
53
|
-
def Ruby18.get_constant(klass, string)
|
54
|
-
klass.const_get( string )
|
55
|
-
end
|
56
|
-
|
57
|
-
def Ruby18.b_value_encode(str, encoding)
|
58
|
-
# Ruby 1.8 requires an encoding to work
|
59
|
-
raise ArgumentError, "Must supply an encoding" if encoding.nil?
|
60
|
-
encoding = encoding.to_s.upcase.gsub('_', '-')
|
61
|
-
[Encodings::Base64.encode(str), fix_encoding(encoding)]
|
62
|
-
end
|
63
|
-
|
64
|
-
def Ruby18.b_value_decode(str)
|
65
|
-
match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
|
66
|
-
if match
|
67
|
-
encoding = match[1]
|
68
|
-
str = Ruby18.decode_base64(match[2])
|
69
|
-
str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
|
70
|
-
end
|
71
|
-
str
|
72
|
-
end
|
73
|
-
|
74
|
-
def Ruby18.q_value_encode(str, encoding)
|
75
|
-
# Ruby 1.8 requires an encoding to work
|
76
|
-
raise ArgumentError, "Must supply an encoding" if encoding.nil?
|
77
|
-
encoding = encoding.to_s.upcase.gsub('_', '-')
|
78
|
-
[Encodings::QuotedPrintable.encode(str), encoding]
|
79
|
-
end
|
80
|
-
|
81
|
-
def Ruby18.q_value_decode(str)
|
82
|
-
match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
|
83
|
-
if match
|
84
|
-
encoding = match[1]
|
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)
|
90
|
-
end
|
91
|
-
str
|
92
|
-
end
|
93
|
-
|
94
|
-
def Ruby18.param_decode(str, encoding)
|
95
|
-
URI.unescape(str)
|
96
|
-
end
|
97
|
-
|
98
|
-
def Ruby18.param_encode(str)
|
99
|
-
encoding = $KCODE.to_s.downcase
|
100
|
-
language = Configuration.instance.param_encode_language
|
101
|
-
"#{encoding}'#{language}'#{URI.escape(str)}"
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
|
-
def Ruby18.fix_encoding(encoding)
|
107
|
-
case encoding.upcase
|
108
|
-
when 'UTF8', 'UTF_8'
|
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
|
118
|
-
end
|
119
|
-
end
|
@@ -1,159 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Mail
|
4
|
-
class Ruby19
|
5
|
-
|
6
|
-
# Escapes any parenthesis in a string that are unescaped this uses
|
7
|
-
# a Ruby 1.9.1 regexp feature of negative look behind
|
8
|
-
def Ruby19.escape_paren( str )
|
9
|
-
re = /(?<!\\)([\(\)])/ # Only match unescaped parens
|
10
|
-
str.gsub(re) { |s| '\\' + s }
|
11
|
-
end
|
12
|
-
|
13
|
-
def Ruby19.paren( str )
|
14
|
-
str = $1 if str =~ /^\((.*)?\)$/
|
15
|
-
str = escape_paren( str )
|
16
|
-
'(' + str + ')'
|
17
|
-
end
|
18
|
-
|
19
|
-
def Ruby19.escape_bracket( str )
|
20
|
-
re = /(?<!\\)([\<\>])/ # Only match unescaped brackets
|
21
|
-
str.gsub(re) { |s| '\\' + s }
|
22
|
-
end
|
23
|
-
|
24
|
-
def Ruby19.bracket( str )
|
25
|
-
str = $1 if str =~ /^\<(.*)?\>$/
|
26
|
-
str = escape_bracket( str )
|
27
|
-
'<' + str + '>'
|
28
|
-
end
|
29
|
-
|
30
|
-
def Ruby19.decode_base64(str)
|
31
|
-
str.unpack( 'm' ).first
|
32
|
-
end
|
33
|
-
|
34
|
-
def Ruby19.encode_base64(str)
|
35
|
-
[str].pack( 'm' )
|
36
|
-
end
|
37
|
-
|
38
|
-
def Ruby19.has_constant?(klass, string)
|
39
|
-
klass.const_defined?( string, false )
|
40
|
-
end
|
41
|
-
|
42
|
-
def Ruby19.get_constant(klass, string)
|
43
|
-
klass.const_get( string )
|
44
|
-
end
|
45
|
-
|
46
|
-
def Ruby19.b_value_encode(str, encoding = nil)
|
47
|
-
encoding = str.encoding.to_s
|
48
|
-
[Ruby19.encode_base64(str), encoding]
|
49
|
-
end
|
50
|
-
|
51
|
-
def Ruby19.b_value_decode(str)
|
52
|
-
match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
|
53
|
-
if match
|
54
|
-
charset = match[1]
|
55
|
-
str = Ruby19.decode_base64(match[2])
|
56
|
-
str.force_encoding(pick_encoding(charset))
|
57
|
-
end
|
58
|
-
decoded = str.encode("utf-8", :invalid => :replace, :replace => "")
|
59
|
-
decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8")
|
60
|
-
end
|
61
|
-
|
62
|
-
def Ruby19.q_value_encode(str, encoding = nil)
|
63
|
-
encoding = str.encoding.to_s
|
64
|
-
[Encodings::QuotedPrintable.encode(str), encoding]
|
65
|
-
end
|
66
|
-
|
67
|
-
def Ruby19.q_value_decode(str)
|
68
|
-
match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
|
69
|
-
if match
|
70
|
-
charset = match[1]
|
71
|
-
string = match[2].gsub(/_/, '=20')
|
72
|
-
# Remove trailing = if it exists in a Q encoding
|
73
|
-
string = string.sub(/\=$/, '')
|
74
|
-
str = Encodings::QuotedPrintable.decode(string)
|
75
|
-
str.force_encoding(pick_encoding(charset))
|
76
|
-
# We assume that binary strings hold utf-8 directly to work around
|
77
|
-
# jruby/jruby#829 which subtly changes String#encode semantics.
|
78
|
-
str.force_encoding('utf-8') if str.encoding == Encoding::ASCII_8BIT
|
79
|
-
end
|
80
|
-
decoded = str.encode("utf-8", :invalid => :replace, :replace => "")
|
81
|
-
decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8")
|
82
|
-
rescue Encoding::UndefinedConversionError
|
83
|
-
str.dup.force_encoding("utf-8")
|
84
|
-
end
|
85
|
-
|
86
|
-
def Ruby19.param_decode(str, encoding)
|
87
|
-
string = uri_parser.unescape(str)
|
88
|
-
string.force_encoding(encoding) if encoding
|
89
|
-
string
|
90
|
-
end
|
91
|
-
|
92
|
-
def Ruby19.param_encode(str)
|
93
|
-
encoding = str.encoding.to_s.downcase
|
94
|
-
language = Configuration.instance.param_encode_language
|
95
|
-
"#{encoding}'#{language}'#{uri_parser.escape(str)}"
|
96
|
-
end
|
97
|
-
|
98
|
-
def Ruby19.uri_parser
|
99
|
-
@uri_parser ||= URI::Parser.new
|
100
|
-
end
|
101
|
-
|
102
|
-
# Pick a Ruby encoding corresponding to the message charset. Most
|
103
|
-
# charsets have a Ruby encoding, but some need manual aliasing here.
|
104
|
-
#
|
105
|
-
# TODO: add this as a test somewhere:
|
106
|
-
# Encoding.list.map { |e| [e.to_s.upcase == pick_encoding(e.to_s.downcase.gsub("-", "")), e.to_s] }.select {|a,b| !b}
|
107
|
-
# Encoding.list.map { |e| [e.to_s == pick_encoding(e.to_s), e.to_s] }.select {|a,b| !b}
|
108
|
-
def Ruby19.pick_encoding(charset)
|
109
|
-
case charset
|
110
|
-
|
111
|
-
# ISO-8859-8-I etc. http://en.wikipedia.org/wiki/ISO-8859-8-I
|
112
|
-
when /^iso-?8859-(\d+)(-i)?$/i
|
113
|
-
"ISO-8859-#{$1}"
|
114
|
-
|
115
|
-
# ISO-8859-15, ISO-2022-JP and alike
|
116
|
-
when /iso-?(\d{4})-?(\w{1,2})/i
|
117
|
-
"ISO-#{$1}-#{$2}"
|
118
|
-
|
119
|
-
# "ISO-2022-JP-KDDI" and alike
|
120
|
-
when /iso-?(\d{4})-?(\w{1,2})-?(\w*)/i
|
121
|
-
"ISO-#{$1}-#{$2}-#{$3}"
|
122
|
-
|
123
|
-
# UTF-8, UTF-32BE and alike
|
124
|
-
when /utf[\-_]?(\d{1,2})?(\w{1,2})/i
|
125
|
-
"UTF-#{$1}#{$2}".gsub(/\A(UTF-(?:16|32))\z/, '\\1BE')
|
126
|
-
|
127
|
-
# Windows-1252 and alike
|
128
|
-
when /Windows-?(.*)/i
|
129
|
-
"Windows-#{$1}"
|
130
|
-
|
131
|
-
when /^8bit$/
|
132
|
-
Encoding::ASCII_8BIT
|
133
|
-
|
134
|
-
# alternatives/misspellings of us-ascii seen in the wild
|
135
|
-
when /^iso-?646(-us)?$/i, /us=ascii/i
|
136
|
-
Encoding::ASCII
|
137
|
-
|
138
|
-
# Microsoft-specific alias for MACROMAN
|
139
|
-
when /^macintosh$/i
|
140
|
-
Encoding::MACROMAN
|
141
|
-
|
142
|
-
# Microsoft-specific alias for CP949 (Korean)
|
143
|
-
when 'ks_c_5601-1987'
|
144
|
-
Encoding::CP949
|
145
|
-
|
146
|
-
# Wrongly written Shift_JIS (Japanese)
|
147
|
-
when 'shift-jis'
|
148
|
-
Encoding::Shift_JIS
|
149
|
-
|
150
|
-
# GB2312 (Chinese charset) is a subset of GB18030 (its replacement)
|
151
|
-
when /gb2312/i
|
152
|
-
Encoding::GB18030
|
153
|
-
|
154
|
-
else
|
155
|
-
charset
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|