sisimai 5.2.1-java → 5.4.0-java
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 +4 -4
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +24 -0
- data/Makefile +3 -2
- data/README-JA.md +4 -4
- data/README.md +8 -8
- data/lib/sisimai/address.rb +45 -56
- data/lib/sisimai/arf.rb +11 -16
- data/lib/sisimai/datetime.rb +16 -50
- data/lib/sisimai/fact/json.rb +5 -5
- data/lib/sisimai/fact/yaml.rb +3 -3
- data/lib/sisimai/fact.rb +21 -12
- data/lib/sisimai/lda.rb +3 -3
- data/lib/sisimai/lhost/activehunter.rb +4 -6
- data/lib/sisimai/lhost/amazonses.rb +5 -6
- data/lib/sisimai/lhost/apachejames.rb +7 -9
- data/lib/sisimai/lhost/biglobe.rb +3 -5
- data/lib/sisimai/lhost/courier.rb +4 -6
- data/lib/sisimai/lhost/domino.rb +4 -5
- data/lib/sisimai/lhost/dragonfly.rb +3 -5
- data/lib/sisimai/lhost/einsundeins.rb +6 -8
- data/lib/sisimai/lhost/exchange2003.rb +10 -12
- data/lib/sisimai/lhost/exchange2007.rb +4 -5
- data/lib/sisimai/lhost/exim.rb +6 -8
- data/lib/sisimai/lhost/ezweb.rb +10 -12
- data/lib/sisimai/lhost/fml.rb +2 -3
- data/lib/sisimai/lhost/gmail.rb +4 -6
- data/lib/sisimai/lhost/gmx.rb +6 -8
- data/lib/sisimai/lhost/googlegroups.rb +1 -2
- data/lib/sisimai/lhost/googleworkspace.rb +3 -4
- data/lib/sisimai/lhost/imailserver.rb +6 -7
- data/lib/sisimai/lhost/interscanmss.rb +1 -2
- data/lib/sisimai/lhost/kddi.rb +5 -8
- data/lib/sisimai/lhost/mailfoundry.rb +4 -7
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +4 -6
- data/lib/sisimai/lhost/messagingserver.rb +5 -7
- data/lib/sisimai/lhost/mfilter.rb +4 -6
- data/lib/sisimai/lhost/notes.rb +7 -9
- data/lib/sisimai/lhost/opensmtpd.rb +2 -4
- data/lib/sisimai/lhost/postfix.rb +8 -11
- data/lib/sisimai/lhost/qmail.rb +5 -8
- data/lib/sisimai/lhost/sendmail.rb +7 -10
- data/lib/sisimai/lhost/v5sendmail.rb +15 -17
- data/lib/sisimai/lhost/verizon.rb +9 -14
- data/lib/sisimai/lhost/x1.rb +4 -6
- data/lib/sisimai/lhost/x2.rb +5 -7
- data/lib/sisimai/lhost/x3.rb +3 -4
- data/lib/sisimai/lhost/x6.rb +4 -6
- data/lib/sisimai/lhost/zoho.rb +6 -8
- data/lib/sisimai/lhost.rb +1 -1
- data/lib/sisimai/mail/mbox.rb +1 -1
- data/lib/sisimai/mail/memory.rb +1 -1
- data/lib/sisimai/mail.rb +8 -8
- data/lib/sisimai/message.rb +11 -13
- data/lib/sisimai/order.rb +12 -11
- data/lib/sisimai/reason/authfailure.rb +10 -10
- data/lib/sisimai/reason/badreputation.rb +4 -6
- data/lib/sisimai/reason/blocked.rb +6 -8
- data/lib/sisimai/reason/contenterror.rb +5 -6
- data/lib/sisimai/reason/delivered.rb +2 -2
- data/lib/sisimai/reason/exceedlimit.rb +7 -8
- data/lib/sisimai/reason/expired.rb +6 -7
- data/lib/sisimai/reason/failedstarttls.rb +5 -7
- data/lib/sisimai/reason/feedback.rb +2 -2
- data/lib/sisimai/reason/filtered.rb +7 -10
- data/lib/sisimai/reason/hasmoved.rb +4 -5
- data/lib/sisimai/reason/hostunknown.rb +6 -7
- data/lib/sisimai/reason/mailboxfull.rb +7 -8
- data/lib/sisimai/reason/mailererror.rb +5 -8
- data/lib/sisimai/reason/mesgtoobig.rb +5 -6
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +4 -5
- data/lib/sisimai/reason/notaccept.rb +5 -8
- data/lib/sisimai/reason/notcompliantrfc.rb +5 -6
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +6 -9
- data/lib/sisimai/reason/rejected.rb +5 -6
- data/lib/sisimai/reason/requireptr.rb +6 -7
- data/lib/sisimai/reason/securityerror.rb +6 -9
- data/lib/sisimai/reason/spamdetected.rb +8 -9
- data/lib/sisimai/reason/speeding.rb +6 -7
- data/lib/sisimai/reason/suppressed.rb +3 -7
- data/lib/sisimai/reason/suspend.rb +5 -7
- data/lib/sisimai/reason/syntaxerror.rb +3 -5
- data/lib/sisimai/reason/systemerror.rb +6 -9
- data/lib/sisimai/reason/systemfull.rb +5 -8
- data/lib/sisimai/reason/toomanyconn.rb +5 -6
- data/lib/sisimai/reason/undefined.rb +2 -2
- data/lib/sisimai/reason/userunknown.rb +8 -9
- data/lib/sisimai/reason/vacation.rb +4 -5
- data/lib/sisimai/reason/virusdetected.rb +4 -5
- data/lib/sisimai/reason.rb +13 -13
- data/lib/sisimai/rfc1123.rb +4 -8
- data/lib/sisimai/rfc1894.rb +5 -6
- data/lib/sisimai/rfc2045.rb +27 -31
- data/lib/sisimai/rfc3464/thirdparty.rb +1 -1
- data/lib/sisimai/rfc3464.rb +7 -9
- data/lib/sisimai/rfc3834.rb +5 -9
- data/lib/sisimai/rfc5322.rb +8 -26
- data/lib/sisimai/rfc791.rb +6 -4
- data/lib/sisimai/rhost/google.rb +8 -0
- data/lib/sisimai/rhost/microsoft.rb +17 -5
- data/lib/sisimai/rhost.rb +2 -2
- data/lib/sisimai/smtp/command.rb +1 -1
- data/lib/sisimai/smtp/failure.rb +5 -12
- data/lib/sisimai/smtp/reply.rb +33 -12
- data/lib/sisimai/smtp/status.rb +21 -22
- data/lib/sisimai/smtp/transcript.rb +1 -10
- data/lib/sisimai/string.rb +20 -30
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +11 -11
- data/set-of-emails/maildir/bsd/rhost-microsoft-06.eml +45 -0
- metadata +8 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e7c01c8568c5c1922dc71d9948d86eb8684bf18a981243b3e476a2de4d187f6
|
4
|
+
data.tar.gz: 0ca7b2415f6afc00b98f9e8e25b939f9962d0aba7c08f0c1689647a26f6329ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 201468479dbd8c7cf75d6ac3d7560e2ec9bf9badb6d9a847c5979264138477699450a15a9553e1e919f69dd8f369c9792af6fac56e2a07eea5940daa4a943273
|
7
|
+
data.tar.gz: 933f217ffb3bc6092e2f338a4df40291e11ad3c59b6bdb22e56ba53d9b88368ff21ab37687d2dc87873f3ce4327aede14913616312eff1ee716768a7c960b816
|
data/ChangeLog.md
CHANGED
@@ -3,6 +3,30 @@ RELEASE NOTES for Ruby version of Sisimai
|
|
3
3
|
- releases: "https://github.com/sisimai/rb-sisimai/releases"
|
4
4
|
- download: "https://rubygems.org/gems/sisimai"
|
5
5
|
|
6
|
+
v5.4.0
|
7
|
+
---------------------------------------------------------------------------------------------------
|
8
|
+
- release: "Tue, 1 Jul 2025 20:22:22 +0900 (JST)"
|
9
|
+
- version: "5.4.0"
|
10
|
+
- changes:
|
11
|
+
- #341 #342 #345 Implement the new status code `5.7.515` as `authfailure` and other undocumented
|
12
|
+
status codes begin with `4.4.` as `systemerror` of Microsoft in `Sisimai::Rhost::Microsoft`.
|
13
|
+
- #343 #346 Some internal methods do not return `nil`, standardize return values to align with
|
14
|
+
zero-value principle.
|
15
|
+
- #347 Support a frozen string literal
|
16
|
+
- #349 #350 Implement new status codes of Google: `4.7.40` and `5.7.32` as `authfailure`.
|
17
|
+
|
18
|
+
v5.3.0
|
19
|
+
---------------------------------------------------------------------------------------------------
|
20
|
+
- release: "Sat, 29 Mar 2025 06:04:41 +0900 (JST)"
|
21
|
+
- version: "5.3.0"
|
22
|
+
- changes:
|
23
|
+
- Collateral update due to the Go version of Sisimai's broken module path fix.
|
24
|
+
- Sisimai works on Ruby 3.4
|
25
|
+
- SMTP reply code improvements
|
26
|
+
- Update the list of SMTP reply codes in `Sisimai::SMTP::Reply`
|
27
|
+
- Implement `Sisimai::SMTP::Reply.associatedwith`
|
28
|
+
- Implement `Sisimai::SMTP::Status.is_explicit`
|
29
|
+
|
6
30
|
v5.2.1
|
7
31
|
---------------------------------------------------------------------------------------------------
|
8
32
|
- release: "Wed, 12 Mar 2025 06:50:25 +0900 (JST)"
|
data/Makefile
CHANGED
@@ -16,6 +16,7 @@ CP := cp
|
|
16
16
|
RM := rm -f
|
17
17
|
|
18
18
|
DEPENDENCIES = bundle rake minitest
|
19
|
+
RUBYARGUMENT = --enable-frozen-string-literal
|
19
20
|
.DEFAULT_GOAL = git-status
|
20
21
|
REPOS_TARGETS = git-status git-push git-commit-amend git-tag-list git-diff git-reset-soft \
|
21
22
|
git-rm-cached git-branch
|
@@ -58,11 +59,11 @@ release:
|
|
58
59
|
test: user-test author-test
|
59
60
|
user-test:
|
60
61
|
# Suppress warning messages until v5.5.0
|
61
|
-
rake publictest 2> /dev/null
|
62
|
+
RUBYOPT="$(RUBYARGUMENT)" rake publictest 2> /dev/null
|
62
63
|
|
63
64
|
author-test:
|
64
65
|
# Suppress warning messages until v5.5.0
|
65
|
-
rake privatetest 2> /dev/null
|
66
|
+
RUBYOPT="$(RUBYARGUMENT)" rake privatetest 2> /dev/null
|
66
67
|
|
67
68
|
check:
|
68
69
|
find lib -type f -exec grep --color -E ' $$' {} /dev/null \;
|
data/README-JA.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|

|
2
2
|
[](https://github.com/sisimai/rb-sisimai/blob/master/LICENSE)
|
3
|
-
[](https://www.ruby-lang.org/)
|
4
4
|
[](https://badge.fury.io/rb/sisimai)
|
5
5
|
[](https://codecov.io/github/sisimai/rb-sisimai)
|
6
6
|
|
@@ -23,7 +23,7 @@
|
|
23
23
|
> SisimaiはPerlモジュールまたはRuby Gemですが、PHPやPython、GoやRustなどJSONを読める言語であれば
|
24
24
|
> どのような環境においても解析結果を得ることでバウンスの発生状況を捉えるのにとても有用です。
|
25
25
|
|
26
|
-
- [**README(
|
26
|
+
- [**README(🇬🇧)**](README.md)
|
27
27
|
- [シシマイ? | What is Sisimai](#what-is-sisimai)
|
28
28
|
- [主な特徴的機能 | The key features](#the-key-features-of-sisimai)
|
29
29
|
- [コマンドラインでのデモ | Command line demo](#command-line-demo)
|
@@ -362,7 +362,7 @@ Sisimai 5.0.0から**Ruby 2.4以上**が必要になります。
|
|
362
362
|
| ソースコードの行数 | 10,800 行 | 9,860 行 |
|
363
363
|
| テストフレームワーク | rspec | minitest |
|
364
364
|
| テスト件数(spec/またはtest/ディレクトリ) | 311,000 件 | 410,000 件 |
|
365
|
-
| 1秒間に解析できるバウンスメール数[^4] |
|
365
|
+
| 1秒間に解析できるバウンスメール数[^4] | 620 通 | 620 通 |
|
366
366
|
| ライセンス | 2条項BSD | 2条項BSD |
|
367
367
|
| 開発会社による商用サポート | 提供中 | 提供中 |
|
368
368
|
|
@@ -447,7 +447,7 @@ Related sites
|
|
447
447
|
|
448
448
|
See also
|
449
449
|
---------------------------------------------------------------------------------------------------
|
450
|
-
* [README.md - README.md in English](https://github.com/sisimai/rb-sisimai/blob/master/README.md)
|
450
|
+
* [README.md - README.md in English(🇬🇧)](https://github.com/sisimai/rb-sisimai/blob/master/README.md)
|
451
451
|
* [RFC3463 - Enhanced Mail System Status Codes](https://tools.ietf.org/html/rfc3463)
|
452
452
|
* [RFC3464 - An Extensible Message Format for Delivery Status Notifications](https://tools.ietf.org/html/rfc3464)
|
453
453
|
* [RFC3834 - Recommendations for Automatic Responses to Electronic Mail](https://tools.ietf.org/html/rfc3834)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|

|
2
2
|
[](https://github.com/sisimai/rb-sisimai/blob/master/LICENSE)
|
3
|
-
[](https://www.ruby-lang.org/)
|
4
4
|
[](https://badge.fury.io/rb/sisimai)
|
5
5
|
[](https://codecov.io/github/sisimai/rb-sisimai)
|
6
6
|
|
@@ -25,7 +25,7 @@
|
|
25
25
|
> such as PHP, Python, Go, and Rust. By obtaining the analysis results, it is very useful for understanding
|
26
26
|
> the bounce occurrence status.
|
27
27
|
|
28
|
-
- [**README-JA(
|
28
|
+
- [**README-JA(🇯🇵)**](README-JA.md)
|
29
29
|
- [What is Sisimai](#what-is-sisimai)
|
30
30
|
- [The key features of sisimai](#the-key-features-of-sisimai)
|
31
31
|
- [Command line demo](#command-line-demo)
|
@@ -57,10 +57,10 @@
|
|
57
57
|
|
58
58
|
What is Sisimai
|
59
59
|
===================================================================================================
|
60
|
-
Sisimai is a library that decodes complex and diverse bounce emails and
|
61
|
-
delivery failure, such as the reason for the bounce and the recipient
|
62
|
-
data. It is also possible to output in JSON format. The Ruby version
|
63
|
-
Perl version of Sisimai
|
60
|
+
Sisimai (pronounced /ɕi.ɕi.ma.i/) is a library that decodes complex and diverse bounce emails and
|
61
|
+
outputs the results of the delivery failure, such as the reason for the bounce and the recipient
|
62
|
+
email address, in structured data. It is also possible to output in JSON format. The Ruby version
|
63
|
+
of Sisimai is ported from [the Perl version of Sisimai](https://github.com/sisimai/p5-sisimai/).
|
64
64
|
|
65
65
|

|
66
66
|
|
@@ -361,7 +361,7 @@ Beginning with v5.0.0, Sisimai requires **Ruby 2.4.0 or later.**
|
|
361
361
|
| Source lines of code | 10,300 lines | 9,800 lines |
|
362
362
|
| Test frameworks | rspec | minitest |
|
363
363
|
| The number of tests in spec/ or test/ directory | 311,000 tests | 410,000 tests |
|
364
|
-
| The number of bounce emails decoded/sec (CRuby)[^4] |
|
364
|
+
| The number of bounce emails decoded/sec (CRuby)[^4] | 620 emails | 620 emails |
|
365
365
|
| License | 2 Clause BSD | 2 Caluse BSD |
|
366
366
|
| Commercial support | Available | Available |
|
367
367
|
|
@@ -450,7 +450,7 @@ Related Sites
|
|
450
450
|
|
451
451
|
See also
|
452
452
|
---------------------------------------------------------------------------------------------------
|
453
|
-
* [README-JA.md - README.md in Japanese(
|
453
|
+
* [README-JA.md - README.md in Japanese(🇯🇵)](https://github.com/sisimai/rb-sisimai/blob/master/README-JA.md)
|
454
454
|
* [RFC3463 - Enhanced Mail System Status Codes](https://tools.ietf.org/html/rfc3463)
|
455
455
|
* [RFC3464 - An Extensible Message Format for Delivery Status Notifications](https://tools.ietf.org/html/rfc3464)
|
456
456
|
* [RFC3834 - Recommendations for Automatic Responses to Electronic Mail](https://tools.ietf.org/html/rfc3834)
|
data/lib/sisimai/address.rb
CHANGED
@@ -12,7 +12,7 @@ module Sisimai
|
|
12
12
|
# dtext = NO-WS-CTL / ; Non white space controls
|
13
13
|
# %d33-90 / ; The rest of the US-ASCII
|
14
14
|
# %d94-126 ; characters not including "[", "]", or "\"
|
15
|
-
re = {
|
15
|
+
re = {rfc5322: nil, ignored: nil, domain: nil}
|
16
16
|
atom = %r([a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+)o
|
17
17
|
quoted_string = %r/"(?:\\[^\r\n]|[^\\"])*"/o
|
18
18
|
domain_literal = %r/\[(?:\\[\x01-\x09\x0B-\x0c\x0e-\x7f]|[\x21-\x5a\x5e-\x7e])*\]/o
|
@@ -33,7 +33,7 @@ module Sisimai
|
|
33
33
|
:'quoted-string' => (1 << 1), # "Neko, Nyaan"
|
34
34
|
:'comment-block' => (1 << 2), # (neko)
|
35
35
|
}.freeze
|
36
|
-
Delimiters = {
|
36
|
+
Delimiters = {'<' => 1, '>' => 1, '(' => 1, ')' => 1, '"' => 1, ',' => 1}.freeze
|
37
37
|
|
38
38
|
# Return pseudo recipient or sender address
|
39
39
|
# @param [Symbol] argv0 Address type: true = recipient, false = sender
|
@@ -45,12 +45,10 @@ module Sisimai
|
|
45
45
|
|
46
46
|
# Check that the argument is an email address or not
|
47
47
|
# @param [String] email Email address string
|
48
|
-
# @return [
|
49
|
-
# false: is not an email address
|
48
|
+
# @return [Boolean] true: is an email address, false: is not an email address
|
50
49
|
def self.is_emailaddress(email)
|
51
|
-
return false
|
52
|
-
return false if email =~ %r/(?:[\x00-\x1f]|\x1f)/
|
53
|
-
return false if email.size > 254
|
50
|
+
return false if email.is_a?(::String) == false
|
51
|
+
return false if email =~ %r/(?:[\x00-\x1f]|\x1f)/ || email.size > 254
|
54
52
|
return true if email =~ Re[:ignored]
|
55
53
|
return false
|
56
54
|
end
|
@@ -60,9 +58,7 @@ module Sisimai
|
|
60
58
|
# @return [True,False] true: mailer-daemon
|
61
59
|
# false: Not mailer-daemon
|
62
60
|
def self.is_mailerdaemon(argv0 = nil)
|
63
|
-
return false
|
64
|
-
return false unless argv0.size > 0
|
65
|
-
return false unless argv0.is_a?(::String)
|
61
|
+
return false if argv0.to_s == "" || argv0.is_a?(::String) == false
|
66
62
|
|
67
63
|
email = argv0.downcase
|
68
64
|
postmaster = [
|
@@ -71,8 +67,7 @@ module Sisimai
|
|
71
67
|
].freeze
|
72
68
|
|
73
69
|
return true if postmaster.any? { |a| email.include?(a) }
|
74
|
-
return true if email == 'mailer-daemon'
|
75
|
-
return true if email == 'postmaster'
|
70
|
+
return true if email == 'mailer-daemon' || email == 'postmaster'
|
76
71
|
return false
|
77
72
|
end
|
78
73
|
|
@@ -87,7 +82,7 @@ module Sisimai
|
|
87
82
|
# #=> [{ address: 'neko@example.org', name: 'Neko', comment: '(nyaan)'}]
|
88
83
|
return nil unless argv1
|
89
84
|
|
90
|
-
emailtable = {
|
85
|
+
emailtable = {address: '', name: '', comment: ''}
|
91
86
|
addrtables = []
|
92
87
|
readbuffer = []
|
93
88
|
readcursor = 0
|
@@ -109,20 +104,20 @@ module Sisimai
|
|
109
104
|
# An email address has already been picked
|
110
105
|
if readcursor & Indicators[:'comment-block'] > 0
|
111
106
|
# The cursor is in the comment block (Neko, Nyaan)
|
112
|
-
v[:comment]
|
107
|
+
v[:comment] += e
|
113
108
|
elsif readcursor & Indicators[:'quoted-string'] > 0
|
114
109
|
# "Neko, Nyaan"
|
115
|
-
v[:name]
|
110
|
+
v[:name] += e
|
116
111
|
else
|
117
112
|
# The cursor is not in neither the quoted-string nor the comment block
|
118
113
|
readcursor = 0 # reset cursor position
|
119
114
|
readbuffer << v
|
120
|
-
v = {
|
115
|
+
v = {address: '', name: '', comment: ''}
|
121
116
|
p = ''
|
122
117
|
end
|
123
118
|
else
|
124
119
|
# "Neko, Nyaan" <neko@nyaan.example.org> OR <"neko,nyaan"@example.org>
|
125
|
-
p.empty? ? (v[:name]
|
120
|
+
p.empty? ? (v[:name] += e) : (v[p] += e)
|
126
121
|
end
|
127
122
|
next
|
128
123
|
end # End of if(',')
|
@@ -130,11 +125,11 @@ module Sisimai
|
|
130
125
|
if e == '<'
|
131
126
|
# <: The beginning of an email address or not
|
132
127
|
if v[:address].size > 0
|
133
|
-
p.empty? ? (v[:name]
|
128
|
+
p.empty? ? (v[:name] += e) : (v[p] += e)
|
134
129
|
else
|
135
130
|
# <neko@nyaan.example.org>
|
136
131
|
readcursor |= Indicators[:'email-address']
|
137
|
-
v[:address]
|
132
|
+
v[:address] += e
|
138
133
|
p = :address
|
139
134
|
end
|
140
135
|
next
|
@@ -146,11 +141,11 @@ module Sisimai
|
|
146
141
|
if readcursor & Indicators[:'email-address'] > 0
|
147
142
|
# <neko@example.org>
|
148
143
|
readcursor &= ~Indicators[:'email-address']
|
149
|
-
v[:address]
|
144
|
+
v[:address] += e
|
150
145
|
p = ''
|
151
146
|
else
|
152
147
|
# a comment block or a display name
|
153
|
-
p.empty? ? (v[:name]
|
148
|
+
p.empty? ? (v[:name] == e) : (v[:comment] -= e)
|
154
149
|
end
|
155
150
|
next
|
156
151
|
end # End of if('>')
|
@@ -161,27 +156,27 @@ module Sisimai
|
|
161
156
|
# <"neko(nyaan)"@example.org> or <neko(nyaan)@example.org>
|
162
157
|
if v[:address].include?('"')
|
163
158
|
# Quoted local part: <"neko(nyaan)"@example.org>
|
164
|
-
v[:address]
|
159
|
+
v[:address] += e
|
165
160
|
else
|
166
161
|
# Comment: <neko(nyaan)@example.org>
|
167
162
|
readcursor |= Indicators[:'comment-block']
|
168
|
-
v[:comment]
|
169
|
-
v[:comment]
|
163
|
+
v[:comment] += ' ' if v[:comment].end_with?(')')
|
164
|
+
v[:comment] += e
|
170
165
|
p = :comment
|
171
166
|
end
|
172
167
|
elsif readcursor & Indicators[:'comment-block'] > 0
|
173
168
|
# Comment at the outside of an email address (...(...)
|
174
|
-
v[:comment]
|
175
|
-
v[:comment]
|
169
|
+
v[:comment] += ' ' if v[:comment].end_with?(')')
|
170
|
+
v[:comment] += e
|
176
171
|
|
177
172
|
elsif readcursor & Indicators[:'quoted-string'] > 0
|
178
173
|
# "Neko, Nyaan(cat)", Deal as a display name
|
179
|
-
v[:name]
|
174
|
+
v[:name] += e
|
180
175
|
else
|
181
176
|
# The beginning of a comment block
|
182
177
|
readcursor |= Indicators[:'comment-block']
|
183
|
-
v[:comment]
|
184
|
-
v[:comment]
|
178
|
+
v[:comment] += ' ' if v[:comment].end_with?(')')
|
179
|
+
v[:comment] += e
|
185
180
|
p = :comment
|
186
181
|
end
|
187
182
|
next
|
@@ -193,22 +188,22 @@ module Sisimai
|
|
193
188
|
# <"neko(nyaan)"@example.org> OR <neko(nyaan)@example.org>
|
194
189
|
if v[:address].include?('"')
|
195
190
|
# Quoted string in the local part: <"neko(nyaan)"@example.org>
|
196
|
-
v[:address]
|
191
|
+
v[:address] += e
|
197
192
|
else
|
198
193
|
# Comment: <neko(nyaan)@example.org>
|
199
194
|
readcursor &= ~Indicators[:'comment-block']
|
200
|
-
v[:comment]
|
195
|
+
v[:comment] += e
|
201
196
|
p = :address
|
202
197
|
end
|
203
198
|
elsif readcursor & Indicators[:'comment-block'] > 0
|
204
199
|
# Comment at the outside of an email address (...(...)
|
205
200
|
readcursor &= ~Indicators[:'comment-block']
|
206
|
-
v[:comment]
|
201
|
+
v[:comment] += e
|
207
202
|
p = ''
|
208
203
|
else
|
209
204
|
# Deal as a display name
|
210
205
|
readcursor &= ~Indicators[:'comment-block']
|
211
|
-
v[:name]
|
206
|
+
v[:name] += e
|
212
207
|
p = ''
|
213
208
|
end
|
214
209
|
next
|
@@ -218,10 +213,10 @@ module Sisimai
|
|
218
213
|
# The beginning or the end of a quoted-string
|
219
214
|
if p.size > 0
|
220
215
|
# email-address or comment-block
|
221
|
-
v[p]
|
216
|
+
v[p] += e
|
222
217
|
else
|
223
218
|
# Display name like "Neko, Nyaan"
|
224
|
-
v[:name]
|
219
|
+
v[:name] += e
|
225
220
|
next unless readcursor & Indicators[:'quoted-string'] > 0
|
226
221
|
next if v[:name].end_with?(%Q|\x5c"|) # "Neko, Nyaan \"...
|
227
222
|
readcursor &= ~Indicators[:'quoted-string']
|
@@ -231,7 +226,7 @@ module Sisimai
|
|
231
226
|
end # End of if('"')
|
232
227
|
else
|
233
228
|
# The character is not a delimiter
|
234
|
-
p.empty? ? (v[:name]
|
229
|
+
p.empty? ? (v[:name] += e) : (v[p] += e)
|
235
230
|
next
|
236
231
|
end
|
237
232
|
end
|
@@ -283,7 +278,7 @@ module Sisimai
|
|
283
278
|
e.delete(:comment)
|
284
279
|
else
|
285
280
|
# Remove double-quotations, trailing spaces.
|
286
|
-
[:name, :comment].each { |f| e[f].strip
|
281
|
+
[:name, :comment].each { |f| e[f] = e[f].strip }
|
287
282
|
e[:comment] = '' unless e[:comment] =~ /\A[(].+[)]/
|
288
283
|
e[:name].squeeze!(' ') unless e[:name] =~ /\A["].+["]\z/
|
289
284
|
e[:name].sub!(/\A["]/, '') unless e[:name] =~ /\A["].+["][@]/
|
@@ -301,8 +296,8 @@ module Sisimai
|
|
301
296
|
# @return [String] Email address without comment, brackets
|
302
297
|
# @example s3s4('<neko@example.cat>') #=> 'neko@example.cat'
|
303
298
|
def self.s3s4(input)
|
304
|
-
return
|
305
|
-
return
|
299
|
+
return "" if input.to_s == ""
|
300
|
+
return "" if input.is_a?(Object::String) == false
|
306
301
|
|
307
302
|
addrs = Sisimai::Address.find(input, true) || []
|
308
303
|
return input if addrs.empty?
|
@@ -315,8 +310,8 @@ module Sisimai
|
|
315
310
|
# @example Expand VERP address
|
316
311
|
# expand_verp('bounce+neko=example.org@example.org') #=> 'neko@example.org'
|
317
312
|
def self.expand_verp(email)
|
318
|
-
return
|
319
|
-
return
|
313
|
+
return "" unless email.is_a? Object::String
|
314
|
+
return "" unless cv = email.split('@', 2).first.match(/\A[-\w]+?[+](\w[-.\w]+\w)[=](\w[-.\w]+\w)\z/)
|
320
315
|
verp0 = cv[1] + '@' + cv[2]
|
321
316
|
return verp0 if Sisimai::Address.is_emailaddress(verp0)
|
322
317
|
end
|
@@ -327,10 +322,10 @@ module Sisimai
|
|
327
322
|
# @example Expand alias
|
328
323
|
# expand_alias('neko+straycat@example.org') #=> 'neko@example.org'
|
329
324
|
def self.expand_alias(email)
|
330
|
-
return
|
325
|
+
return "" unless Sisimai::Address.is_emailaddress(email)
|
331
326
|
|
332
327
|
local = email.split('@')
|
333
|
-
return
|
328
|
+
return "" unless cv = local[0].match(/\A([-\w]+?)[+].+\z/)
|
334
329
|
return cv[1] + '@' + local[1]
|
335
330
|
end
|
336
331
|
|
@@ -347,11 +342,9 @@ module Sisimai
|
|
347
342
|
# Constructor of Sisimai::Address
|
348
343
|
# @param [Hash] argvs Email address, name, and other elements
|
349
344
|
# @return [Sisimai::Address] Object or nil when the email address was not valid.
|
350
|
-
# @example new(
|
345
|
+
# @example new(address: 'neko@example.org', name: 'Neko', comment: '(nyaan)') # => Sisimai::Address object
|
351
346
|
def initialize(argvs)
|
352
|
-
return nil
|
353
|
-
return nil unless argvs[:address]
|
354
|
-
return nil if argvs[:address].empty?
|
347
|
+
return nil if argvs.is_a?(Hash) == false || argvs[:address].nil? || argvs[:address].empty?
|
355
348
|
|
356
349
|
heads = ['<']
|
357
350
|
tails = ['>', ',', '.', ';']
|
@@ -364,10 +357,10 @@ module Sisimai
|
|
364
357
|
email = Sisimai::Address.expand_verp(argvs[:address])
|
365
358
|
aname = nil
|
366
359
|
|
367
|
-
|
360
|
+
if email.empty?
|
368
361
|
# Is not VERP address, try to expand the address as an alias
|
369
|
-
email = Sisimai::Address.expand_alias(argvs[:address])
|
370
|
-
aname = true
|
362
|
+
email = Sisimai::Address.expand_alias(argvs[:address])
|
363
|
+
aname = true if email.empty? == false
|
371
364
|
end
|
372
365
|
|
373
366
|
if email.include?('@')
|
@@ -422,15 +415,11 @@ module Sisimai
|
|
422
415
|
|
423
416
|
# Returns the value of address as String
|
424
417
|
# @return [String] Email address
|
425
|
-
def to_json(*)
|
426
|
-
return self.address.to_s
|
427
|
-
end
|
418
|
+
def to_json(*); return self.address.to_s; end
|
428
419
|
|
429
420
|
# Returns the value of address as String
|
430
421
|
# @return [String] Email address
|
431
|
-
def to_s
|
432
|
-
return self.address.to_s
|
433
|
-
end
|
422
|
+
def to_s; return self.address.to_s; end
|
434
423
|
|
435
424
|
end
|
436
425
|
end
|
data/lib/sisimai/arf.rb
CHANGED
@@ -53,12 +53,9 @@ module Sisimai
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
return true if heads["x-apple-unsubscribe"] == "true"
|
60
|
-
break
|
61
|
-
end
|
56
|
+
# X-Apple-Unsubscribe: true
|
57
|
+
return false unless heads.has_key?("x-apple-unsubscribe")
|
58
|
+
return true if heads["x-apple-unsubscribe"] == "true"
|
62
59
|
return false
|
63
60
|
end
|
64
61
|
|
@@ -70,7 +67,7 @@ module Sisimai
|
|
70
67
|
def inquire(mhead, mbody)
|
71
68
|
return nil unless self.is_arf(mhead)
|
72
69
|
|
73
|
-
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
70
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = dscontents[-1]
|
74
71
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
75
72
|
bodyslices = emailparts[0].split("\n")
|
76
73
|
reportpart = false
|
@@ -80,7 +77,6 @@ module Sisimai
|
|
80
77
|
remotehost = "" # The value of "Source-IP" field
|
81
78
|
reportedby = "" # The value of "Reporting-MTA" field
|
82
79
|
anotherone = "" # Other fields(append to Diagnosis)
|
83
|
-
v = dscontents[-1]
|
84
80
|
|
85
81
|
# 3.1. Required Fields
|
86
82
|
#
|
@@ -115,13 +111,12 @@ module Sisimai
|
|
115
111
|
# this is an autogenerated email abuse complaint regarding your network.
|
116
112
|
next unless Sisimai::String.aligned(r, f)
|
117
113
|
readcursor |= Indicators[:deliverystatus]
|
118
|
-
v["diagnosis"]
|
114
|
+
v["diagnosis"] += " #{e}"
|
119
115
|
break
|
120
116
|
end
|
121
117
|
next
|
122
118
|
end
|
123
|
-
next
|
124
|
-
next if e.empty?
|
119
|
+
next if (readcursor & Indicators[:deliverystatus]) > 0 || e.empty?
|
125
120
|
if e == ReportFrom then reportpart = true; next; end
|
126
121
|
|
127
122
|
if reportpart
|
@@ -158,12 +153,12 @@ module Sisimai
|
|
158
153
|
#
|
159
154
|
# Authentication-Results: mail.example.com;
|
160
155
|
# spf=fail smtp.mail=somespammer@example.com
|
161
|
-
anotherone
|
156
|
+
anotherone += "#{e}, "
|
162
157
|
|
163
158
|
elsif e.start_with?("User-Agent: ")
|
164
159
|
# The header field MUST appear exactly once.
|
165
160
|
# User-Agent: SomeGenerator/1.0
|
166
|
-
anotherone
|
161
|
+
anotherone += "#{e}, "
|
167
162
|
|
168
163
|
elsif e.start_with?("Received-Date: ") || e.start_with?("Arrival-Date: ")
|
169
164
|
# Arrival-Date header is optional and MUST NOT appear more than once.
|
@@ -185,11 +180,11 @@ module Sisimai
|
|
185
180
|
elsif e.start_with?("Original-Mail-From: ")
|
186
181
|
# the header is optional and MUST NOT appear more than once.
|
187
182
|
# Original-Mail-From: <somespammer@example.net>
|
188
|
-
anotherone
|
183
|
+
anotherone += "#{e}, "
|
189
184
|
end
|
190
185
|
else
|
191
186
|
# Messages before "Content-Type: message/feedback-report" part
|
192
|
-
v["diagnosis"]
|
187
|
+
v["diagnosis"] += " #{e}"
|
193
188
|
end
|
194
189
|
|
195
190
|
while recipients == 0
|
@@ -220,7 +215,7 @@ module Sisimai
|
|
220
215
|
end
|
221
216
|
return nil if recipients == 0
|
222
217
|
|
223
|
-
anotherone = ":
|
218
|
+
anotherone = ": #{Sisimai::String.sweep(anotherone)}" if anotherone != ""
|
224
219
|
anotherone = anotherone.chop if anotherone[-1, 1] == ","
|
225
220
|
|
226
221
|
j = -1
|