rmail 1.0.0 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|