sisimai 4.22.7 → 4.23.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sisimai might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ChangeLog.md +15 -0
- data/README-JA.md +13 -8
- data/README.md +14 -9
- data/lib/sisimai.rb +11 -12
- data/lib/sisimai/address.rb +13 -23
- data/lib/sisimai/arf.rb +10 -12
- data/lib/sisimai/bite/email/activehunter.rb +5 -9
- data/lib/sisimai/bite/email/amazonses.rb +12 -18
- data/lib/sisimai/bite/email/amazonworkmail.rb +7 -12
- data/lib/sisimai/bite/email/aol.rb +10 -16
- data/lib/sisimai/bite/email/apachejames.rb +8 -12
- data/lib/sisimai/bite/email/bigfoot.rb +10 -15
- data/lib/sisimai/bite/email/biglobe.rb +7 -11
- data/lib/sisimai/bite/email/courier.rb +11 -15
- data/lib/sisimai/bite/email/domino.rb +8 -13
- data/lib/sisimai/bite/email/einsundeins.rb +7 -11
- data/lib/sisimai/bite/email/exchange2003.rb +11 -15
- data/lib/sisimai/bite/email/exchange2007.rb +7 -11
- data/lib/sisimai/bite/email/exim.rb +20 -27
- data/lib/sisimai/bite/email/ezweb.rb +13 -22
- data/lib/sisimai/bite/email/facebook.rb +7 -10
- data/lib/sisimai/bite/email/fml.rb +4 -7
- data/lib/sisimai/bite/email/gmx.rb +7 -12
- data/lib/sisimai/bite/email/google.rb +6 -12
- data/lib/sisimai/bite/email/gsuite.rb +11 -18
- data/lib/sisimai/bite/email/imailserver.rb +6 -10
- data/lib/sisimai/bite/email/interscanmss.rb +7 -11
- data/lib/sisimai/bite/email/kddi.rb +10 -16
- data/lib/sisimai/bite/email/mailfoundry.rb +6 -9
- data/lib/sisimai/bite/email/mailmarshalsmtp.rb +6 -10
- data/lib/sisimai/bite/email/mailru.rb +12 -16
- data/lib/sisimai/bite/email/mcafee.rb +5 -9
- data/lib/sisimai/bite/email/messagelabs.rb +7 -10
- data/lib/sisimai/bite/email/messagingserver.rb +8 -14
- data/lib/sisimai/bite/email/mfilter.rb +6 -10
- data/lib/sisimai/bite/email/mxlogic.rb +11 -17
- data/lib/sisimai/bite/email/notes.rb +9 -13
- data/lib/sisimai/bite/email/office365.rb +8 -13
- data/lib/sisimai/bite/email/opensmtpd.rb +7 -11
- data/lib/sisimai/bite/email/outlook.rb +9 -13
- data/lib/sisimai/bite/email/postfix.rb +12 -18
- data/lib/sisimai/bite/email/qmail.rb +10 -15
- data/lib/sisimai/bite/email/receivingses.rb +10 -17
- data/lib/sisimai/bite/email/sendgrid.rb +8 -14
- data/lib/sisimai/bite/email/sendmail.rb +8 -12
- data/lib/sisimai/bite/email/surfcontrol.rb +5 -9
- data/lib/sisimai/bite/email/userdefined.rb +5 -8
- data/lib/sisimai/bite/email/v5sendmail.rb +7 -11
- data/lib/sisimai/bite/email/verizon.rb +14 -28
- data/lib/sisimai/bite/email/x1.rb +5 -8
- data/lib/sisimai/bite/email/x2.rb +5 -8
- data/lib/sisimai/bite/email/x3.rb +5 -9
- data/lib/sisimai/bite/email/x4.rb +10 -14
- data/lib/sisimai/bite/email/x5.rb +6 -11
- data/lib/sisimai/bite/email/yahoo.rb +6 -11
- data/lib/sisimai/bite/email/yandex.rb +8 -12
- data/lib/sisimai/bite/email/zoho.rb +7 -12
- data/lib/sisimai/bite/json/amazonses.rb +6 -12
- data/lib/sisimai/bite/json/sendgrid.rb +1 -7
- data/lib/sisimai/data.rb +26 -34
- data/lib/sisimai/datetime.rb +5 -5
- data/lib/sisimai/mail.rb +9 -3
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +1 -1
- data/lib/sisimai/mail/memory.rb +47 -0
- data/lib/sisimai/mail/stdin.rb +1 -1
- data/lib/sisimai/mda.rb +7 -10
- data/lib/sisimai/message.rb +4 -6
- data/lib/sisimai/message/email.rb +16 -24
- data/lib/sisimai/message/json.rb +3 -5
- data/lib/sisimai/mime.rb +13 -18
- data/lib/sisimai/order/email.rb +5 -8
- data/lib/sisimai/order/json.rb +2 -2
- data/lib/sisimai/reason.rb +3 -7
- data/lib/sisimai/reason/blocked.rb +0 -4
- data/lib/sisimai/reason/contenterror.rb +1 -1
- data/lib/sisimai/reason/exceedlimit.rb +2 -5
- data/lib/sisimai/reason/expired.rb +1 -1
- data/lib/sisimai/reason/filtered.rb +1 -4
- data/lib/sisimai/reason/hasmoved.rb +1 -4
- data/lib/sisimai/reason/hostunknown.rb +1 -4
- data/lib/sisimai/reason/mailboxfull.rb +2 -5
- data/lib/sisimai/reason/mesgtoobig.rb +1 -4
- data/lib/sisimai/reason/networkerror.rb +1 -1
- data/lib/sisimai/reason/norelaying.rb +1 -4
- data/lib/sisimai/reason/notaccept.rb +1 -3
- data/lib/sisimai/reason/onhold.rb +1 -5
- data/lib/sisimai/reason/policyviolation.rb +1 -1
- data/lib/sisimai/reason/rejected.rb +2 -6
- data/lib/sisimai/reason/spamdetected.rb +1 -5
- data/lib/sisimai/reason/suspend.rb +2 -5
- data/lib/sisimai/reason/syntaxerror.rb +0 -3
- data/lib/sisimai/reason/systemerror.rb +1 -1
- data/lib/sisimai/reason/systemfull.rb +1 -1
- data/lib/sisimai/reason/toomanyconn.rb +1 -5
- data/lib/sisimai/reason/userunknown.rb +1 -4
- data/lib/sisimai/reason/vacation.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +1 -1
- data/lib/sisimai/rfc2606.rb +3 -3
- data/lib/sisimai/rfc3464.rb +12 -20
- data/lib/sisimai/rfc3834.rb +1 -10
- data/lib/sisimai/rfc5322.rb +4 -6
- data/lib/sisimai/rhost.rb +0 -4
- data/lib/sisimai/rhost/exchangeonline.rb +5 -7
- data/lib/sisimai/rhost/franceptt.rb +1 -3
- data/lib/sisimai/rhost/godaddy.rb +2 -4
- data/lib/sisimai/rhost/googleapps.rb +2 -4
- data/lib/sisimai/rhost/kddi.rb +0 -3
- data/lib/sisimai/smtp/error.rb +0 -3
- data/lib/sisimai/smtp/reply.rb +5 -8
- data/lib/sisimai/smtp/status.rb +3 -4
- data/lib/sisimai/string.rb +13 -20
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/email-office365-09.eml +596 -0
- data/set-of-emails/maildir/bsd/email-office365-10.eml +594 -0
- data/set-of-emails/maildir/bsd/email-postfix-45.eml +76 -0
- metadata +6 -2
data/lib/sisimai/datetime.rb
CHANGED
@@ -200,7 +200,7 @@ module Sisimai
|
|
200
200
|
elsif cr = argv1.match(/\A(\d+|\d+[.]\d+)?([#{mathconsts}])([#{unitoftime}])?\z/)
|
201
201
|
# 1pd, 1.5pw
|
202
202
|
n = cr[1].to_f || 1
|
203
|
-
n = 1 if n.to_i
|
203
|
+
n = 1 if n.to_i == 0
|
204
204
|
m = MathematicalConstant[cr[2].to_sym].to_f
|
205
205
|
u = cr[3] || 'd'
|
206
206
|
getseconds = n * m * TimeUnit[u.to_sym].to_f
|
@@ -278,11 +278,11 @@ module Sisimai
|
|
278
278
|
# parse("Tue, Nov 3 2015 2:2:2") #=> Tue, 3 Nov 2015 02:02:02 +0900
|
279
279
|
def parse(argv1)
|
280
280
|
return nil unless argv1.is_a?(::String)
|
281
|
-
return nil
|
281
|
+
return nil if argv1.empty?
|
282
282
|
|
283
283
|
datestring = argv1
|
284
|
-
datestring
|
285
|
-
datestring
|
284
|
+
datestring.sub!(/[,](\d+)/, ', \1') # Thu,13 -> Thu, 13
|
285
|
+
datestring.sub!(/(\d{1,2}),/, '\1') # Apr,29 -> Apr 29
|
286
286
|
timetokens = datestring.split(' ')
|
287
287
|
afternoon1 = 0 # (Integer) After noon flag
|
288
288
|
altervalue = {} # (Hash) To store alternative values
|
@@ -299,7 +299,7 @@ module Sisimai
|
|
299
299
|
# Parse each piece of time
|
300
300
|
if p =~ /\A[A-Z][a-z]{2}[,]?\z/
|
301
301
|
# Day of week or Day of week; Thu, Apr, ...
|
302
|
-
p.chop if p.
|
302
|
+
p.chop if p.size == 4 # Thu, -> Thu
|
303
303
|
|
304
304
|
if DayOfWeek[:abbr].include?(p)
|
305
305
|
# Day of week; Mon, Thu, Sun,...
|
data/lib/sisimai/mail.rb
CHANGED
@@ -8,7 +8,7 @@ module Sisimai
|
|
8
8
|
:type, # [String] Data type: mailbox, maildir, or stdin
|
9
9
|
]
|
10
10
|
@@rwaccessors = [
|
11
|
-
:mail, # [Sisimai::Mail::Mbox,
|
11
|
+
:mail, # [Sisimai::Mail::[Mbox,Maildir,Memory,STDIN]] Object
|
12
12
|
]
|
13
13
|
@@roaccessors.each { |e| attr_reader e }
|
14
14
|
@@rwaccessors.each { |e| attr_accessor e }
|
@@ -29,7 +29,7 @@ module Sisimai
|
|
29
29
|
parameter['path'] = $stdin
|
30
30
|
else
|
31
31
|
# The argumenet is a mailbox or a Maildir/.
|
32
|
-
mediatype = File.ftype(argv1)
|
32
|
+
mediatype = argv1.include?("\n") ? 'memory' : File.ftype(argv1)
|
33
33
|
|
34
34
|
if mediatype == 'file'
|
35
35
|
# The argument is a file, it is an mbox or email file in Maildir/
|
@@ -40,6 +40,12 @@ module Sisimai
|
|
40
40
|
# The agument is not a file, it is a Maildir/
|
41
41
|
classname = self.class.to_s << '::Maildir'
|
42
42
|
parameter['type'] = 'maildir'
|
43
|
+
|
44
|
+
elsif mediatype == 'memory'
|
45
|
+
# The argument is an email string
|
46
|
+
classname = self.class.to_s << '::Memory'
|
47
|
+
parameter['type'] = 'memory'
|
48
|
+
parameter['path'] = 'MEMORY'
|
43
49
|
end
|
44
50
|
end
|
45
51
|
elsif argv1.is_a?(IO)
|
@@ -52,7 +58,7 @@ module Sisimai
|
|
52
58
|
|
53
59
|
classpath = classname.gsub('::', '/').downcase
|
54
60
|
require classpath
|
55
|
-
parameter['mail'] = Module.const_get(classname).new(
|
61
|
+
parameter['mail'] = Module.const_get(classname).new(argv1)
|
56
62
|
|
57
63
|
@path = parameter['path']
|
58
64
|
@type = parameter['type']
|
data/lib/sisimai/mail/maildir.rb
CHANGED
@@ -48,9 +48,7 @@ module Sisimai
|
|
48
48
|
# Read each file in the directory
|
49
49
|
next if r == '.' || r == '..'
|
50
50
|
|
51
|
-
emailindir = self.dir + '/' + r
|
52
|
-
emailindir = emailindir.squeeze('/')
|
53
|
-
|
51
|
+
emailindir = (self.dir + '/' + r).squeeze('/')
|
54
52
|
next unless File.ftype(emailindir) == 'file'
|
55
53
|
next unless File.size(emailindir) > 0
|
56
54
|
next unless File.readable?(emailindir)
|
data/lib/sisimai/mail/mbox.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Sisimai
|
2
|
+
class Mail
|
3
|
+
# Sisimai::Mail::Memory is a class for reading an email string
|
4
|
+
class Memory
|
5
|
+
# Imported from p5-Sisimail/lib/Sisimai/Mail/Memory.pm
|
6
|
+
@@roaccessors = [
|
7
|
+
:size, # [Integer] data size of the email text
|
8
|
+
]
|
9
|
+
@@rwaccessors = [
|
10
|
+
:data, # [Array] Entire bounce mail message
|
11
|
+
:offset, # [Integer] Index of ":data"
|
12
|
+
]
|
13
|
+
@@roaccessors.each { |e| attr_reader e }
|
14
|
+
@@rwaccessors.each { |e| attr_accessor e }
|
15
|
+
|
16
|
+
# Constructor of Sisimai::Mail::Memory
|
17
|
+
# @param [String] argv1 Entire email string
|
18
|
+
# @return [Sisimai::Mail::Memory,Nil] Object or nil if the argument is
|
19
|
+
# not specified or does not exist
|
20
|
+
def initialize(argv1)
|
21
|
+
raise 'is not a String' unless argv1.is_a? ::String
|
22
|
+
raise 'is empty' if argv1.empty?
|
23
|
+
|
24
|
+
@size = argv1.size
|
25
|
+
@data = []
|
26
|
+
@offset = 0
|
27
|
+
|
28
|
+
if argv1.start_with?('From ')
|
29
|
+
# UNIX mbox
|
30
|
+
@data = argv1.split(/^From /).map! { |e| e = 'From ' + e }
|
31
|
+
@data.shift
|
32
|
+
else
|
33
|
+
@data = [argv1]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Memory reader, works as an iterator.
|
38
|
+
# @return [String] Contents of a bounce mail
|
39
|
+
def read
|
40
|
+
return nil if self.data.empty?
|
41
|
+
self.offset += 1
|
42
|
+
return self.data.shift
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
data/lib/sisimai/mail/stdin.rb
CHANGED
data/lib/sisimai/mda.rb
CHANGED
@@ -86,10 +86,6 @@ module Sisimai
|
|
86
86
|
# or nil if it failed to parse or the
|
87
87
|
# arguments are missing
|
88
88
|
def scan(mhead, mbody)
|
89
|
-
return nil unless mhead
|
90
|
-
return nil unless mbody
|
91
|
-
return nil if mhead.keys.size.zero?
|
92
|
-
return nil if mbody.empty?
|
93
89
|
return nil unless mhead['from'].downcase.start_with?('mail delivery subsystem','mailer-daemon', 'postmaster')
|
94
90
|
|
95
91
|
agentname0 = '' # [String] MDA name
|
@@ -102,7 +98,7 @@ module Sisimai
|
|
102
98
|
# Check each line with each MDA's symbol regular expression.
|
103
99
|
if agentname0 == ''
|
104
100
|
# Try to match with each regular expression
|
105
|
-
next
|
101
|
+
next if e.empty?
|
106
102
|
next unless e =~ MarkingsOf[:message]
|
107
103
|
|
108
104
|
AgentNames.each_key do |f|
|
@@ -115,17 +111,18 @@ module Sisimai
|
|
115
111
|
|
116
112
|
# Append error message lines to @linebuffer
|
117
113
|
linebuffer << e
|
118
|
-
break
|
114
|
+
break if e.empty?
|
119
115
|
end
|
120
|
-
return nil
|
121
|
-
return nil
|
116
|
+
return nil if agentname0.empty?
|
117
|
+
return nil if linebuffer.empty?
|
122
118
|
|
123
119
|
MessagesOf[agentname0.to_sym].each_key do |e|
|
124
120
|
# Detect an error reason from message patterns of the MDA.
|
125
|
-
linebuffer.
|
121
|
+
duplicated = linebuffer.dup
|
122
|
+
while f = duplicated.shift do
|
126
123
|
# Whether the error message include each message defined in $MessagesOf
|
127
124
|
g = f.downcase
|
128
|
-
next unless MessagesOf[agentname0.to_sym][e].
|
125
|
+
next unless MessagesOf[agentname0.to_sym][e].any? { |a| g.include?(a) }
|
129
126
|
reasonname = e.to_s
|
130
127
|
bouncemesg = f
|
131
128
|
break
|
data/lib/sisimai/message.rb
CHANGED
@@ -5,12 +5,11 @@ module Sisimai
|
|
5
5
|
# method is not a bounce email, the method returns nil.
|
6
6
|
class Message
|
7
7
|
# Imported from p5-Sisimail/lib/Sisimai/Message.pm
|
8
|
-
require 'sisimai/arf'
|
9
|
-
require 'sisimai/mime'
|
10
8
|
require 'sisimai/order'
|
11
9
|
require 'sisimai/string'
|
12
|
-
require 'sisimai/
|
10
|
+
require 'sisimai/address'
|
13
11
|
require 'sisimai/rfc5322'
|
12
|
+
require 'sisimai/smtp/error'
|
14
13
|
|
15
14
|
@@rwaccessors = [
|
16
15
|
:from, # [String] UNIX From line
|
@@ -41,9 +40,8 @@ module Sisimai
|
|
41
40
|
|
42
41
|
if input == 'email'
|
43
42
|
# Sisimai::Message::Email
|
44
|
-
return nil
|
45
|
-
email = email.scrub('?')
|
46
|
-
email = email.gsub("\r\n", "\n")
|
43
|
+
return nil if email.empty?
|
44
|
+
email = email.scrub('?').gsub("\r\n", "\n")
|
47
45
|
child = 'Sisimai::Message::Email'
|
48
46
|
|
49
47
|
elsif input == 'json'
|
@@ -8,9 +8,7 @@ module Sisimai
|
|
8
8
|
# Imported from p5-Sisimail/lib/Sisimai/Message/Email.pm
|
9
9
|
require 'sisimai/arf'
|
10
10
|
require 'sisimai/mime'
|
11
|
-
require 'sisimai/string'
|
12
11
|
require 'sisimai/rfc3834'
|
13
|
-
require 'sisimai/rfc5322'
|
14
12
|
require 'sisimai/order/email'
|
15
13
|
|
16
14
|
@@ToBeLoaded = []
|
@@ -73,7 +71,7 @@ module Sisimai
|
|
73
71
|
|
74
72
|
# 3. Check headers for detecting MTA modules
|
75
73
|
if headerargv['tryonfirst'].empty?
|
76
|
-
headerargv['tryonfirst']
|
74
|
+
headerargv['tryonfirst'] += Sisimai::Message::Email.makeorder(processing['header'])
|
77
75
|
end
|
78
76
|
|
79
77
|
# 4. Rewrite message body for detecting the bounce reason
|
@@ -121,7 +119,7 @@ module Sisimai
|
|
121
119
|
next unless argvs[e].is_a? Array
|
122
120
|
next if argvs[e].empty?
|
123
121
|
|
124
|
-
modulelist
|
122
|
+
modulelist += argvs['order'] if e == 'order'
|
125
123
|
next unless e == 'load'
|
126
124
|
|
127
125
|
# Load user defined MTA module
|
@@ -143,7 +141,7 @@ module Sisimai
|
|
143
141
|
end
|
144
142
|
end
|
145
143
|
|
146
|
-
modulelist.
|
144
|
+
while e = modulelist.shift do
|
147
145
|
# Append the custom order of MTA modules
|
148
146
|
next if tobeloaded.index(e)
|
149
147
|
tobeloaded << e
|
@@ -158,9 +156,9 @@ module Sisimai
|
|
158
156
|
def self.divideup(email)
|
159
157
|
return {} if email.empty?
|
160
158
|
|
161
|
-
email
|
162
|
-
email
|
163
|
-
email
|
159
|
+
email.scrub!('?')
|
160
|
+
email.gsub!(/\r\n/, "\n") if email.include?("\r\n")
|
161
|
+
email.gsub!(/[ \t]+$/, '') if email =~ /[ \t]+$/
|
164
162
|
|
165
163
|
hasdivided = email.split("\n")
|
166
164
|
return {} if hasdivided.empty?
|
@@ -219,7 +217,7 @@ module Sisimai
|
|
219
217
|
RFC3834Set.each { |e| allheaders[e] = true }
|
220
218
|
MultiHeads.each_key { |e| structured[e.downcase] = [] }
|
221
219
|
extheaders.each_key { |e| allheaders[e] = true }
|
222
|
-
|
220
|
+
unless extrafield.empty?
|
223
221
|
extrafield.each { |e| allheaders[e.downcase] = true }
|
224
222
|
end
|
225
223
|
|
@@ -236,8 +234,7 @@ module Sisimai
|
|
236
234
|
if MultiHeads.key?(currheader)
|
237
235
|
# Such as 'Received' header, there are multiple headers in a single
|
238
236
|
# email message.
|
239
|
-
rhs = rhs.tr("\t", ' ')
|
240
|
-
rhs = rhs.squeeze(' ')
|
237
|
+
rhs = rhs.tr("\t", ' ').squeeze(' ')
|
241
238
|
structured[currheader] << rhs
|
242
239
|
else
|
243
240
|
# Other headers except "Received" and so on
|
@@ -282,9 +279,7 @@ module Sisimai
|
|
282
279
|
SubjectTab.each_key do |e|
|
283
280
|
# Get MTA list from the subject header
|
284
281
|
next unless title.include?(e)
|
285
|
-
|
286
|
-
# Matched and push MTA list
|
287
|
-
order.concat(SubjectTab[e])
|
282
|
+
order += SubjectTab[e] # Matched and push MTA list
|
288
283
|
break
|
289
284
|
end
|
290
285
|
return order
|
@@ -298,8 +293,7 @@ module Sisimai
|
|
298
293
|
|
299
294
|
# 1. Scrub to avoid "invalid byte sequence in UTF-8" exception (#82)
|
300
295
|
# 2. Convert from string to hash reference
|
301
|
-
heads = heads.scrub('?')
|
302
|
-
heads = heads.gsub(/^[>]+[ ]/m, '')
|
296
|
+
heads = heads.scrub('?').gsub(/^[>]+[ ]/m, '')
|
303
297
|
|
304
298
|
takenapart = {}
|
305
299
|
hasdivided = heads.split("\n")
|
@@ -335,8 +329,7 @@ module Sisimai
|
|
335
329
|
mimeborder[previousfn] = true
|
336
330
|
else
|
337
331
|
# ASCII Characters only: Not MIME-Encoded
|
338
|
-
|
339
|
-
takenapart[previousfn] << e
|
332
|
+
takenapart[previousfn] << e.lstrip
|
340
333
|
mimeborder[previousfn] ||= false
|
341
334
|
end
|
342
335
|
end
|
@@ -461,11 +454,11 @@ module Sisimai
|
|
461
454
|
# Get the original text when the subject begins from 'fwd:' or 'fw:'
|
462
455
|
if mailheader['subject'].downcase =~ /\A[ \t]*fwd?:/
|
463
456
|
# Delete quoted strings, quote symbols(>)
|
464
|
-
bodystring = bodystring.gsub(/^[>]+[ ]/m, '')
|
465
|
-
bodystring = bodystring.gsub(/^[>]$/m, '')
|
457
|
+
bodystring = bodystring.gsub(/^[>]+[ ]/m, '').gsub(/^[>]$/m, '')
|
466
458
|
end
|
467
459
|
bodystring << EndOfEmail
|
468
460
|
haveloaded = {}
|
461
|
+
defaultset = DefaultSet.dup
|
469
462
|
scannedset = nil
|
470
463
|
|
471
464
|
catch :SCANNER do
|
@@ -483,16 +476,15 @@ module Sisimai
|
|
483
476
|
throw :SCANNER if scannedset
|
484
477
|
end
|
485
478
|
|
486
|
-
tobeloaded.
|
479
|
+
while r = tobeloaded.shift do
|
487
480
|
# Call user defined MTA modules
|
488
481
|
next if haveloaded[r]
|
489
|
-
#require r.gsub('::', '/').downcase
|
490
482
|
scannedset = Module.const_get(r).scan(mailheader, bodystring)
|
491
483
|
haveloaded[r] = true
|
492
484
|
throw :SCANNER if scannedset
|
493
485
|
end
|
494
486
|
|
495
|
-
tryonfirst.
|
487
|
+
while r = tryonfirst.shift do
|
496
488
|
# Try MTA module candidates which are detected from MTA specific
|
497
489
|
# mail headers on first
|
498
490
|
next if haveloaded.key?(r)
|
@@ -502,7 +494,7 @@ module Sisimai
|
|
502
494
|
throw :SCANNER if scannedset
|
503
495
|
end
|
504
496
|
|
505
|
-
|
497
|
+
while r = defaultset.shift do
|
506
498
|
# MTA modules which does not have MTA specific header and did
|
507
499
|
# not match with any regular expressions of Subject header.
|
508
500
|
next if haveloaded.key?(r)
|
data/lib/sisimai/message/json.rb
CHANGED
@@ -64,7 +64,7 @@ module Sisimai
|
|
64
64
|
next unless argvs[e].is_a? Array
|
65
65
|
next if argvs[e].empty?
|
66
66
|
|
67
|
-
modulelist
|
67
|
+
modulelist += argvs['order'] if e == 'order'
|
68
68
|
next unless e == 'load'
|
69
69
|
|
70
70
|
# Load user defined MTA(JSON) module
|
@@ -95,16 +95,14 @@ module Sisimai
|
|
95
95
|
# @return [Array] Order of MTA(JSON) modules
|
96
96
|
def self.makeorder(argvs)
|
97
97
|
return [] unless argvs
|
98
|
-
return []
|
98
|
+
return [] if argvs.empty?
|
99
99
|
order = []
|
100
100
|
|
101
101
|
# Seek some key names from given argument
|
102
102
|
ObjectKeys.each_key do |e|
|
103
103
|
# Get MTA(JSON) module list matched with a specified key
|
104
104
|
next unless argvs.key?(e)
|
105
|
-
|
106
|
-
# Matched and push it into the order list
|
107
|
-
order.concat(ObjectKeys[e])
|
105
|
+
order += ObjectKeys[e] # Matched and push it into the order list
|
108
106
|
break
|
109
107
|
end
|
110
108
|
return order
|
data/lib/sisimai/mime.rb
CHANGED
@@ -28,7 +28,7 @@ module Sisimai
|
|
28
28
|
def is_mimeencoded(argv1)
|
29
29
|
return false unless argv1
|
30
30
|
|
31
|
-
argv1
|
31
|
+
argv1.delete!('"')
|
32
32
|
piece = []
|
33
33
|
mime1 = false
|
34
34
|
|
@@ -48,12 +48,9 @@ module Sisimai
|
|
48
48
|
end
|
49
49
|
|
50
50
|
# Decode MIME-Encoded string
|
51
|
-
# @param [Array] argvs
|
51
|
+
# @param [Array] argvs An array including MIME-Encoded text
|
52
52
|
# @return [String] MIME-Decoded text
|
53
53
|
def mimedecode(argvs = [])
|
54
|
-
return '' unless argvs
|
55
|
-
return '' unless argvs.is_a? Array
|
56
|
-
|
57
54
|
characterset = nil
|
58
55
|
encodingname = nil
|
59
56
|
mimeencoded0 = nil
|
@@ -61,10 +58,9 @@ module Sisimai
|
|
61
58
|
notmimetext0 = ''
|
62
59
|
notmimetext1 = ''
|
63
60
|
|
64
|
-
argvs.
|
61
|
+
while e = argvs.shift do
|
65
62
|
# Check and decode each element
|
66
|
-
e = e.strip
|
67
|
-
e = e.delete('"')
|
63
|
+
e = e.strip.delete('"')
|
68
64
|
|
69
65
|
if self.is_mimeencoded(e)
|
70
66
|
# MIME Encoded string
|
@@ -92,17 +88,17 @@ module Sisimai
|
|
92
88
|
end
|
93
89
|
end
|
94
90
|
|
95
|
-
return ''
|
91
|
+
return '' if decodedtext0.empty?
|
96
92
|
decodedtext1 = decodedtext0.join('')
|
97
93
|
|
98
94
|
if characterset && encodingname
|
99
95
|
# utf8 => UTF-8
|
100
|
-
characterset = 'UTF-8' if characterset.casecmp('UTF8')
|
96
|
+
characterset = 'UTF-8' if characterset.casecmp('UTF8') == 0
|
101
97
|
|
102
|
-
unless characterset.casecmp('UTF-8')
|
98
|
+
unless characterset.casecmp('UTF-8') == 0
|
103
99
|
# Characterset is not UTF-8
|
104
100
|
begin
|
105
|
-
decodedtext1
|
101
|
+
decodedtext1.encode!('UTF-8', characterset)
|
106
102
|
rescue
|
107
103
|
decodedtext1 = 'FAILED TO CONVERT THE SUBJECT'
|
108
104
|
end
|
@@ -119,7 +115,7 @@ module Sisimai
|
|
119
115
|
def qprintd(argv1 = nil, heads = {})
|
120
116
|
return nil unless argv1
|
121
117
|
return argv1.unpack('M').first unless heads['content-type']
|
122
|
-
return argv1.unpack('M').first
|
118
|
+
return argv1.unpack('M').first if heads['content-type'].empty?
|
123
119
|
|
124
120
|
# Quoted-printable encoded part is the part of the text
|
125
121
|
boundary00 = Sisimai::MIME.boundary(heads['content-type'], 0)
|
@@ -127,7 +123,7 @@ module Sisimai
|
|
127
123
|
# Decoded using unpack('M') entire body string when the boundary string
|
128
124
|
# or "Content-Transfer-Encoding: quoted-printable" are not included in
|
129
125
|
# the message body.
|
130
|
-
return argv1.unpack('M').first if boundary00.
|
126
|
+
return argv1.unpack('M').first if boundary00.empty?
|
131
127
|
return argv1.unpack('M').first unless argv1.downcase =~ ReE[:'quoted-print']
|
132
128
|
|
133
129
|
boundary01 = Sisimai::MIME.boundary(heads['content-type'], 1)
|
@@ -154,8 +150,7 @@ module Sisimai
|
|
154
150
|
# The next boundary string has appeared
|
155
151
|
# --=_gy7C4Gpes0RP4V5Bs9cK4o2Us2ZT57b-3OLnRN+4klS8dTmQ
|
156
152
|
getencoded = Sisimai::String.to_utf8(notdecoded.unpack('M').first, encodename)
|
157
|
-
bodystring << getencoded
|
158
|
-
bodystring << e + "\n"
|
153
|
+
bodystring << getencoded << e + "\n"
|
159
154
|
|
160
155
|
notdecoded = ''
|
161
156
|
mimeinside = false
|
@@ -179,7 +174,7 @@ module Sisimai
|
|
179
174
|
mustencode = true
|
180
175
|
while true do
|
181
176
|
break if e.end_with?(' ', "\t")
|
182
|
-
break if e.split('').
|
177
|
+
break if e.split('').any? { |c| c.ord < 32 || c.ord > 126 }
|
183
178
|
if e.end_with?('=')
|
184
179
|
# Padding character of Base64 or not
|
185
180
|
break if e =~ /[\+\/0-9A-Za-z]{32,}[=]+\z/
|
@@ -261,7 +256,7 @@ module Sisimai
|
|
261
256
|
# Content-Type: multipart/report; report-type=delivery-status;
|
262
257
|
# boundary="n6H9lKZh014511.1247824040/mx.example.jp"
|
263
258
|
value = cv[1]
|
264
|
-
value
|
259
|
+
value.delete!(%q|'"|)
|
265
260
|
value = '--' + value if start > -1
|
266
261
|
value = value + '--' if start > 0
|
267
262
|
end
|