rmail 1.0.0 → 1.1.4
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/{NEWS → ChangeLog} +42 -0
- data/{README → README.md} +20 -43
- data/Rakefile +52 -68
- data/lib/rmail/address.rb +17 -5
- data/lib/rmail/header.rb +16 -12
- data/lib/rmail/message.rb +3 -2
- data/lib/rmail/parser.rb +4 -3
- data/lib/rmail/parser/pushbackreader.rb +7 -7
- data/lib/rmail/serialize.rb +1 -1
- data/lib/rmail/version.rb +3 -0
- data/test/testaddress.rb +23 -11
- data/test/testbase.rb +21 -1
- data/test/testheader.rb +21 -13
- data/test/testmessage.rb +1 -1
- metadata +62 -75
- data/install.rb +0 -1023
- data/version +0 -1
data/lib/rmail/message.rb
CHANGED
@@ -46,6 +46,7 @@ module RMail
|
|
46
46
|
@body = nil
|
47
47
|
@epilogue = nil
|
48
48
|
@preamble = nil
|
49
|
+
@delimiters = nil
|
49
50
|
end
|
50
51
|
|
51
52
|
# Test if this message is structured exactly the same as the other
|
@@ -130,14 +131,14 @@ module RMail
|
|
130
131
|
# Access the epilogue string for this message. The epilogue
|
131
132
|
# string is relevant only for multipart messages. It is the text
|
132
133
|
# that occurs after all parts of the message and is generally nil.
|
133
|
-
|
134
|
+
attr_accessor :epilogue
|
134
135
|
|
135
136
|
# Access the preamble string for this message. The preamble
|
136
137
|
# string is relevant only for multipart messages. It is the text
|
137
138
|
# that occurs just before the first part of the message, and is
|
138
139
|
# generally nil or simple English text describing the nature of
|
139
140
|
# the message.
|
140
|
-
|
141
|
+
attr_accessor :preamble
|
141
142
|
|
142
143
|
# Returns the entire message in a single string. This uses the
|
143
144
|
# RMail::Serialize class.
|
data/lib/rmail/parser.rb
CHANGED
@@ -202,7 +202,6 @@ module RMail
|
|
202
202
|
def parse_header(input, depth)
|
203
203
|
data = nil
|
204
204
|
header = nil
|
205
|
-
pushback = nil
|
206
205
|
boundary = nil
|
207
206
|
while chunk = input.read
|
208
207
|
data ||= ''
|
@@ -213,15 +212,17 @@ module RMail
|
|
213
212
|
# headers. The body part starts directly after this
|
214
213
|
# newline.
|
215
214
|
rest = data[1..-1]
|
215
|
+
elsif data[0] == ?\r && data[1] == ?\n
|
216
|
+
rest = data[2..-1]
|
216
217
|
else
|
217
|
-
header, rest = data.split(/\n\n/, 2)
|
218
|
+
header, rest = data.split(/\r?\n\r?\n/, 2)
|
218
219
|
end
|
219
220
|
break if rest
|
220
221
|
end
|
221
222
|
input.pushback(rest)
|
222
223
|
if header
|
223
224
|
mime = false
|
224
|
-
fields = header.split(/\n(?!\s)/)
|
225
|
+
fields = header.split(/\r?\n(?!\s)/)
|
225
226
|
if fields.first =~ /^From /
|
226
227
|
@handler.mbox_from(fields.first)
|
227
228
|
fields.shift
|
@@ -81,11 +81,11 @@ module RMail
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
chunk
|
84
|
-
when
|
84
|
+
when Integer
|
85
85
|
read_chunk(size)
|
86
86
|
else
|
87
87
|
raise ArgumentError,
|
88
|
-
"Read size (#{size.inspect}) must be
|
88
|
+
"Read size (#{size.inspect}) must be an Integer or nil."
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -102,7 +102,7 @@ module RMail
|
|
102
102
|
# convenient to call from derived classes when super() isn't
|
103
103
|
# easy to use.
|
104
104
|
def standard_read_chunk(size)
|
105
|
-
unless size.is_a?(
|
105
|
+
unless size.is_a?(Integer) && size > 0
|
106
106
|
raise ArgumentError,
|
107
107
|
"Read size (#{size.inspect}) must be greater than 0."
|
108
108
|
end
|
@@ -132,11 +132,11 @@ module RMail
|
|
132
132
|
|
133
133
|
# Set the chunk size of this reader in bytes. This is useful
|
134
134
|
# mainly for testing, though perhaps some operations could be
|
135
|
-
# optimized by tweaking this value. The chunk size must be
|
136
|
-
#
|
135
|
+
# optimized by tweaking this value. The chunk size must be an
|
136
|
+
# Integer greater than 0.
|
137
137
|
def chunk_size=(size)
|
138
|
-
unless size.is_a?(
|
139
|
-
raise ArgumentError, "chunk size must be
|
138
|
+
unless size.is_a?(Integer)
|
139
|
+
raise ArgumentError, "chunk size must be an Integer"
|
140
140
|
end
|
141
141
|
unless size >= 1
|
142
142
|
raise ArgumentError, "invalid size #{size.inspect} given"
|
data/lib/rmail/serialize.rb
CHANGED
@@ -74,7 +74,7 @@ module RMail
|
|
74
74
|
|
75
75
|
def serialize_low(message, depth = 0)
|
76
76
|
if message.multipart?
|
77
|
-
delimiters,
|
77
|
+
delimiters, _delimiters_boundary = message.get_delimiters
|
78
78
|
unless delimiters
|
79
79
|
boundary = "\n--" + message.header.param('Content-Type', 'boundary')
|
80
80
|
delimiters = Array.new(message.body.length + 1, boundary + "\n")
|
data/test/testaddress.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#--
|
3
|
-
# Copyright (C) 2001, 2002, 2003, 2007 Matt Armstrong. All rights reserved.
|
3
|
+
# Copyright (C) 2001, 2002, 2003, 2007, 2008 Matt Armstrong. All rights reserved.
|
4
4
|
#
|
5
5
|
# Redistribution and use in source and binary forms, with or without
|
6
6
|
# modification, are permitted provided that the following conditions are met:
|
@@ -419,7 +419,7 @@ class TestRMailAddress < TestBase
|
|
419
419
|
:format => '"Jason @ Tibbitts" <tibbs@uh.edu>' } ] ]
|
420
420
|
|
421
421
|
# Majordomo II parses all of these with an error. We have deleted
|
422
|
-
# some of the tests
|
422
|
+
# some of the tests when they are actually legal.
|
423
423
|
validate_case ['tibbs@uh.edu Jason Tibbitts', [] ]
|
424
424
|
validate_case ['@uh.edu', [] ] # Can't start with @
|
425
425
|
validate_case ['J <tibbs>', [] ] # Not FQDN
|
@@ -644,7 +644,6 @@ class TestRMailAddress < TestBase
|
|
644
644
|
end
|
645
645
|
|
646
646
|
def test_rfc_822
|
647
|
-
|
648
647
|
validate_case\
|
649
648
|
['":sysmail"@ Some-Group. Some-Org, Muhammed.(I am the greatest) Ali @(the)Vegas.WBA',
|
650
649
|
[ { :name => nil,
|
@@ -664,7 +663,6 @@ class TestRMailAddress < TestBase
|
|
664
663
|
end
|
665
664
|
|
666
665
|
def test_misc_addresses()
|
667
|
-
|
668
666
|
# Make sure that parsing empty stuff works
|
669
667
|
assert_equal([], RMail::Address.parse(nil))
|
670
668
|
assert_equal([], RMail::Address.parse(""))
|
@@ -794,17 +792,31 @@ class TestRMailAddress < TestBase
|
|
794
792
|
} ] ]
|
795
793
|
end
|
796
794
|
|
795
|
+
def test_bug_23043
|
796
|
+
# http://rubyforge.org/tracker/?func=detail&atid=1754&aid=23043&group_id=446
|
797
|
+
validate_case\
|
798
|
+
['=?iso-8859-1?Q?acme@example.com?= <acme@example.com>',
|
799
|
+
[ { :name => '=?iso-8859-1?Q?acme@example.com?=',
|
800
|
+
:display_name => '=?iso-8859-1?Q?acme@example.com?=',
|
801
|
+
:address => 'acme@example.com',
|
802
|
+
:comments => nil,
|
803
|
+
:domain => 'example.com',
|
804
|
+
:local => 'acme',
|
805
|
+
:format => '"=?iso-8859-1?Q?acme@example.com?=" <acme@example.com>',
|
806
|
+
} ] ]
|
807
|
+
end
|
808
|
+
|
797
809
|
def test_invalid_addresses()
|
798
810
|
# The display name isn't encoded -- bad, but we parse it.
|
799
811
|
validate_case\
|
800
|
-
["\322\315\322 \312\353\363\341 <bar@foo.invalid>",
|
801
|
-
[ { :name => "\322\315\322 \312\353\363\341",
|
802
|
-
:display_name => "\322\315\322 \312\353\363\341",
|
812
|
+
["\322\315\322 \312\353\363\341 <bar@foo.invalid>".force_encoding('ASCII-8BIT'),
|
813
|
+
[ { :name => "\322\315\322 \312\353\363\341".force_encoding("ASCII-8BIT"),
|
814
|
+
:display_name => "\322\315\322 \312\353\363\341".force_encoding("ASCII-8BIT"),
|
803
815
|
:address => 'bar@foo.invalid',
|
804
816
|
:comments => nil,
|
805
817
|
:domain => 'foo.invalid',
|
806
818
|
:local => 'bar',
|
807
|
-
:format => "\"\322\315\322 \312\353\363\341\" <bar@foo.invalid>",
|
819
|
+
:format => "\"\322\315\322 \312\353\363\341\" <bar@foo.invalid>".force_encoding("ASCII-8BIT"),
|
808
820
|
} ] ]
|
809
821
|
end
|
810
822
|
|
@@ -1117,13 +1129,13 @@ class TestRMailAddress < TestBase
|
|
1117
1129
|
assert_equal(nil, addr.domain)
|
1118
1130
|
assert_equal(nil, addr.local)
|
1119
1131
|
|
1120
|
-
|
1132
|
+
assert_raise(ArgumentError) {
|
1121
1133
|
RMail::Address.new(["bob"])
|
1122
1134
|
}
|
1123
|
-
|
1135
|
+
assert_raise(ArgumentError) {
|
1124
1136
|
RMail::Address.new(Object.new)
|
1125
1137
|
}
|
1126
|
-
|
1138
|
+
assert_raise(ArgumentError) {
|
1127
1139
|
RMail::Address.new(Hash.new)
|
1128
1140
|
}
|
1129
1141
|
end
|
data/test/testbase.rb
CHANGED
@@ -27,6 +27,26 @@
|
|
27
27
|
|
28
28
|
# Base for all the test cases, providing a default setup and teardown
|
29
29
|
|
30
|
+
if ENV["COVERAGE"] || ENV["TRAVIS"]
|
31
|
+
require "simplecov"
|
32
|
+
SimpleCov.start do
|
33
|
+
add_filter "/test/"
|
34
|
+
end
|
35
|
+
top = File.expand_path("../..", __FILE__)
|
36
|
+
# track all ruby files under lib
|
37
|
+
SimpleCov.track_files("#{top}/lib/**/*.rb")
|
38
|
+
|
39
|
+
# use coveralls for on-line code coverage reporting at Travis CI
|
40
|
+
if ENV["TRAVIS"]
|
41
|
+
require "coveralls"
|
42
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [
|
43
|
+
SimpleCov::Formatter::HTMLFormatter,
|
44
|
+
Coveralls::SimpleCov::Formatter
|
45
|
+
]
|
46
|
+
end
|
47
|
+
SimpleCov.start
|
48
|
+
end
|
49
|
+
|
30
50
|
require 'test/unit'
|
31
51
|
require 'rbconfig.rb'
|
32
52
|
require 'tempfile'
|
@@ -39,7 +59,7 @@ rescue LoadError
|
|
39
59
|
end
|
40
60
|
|
41
61
|
class TestBase < Test::Unit::TestCase
|
42
|
-
include
|
62
|
+
include RbConfig
|
43
63
|
|
44
64
|
attr_reader :scratch_dir
|
45
65
|
|
data/test/testheader.rb
CHANGED
@@ -209,7 +209,12 @@ class TestRMailHeader < TestBase
|
|
209
209
|
# Test the params argument
|
210
210
|
h = RMail::Header.new
|
211
211
|
h.add("name", "value", nil, 'param1' => 'value1', 'param2' => '+value2')
|
212
|
-
|
212
|
+
# Param order can not be guaranteed since they are given as dict to the
|
213
|
+
# function.
|
214
|
+
#assert_equal('value; param1=value1; param2="+value2"', h['name'])
|
215
|
+
header_check = (h['name'] == 'value; param1=value1; param2="+value2"' or
|
216
|
+
h['name'] == 'value; param2="+value2"; param1=value1')
|
217
|
+
assert(header_check)
|
213
218
|
|
214
219
|
h = RMail::Header.new
|
215
220
|
h.add_raw("MIME-Version: 1.0")
|
@@ -776,6 +781,10 @@ EOF
|
|
776
781
|
h.delete('content-type')
|
777
782
|
h['content-type'] = ' foo/html ; charset=ISO-8859-1'
|
778
783
|
assert_equal("foo/html", h.content_type)
|
784
|
+
|
785
|
+
h = RMail::Header.new
|
786
|
+
h['content-type'] = ''
|
787
|
+
assert_equal(nil, h.content_type)
|
779
788
|
end
|
780
789
|
|
781
790
|
def test_media_type
|
@@ -1016,18 +1025,7 @@ EOF
|
|
1016
1025
|
begin
|
1017
1026
|
h = RMail::Header.new
|
1018
1027
|
# This one is bogus and can't even be parsed.
|
1019
|
-
h.add_raw("Date:
|
1020
|
-
t = assert_nothing_raised {
|
1021
|
-
h.date
|
1022
|
-
}
|
1023
|
-
assert_nil(t)
|
1024
|
-
end
|
1025
|
-
|
1026
|
-
begin
|
1027
|
-
h = RMail::Header.new
|
1028
|
-
# This time is out of the range that can be represented by a
|
1029
|
-
# Time object.
|
1030
|
-
h.add_raw("Date: Sun, 14 Jun 2065 05:51:55 +0200")
|
1028
|
+
h.add_raw("Date: A long time ago")
|
1031
1029
|
t = assert_nothing_raised {
|
1032
1030
|
h.date
|
1033
1031
|
}
|
@@ -1222,4 +1220,14 @@ EOF
|
|
1222
1220
|
assert_equal(0, h.recipients.length)
|
1223
1221
|
end
|
1224
1222
|
|
1223
|
+
def test_invalid_encoding_utf8
|
1224
|
+
_, value = RMail::Header::Field.parse('Subject: abgeändertes Angebot')
|
1225
|
+
assert_equal 'abgeändertes Angebot', value
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
def test_invalid_encoding_iso_8859_1
|
1229
|
+
_, value = RMail::Header::Field.parse('Subject: abgeändertes Angebot'.encode(Encoding::ISO_8859_1))
|
1230
|
+
assert_equal 'abgeändertes Angebot'.encode(Encoding::ISO_8859_1), value
|
1231
|
+
end
|
1232
|
+
|
1225
1233
|
end
|
data/test/testmessage.rb
CHANGED
metadata
CHANGED
@@ -1,38 +1,56 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rmail
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Matt Armstrong
|
8
|
+
- Antonio Terceiro
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
date: 2008-01-05 00:00:00 -08:00
|
13
|
-
default_executable:
|
12
|
+
date: 2020-07-08 00:00:00.000000000 Z
|
14
13
|
dependencies: []
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
description: |2
|
15
|
+
RMail is a lightweight mail library containing various utility classes and
|
16
|
+
modules that allow ruby scripts to parse, modify, and generate MIME mail
|
17
|
+
messages.
|
18
|
+
email: terceiro@softwarelivre.org
|
18
19
|
executables: []
|
19
|
-
|
20
20
|
extensions: []
|
21
|
-
|
22
|
-
|
23
|
-
-
|
24
|
-
-
|
21
|
+
extra_rdoc_files:
|
22
|
+
- README.md
|
23
|
+
- ChangeLog
|
24
|
+
- THANKS
|
25
|
+
- TODO
|
26
|
+
- guide/Intro.txt
|
27
|
+
- guide/MIME.txt
|
28
|
+
- guide/TableOfContents.txt
|
29
|
+
files:
|
30
|
+
- ChangeLog
|
31
|
+
- NOTES
|
32
|
+
- README.md
|
33
|
+
- Rakefile
|
25
34
|
- THANKS
|
26
35
|
- TODO
|
27
36
|
- guide/Intro.txt
|
28
37
|
- guide/MIME.txt
|
29
38
|
- guide/TableOfContents.txt
|
30
|
-
|
39
|
+
- lib/rmail.rb
|
40
|
+
- lib/rmail/address.rb
|
41
|
+
- lib/rmail/header.rb
|
42
|
+
- lib/rmail/mailbox.rb
|
43
|
+
- lib/rmail/mailbox/mboxreader.rb
|
44
|
+
- lib/rmail/message.rb
|
45
|
+
- lib/rmail/parser.rb
|
46
|
+
- lib/rmail/parser/multipart.rb
|
47
|
+
- lib/rmail/parser/pushbackreader.rb
|
48
|
+
- lib/rmail/serialize.rb
|
49
|
+
- lib/rmail/utils.rb
|
50
|
+
- lib/rmail/version.rb
|
31
51
|
- test/addrgrammar.txt
|
32
|
-
- test/data
|
33
52
|
- test/data/mbox.odd
|
34
53
|
- test/data/mbox.simple
|
35
|
-
- test/data/multipart
|
36
54
|
- test/data/multipart/data.1
|
37
55
|
- test/data/multipart/data.10
|
38
56
|
- test/data/multipart/data.11
|
@@ -50,7 +68,14 @@ files:
|
|
50
68
|
- test/data/multipart/data.7
|
51
69
|
- test/data/multipart/data.8
|
52
70
|
- test/data/multipart/data.9
|
53
|
-
- test/data/parser
|
71
|
+
- test/data/parser.badmime1
|
72
|
+
- test/data/parser.badmime2
|
73
|
+
- test/data/parser.nested-multipart
|
74
|
+
- test/data/parser.nested-simple
|
75
|
+
- test/data/parser.nested-simple2
|
76
|
+
- test/data/parser.nested-simple3
|
77
|
+
- test/data/parser.rfc822
|
78
|
+
- test/data/parser.simple-mime
|
54
79
|
- test/data/parser/multipart.1
|
55
80
|
- test/data/parser/multipart.10
|
56
81
|
- test/data/parser/multipart.11
|
@@ -67,15 +92,6 @@ files:
|
|
67
92
|
- test/data/parser/multipart.7
|
68
93
|
- test/data/parser/multipart.8
|
69
94
|
- test/data/parser/multipart.9
|
70
|
-
- test/data/parser.badmime1
|
71
|
-
- test/data/parser.badmime2
|
72
|
-
- test/data/parser.nested-multipart
|
73
|
-
- test/data/parser.nested-simple
|
74
|
-
- test/data/parser.nested-simple2
|
75
|
-
- test/data/parser.nested-simple3
|
76
|
-
- test/data/parser.rfc822
|
77
|
-
- test/data/parser.simple-mime
|
78
|
-
- test/data/transparency
|
79
95
|
- test/data/transparency/absolute.1
|
80
96
|
- test/data/transparency/absolute.2
|
81
97
|
- test/data/transparency/absolute.3
|
@@ -101,61 +117,32 @@ files:
|
|
101
117
|
- test/testserialize.rb
|
102
118
|
- test/testtestbase.rb
|
103
119
|
- test/testtranspparency.rb
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
- lib/rmail
|
108
|
-
- lib/rmail/address.rb
|
109
|
-
- lib/rmail/header.rb
|
110
|
-
- lib/rmail/mailbox
|
111
|
-
- lib/rmail/mailbox/mboxreader.rb
|
112
|
-
- lib/rmail/mailbox.rb
|
113
|
-
- lib/rmail/message.rb
|
114
|
-
- lib/rmail/parser
|
115
|
-
- lib/rmail/parser/multipart.rb
|
116
|
-
- lib/rmail/parser/pushbackreader.rb
|
117
|
-
- lib/rmail/parser.rb
|
118
|
-
- lib/rmail/serialize.rb
|
119
|
-
- lib/rmail/utils.rb
|
120
|
-
- lib/rmail.rb
|
121
|
-
- install.rb
|
122
|
-
- NEWS
|
123
|
-
- NOTES
|
124
|
-
- README
|
125
|
-
- THANKS
|
126
|
-
- TODO
|
127
|
-
- Rakefile
|
128
|
-
- version
|
129
|
-
has_rdoc: true
|
130
|
-
homepage: http://www.rfc20.org/rubymail
|
120
|
+
homepage: https://github.com/terceiro/rmail
|
121
|
+
licenses: []
|
122
|
+
metadata: {}
|
131
123
|
post_install_message:
|
132
|
-
rdoc_options:
|
133
|
-
- --title
|
134
|
-
- RubyMail Documentation (version 1.
|
135
|
-
- --main
|
124
|
+
rdoc_options:
|
125
|
+
- "--title"
|
126
|
+
- RubyMail Documentation (version 1.1.4)
|
127
|
+
- "--main"
|
136
128
|
- README
|
137
|
-
- --exclude
|
129
|
+
- "--exclude"
|
138
130
|
- SCCS
|
139
|
-
require_paths:
|
131
|
+
require_paths:
|
140
132
|
- lib
|
141
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
143
135
|
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
136
|
+
- !ruby/object:Gem::Version
|
145
137
|
version: 1.8.1
|
146
|
-
|
147
|
-
|
148
|
-
requirements:
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
149
140
|
- - ">="
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
version:
|
152
|
-
version:
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
153
143
|
requirements: []
|
154
|
-
|
155
|
-
rubyforge_project: rubymail
|
156
|
-
rubygems_version: 1.0.1
|
144
|
+
rubygems_version: 3.1.2
|
157
145
|
signing_key:
|
158
|
-
specification_version:
|
146
|
+
specification_version: 4
|
159
147
|
summary: A MIME mail parsing and generation library.
|
160
148
|
test_files: []
|
161
|
-
|