1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
require 'mail/message'
require 'mail/part'
require 'mail/fields/common/parameter_hash'
module Mail
class Message
attr_accessor :url_part_number
attr_accessor :rfc822_attachment # when a whole email message is attached as text
attr_accessor :within_rfc822_attachment # for parts within a message attached as text (for getting subject mainly)
attr_accessor :count_parts_count
attr_accessor :count_first_uudecode_count
end
class Part < Message
def inline?
header[:content_disposition].disposition_type == 'inline' if header[:content_disposition] rescue false
end
end
# A patched version of the parameter hash that handles nil values without throwing
# an error.
class ParameterHash < IndifferentHash
def encoded
map.sort { |a,b| a.first.to_s <=> b.first.to_s }.map do |key_name, value|
# The replacement of this commented out line is the change
# unless value.ascii_only?
unless value.nil? || value.ascii_only?
value = Mail::Encodings.param_encode(value)
key_name = "#{key_name}*"
end
%Q{#{key_name}=#{quote_token(value)}}
end.join(";\r\n\s")
end
end
# HACK: Backport encoding fixes for Ruby 1.8 from Mail 2.5
# Can be removed when we no longer support Ruby 1.8
class Ruby18
def Ruby18.b_value_decode(str)
match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
if match
encoding = match[1]
str = Ruby18.decode_base64(match[2])
# Adding and removing trailing spaces is a workaround
# for Iconv.conv throwing an exception if it finds an
# invalid character at the end of the string, even
# with UTF-8//IGNORE:
# http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
begin
str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str + " ")[0...-4]
rescue Iconv::InvalidEncoding
end
end
str
end
def Ruby18.q_value_decode(str)
match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
if match
encoding = match[1]
string = match[2].gsub(/_/, '=20')
# Remove trailing = if it exists in a Q encoding
string = string.sub(/\=$/, '')
str = Encodings::QuotedPrintable.decode(string)
# Adding and removing trailing spaces is a workaround
# for Iconv.conv throwing an exception if it finds an
# invalid character at the end of the string, even
# with UTF-8//IGNORE:
# http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str + " ")[0...-4]
end
str
end
private
def Ruby18.fix_encoding(encoding)
case encoding.upcase
when 'UTF8'
'UTF-8'
else
encoding
end
end
end
class Ruby19
def Ruby19.b_value_decode(str)
match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
if match
charset = match[1]
str = Ruby19.decode_base64(match[2])
# Rescue an ArgumentError arising from an unknown encoding.
begin
str.force_encoding(pick_encoding(charset))
rescue ArgumentError
end
end
decoded = str.encode("utf-8", :invalid => :replace, :replace => "")
decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8")
end
end
end
|