mail 2.1.3 → 2.1.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mail might be problematic. Click here for more details.
- data/CHANGELOG.rdoc +37 -0
- data/README.rdoc +1 -1
- data/Rakefile +2 -3
- data/TODO.rdoc +2 -12
- data/lib/mail.rb +7 -4
- data/lib/mail/attachments_list.rb +28 -10
- data/lib/mail/body.rb +44 -15
- data/lib/mail/core_extensions/string.rb +4 -0
- data/lib/mail/elements/content_transfer_encoding_element.rb +4 -1
- data/lib/mail/encodings/7bit.rb +29 -0
- data/lib/mail/encodings/8bit.rb +29 -0
- data/lib/mail/encodings/base64.rb +18 -5
- data/lib/mail/encodings/binary.rb +29 -0
- data/lib/mail/encodings/encodings.rb +22 -6
- data/lib/mail/encodings/quoted_printable.rb +27 -4
- data/lib/mail/encodings/transfer_encoding.rb +58 -0
- data/lib/mail/field.rb +4 -2
- data/lib/mail/fields/common/parameter_hash.rb +12 -3
- data/lib/mail/fields/content_disposition_field.rb +12 -2
- data/lib/mail/fields/content_location_field.rb +2 -2
- data/lib/mail/fields/content_transfer_encoding_field.rb +5 -3
- data/lib/mail/fields/content_type_field.rb +14 -4
- data/lib/mail/fields/mime_version_field.rb +2 -2
- data/lib/mail/fields/received_field.rb +8 -4
- data/lib/mail/fields/structured_field.rb +4 -0
- data/lib/mail/fields/unstructured_field.rb +5 -0
- data/lib/mail/header.rb +13 -6
- data/lib/mail/mail.rb +1 -1
- data/lib/mail/message.rb +100 -28
- data/lib/mail/network/delivery_methods/smtp.rb +1 -1
- data/lib/mail/parsers/address_lists.rb +4 -1
- data/lib/mail/parsers/content_disposition.rb +24 -6
- data/lib/mail/parsers/content_location.rb +8 -2
- data/lib/mail/parsers/content_transfer_encoding.rb +73 -83
- data/lib/mail/parsers/content_transfer_encoding.treetop +5 -10
- data/lib/mail/parsers/content_type.rb +36 -9
- data/lib/mail/parsers/date_time.rb +4 -1
- data/lib/mail/parsers/envelope_from.rb +8 -2
- data/lib/mail/parsers/message_ids.rb +4 -1
- data/lib/mail/parsers/mime_version.rb +4 -1
- data/lib/mail/parsers/phrase_lists.rb +4 -1
- data/lib/mail/parsers/received.rb +4 -1
- data/lib/mail/parsers/rfc2045.rb +75 -17
- data/lib/mail/parsers/rfc2045.treetop +2 -1
- data/lib/mail/parsers/rfc2822.rb +316 -79
- data/lib/mail/parsers/rfc2822_obsolete.rb +200 -50
- data/lib/mail/part.rb +21 -6
- data/lib/mail/patterns.rb +3 -3
- data/lib/mail/utilities.rb +4 -4
- data/lib/mail/vendor/treetop-1.4.3/Or +0 -0
- data/lib/mail/vendor/treetop-1.4.3/Rakefile +11 -6
- data/lib/mail/vendor/treetop-1.4.3/Treetop.tmbundle/Preferences/Comments.tmPreferences +22 -0
- data/lib/mail/vendor/treetop-1.4.3/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +28 -1
- data/lib/mail/vendor/treetop-1.4.3/bin/tt +5 -5
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop.rb +3 -19
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/bootstrap_gen_1_metagrammar.rb +4 -7
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler.rb +7 -6
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler/metagrammar.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes.rb +19 -20
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/polyglot.rb +9 -0
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/ruby_extensions.rb +1 -2
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/runtime.rb +6 -5
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/runtime/interval_skip_list.rb +3 -4
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/runtime/syntax_node.rb +7 -7
- data/lib/mail/vendor/treetop-1.4.3/lib/treetop/version.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/script/generate_metagrammar.rb +3 -4
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/and_predicate_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/anything_symbol_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/character_class_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/choice_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/circular_compilation_spec.rb +3 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/failure_propagation_functional_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/grammar_compiler_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/grammar_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/multibyte_chars_spec.rb +1 -9
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/nonterminal_symbol_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/not_predicate_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/one_or_more_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/optional_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/parenthesized_expression_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/parsing_rule_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/repeated_subrule_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/semantic_predicate_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/sequence_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/terminal_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/terminal_symbol_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/tt_compiler_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/compiler/zero_or_more_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/composition/grammar_composition_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/ruby_extensions/string_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/compiled_parser_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/delete_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/expire_range_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/insert_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +2 -3
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/spec_helper.rb +2 -2
- data/lib/mail/vendor/treetop-1.4.3/spec/runtime/syntax_node_spec.rb +1 -1
- data/lib/mail/vendor/treetop-1.4.3/spec/spec_helper.rb +4 -5
- data/lib/mail/vendor/treetop-1.4.3/treetop.gemspec +2 -2
- data/lib/mail/version.rb +1 -1
- data/lib/mail/version_specific/ruby_1_8.rb +1 -3
- data/lib/mail/version_specific/ruby_1_9.rb +1 -2
- data/lib/tasks/treetop.rake +1 -1
- metadata +33 -14
- data/lib/mail/vendor/treetop-1.4.3/spec/spec_suite.rb +0 -4
data/lib/mail/mail.rb
CHANGED
data/lib/mail/message.rb
CHANGED
@@ -10,7 +10,7 @@ module Mail
|
|
10
10
|
#
|
11
11
|
# * A Header object which contians all information and settings of the header of the email
|
12
12
|
# * Body object which contains all parts of the email that are not part of the header, this
|
13
|
-
# includes any attachments, body text,
|
13
|
+
# includes any attachments, body text, MIME parts etc.
|
14
14
|
#
|
15
15
|
# ==Per RFC2822
|
16
16
|
#
|
@@ -99,6 +99,7 @@ module Mail
|
|
99
99
|
@body = nil
|
100
100
|
@text_part = nil
|
101
101
|
@html_part = nil
|
102
|
+
@errors = nil
|
102
103
|
|
103
104
|
@perform_deliveries = true
|
104
105
|
@raise_delivery_errors = true
|
@@ -106,7 +107,9 @@ module Mail
|
|
106
107
|
@delivery_handler = nil
|
107
108
|
|
108
109
|
@delivery_method = Mail.delivery_method.dup
|
109
|
-
|
110
|
+
|
111
|
+
@transport_encoding = Mail::Encodings.get_encoding('7bit')
|
112
|
+
|
110
113
|
if args.flatten.first.respond_to?(:each_pair)
|
111
114
|
init_with_hash(args.flatten.first)
|
112
115
|
else
|
@@ -374,6 +377,27 @@ module Mail
|
|
374
377
|
end
|
375
378
|
end
|
376
379
|
|
380
|
+
# Returns a list of parser errors on the header, each field that had an error
|
381
|
+
# will be reparsed as an unstructured field to preserve the data inside, but
|
382
|
+
# will not be used for further processing.
|
383
|
+
#
|
384
|
+
# It returns a nested array of [field_name, value, original_error_message]
|
385
|
+
# per error found.
|
386
|
+
#
|
387
|
+
# Example:
|
388
|
+
#
|
389
|
+
# message = Mail.new("Content-Transfer-Encoding: weirdo\r\n")
|
390
|
+
# message.errors.size #=> 1
|
391
|
+
# message.errors.first[0] #=> "Content-Transfer-Encoding"
|
392
|
+
# message.errors.first[1] #=> "weirdo"
|
393
|
+
# message.errors.first[3] #=> <The original error message exception>
|
394
|
+
#
|
395
|
+
# This is a good first defence on detecting spam by the way. Some spammers send
|
396
|
+
# invalid emails to try and get email parsers to give up parsing them.
|
397
|
+
def errors
|
398
|
+
header.errors
|
399
|
+
end
|
400
|
+
|
377
401
|
# Returns the Bcc value of the mail object as an array of strings of
|
378
402
|
# address specs.
|
379
403
|
#
|
@@ -519,7 +543,19 @@ module Mail
|
|
519
543
|
def date=( val )
|
520
544
|
header[:date] = val
|
521
545
|
end
|
522
|
-
|
546
|
+
|
547
|
+
def transport_encoding( val = nil)
|
548
|
+
if val
|
549
|
+
self.transport_encoding = val
|
550
|
+
else
|
551
|
+
@transport_encoding
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
def transport_encoding=( val )
|
556
|
+
@transport_encoding = Mail::Encodings.get_encoding(val)
|
557
|
+
end
|
558
|
+
|
523
559
|
# Returns the From value of the mail object as an array of strings of
|
524
560
|
# address specs.
|
525
561
|
#
|
@@ -603,14 +639,14 @@ module Mail
|
|
603
639
|
header[:message_id] = val
|
604
640
|
end
|
605
641
|
|
606
|
-
# Returns the
|
642
|
+
# Returns the MIME version of the email as a string
|
607
643
|
#
|
608
644
|
# Example:
|
609
645
|
#
|
610
646
|
# mail.mime_version = '1.0'
|
611
647
|
# mail.mime_version #=> '1.0'
|
612
648
|
#
|
613
|
-
# Also allows you to set the
|
649
|
+
# Also allows you to set the MIME version by passing a string as a parameter.
|
614
650
|
#
|
615
651
|
# Example:
|
616
652
|
#
|
@@ -620,7 +656,7 @@ module Mail
|
|
620
656
|
default :mime_version, val
|
621
657
|
end
|
622
658
|
|
623
|
-
# Sets the
|
659
|
+
# Sets the MIME version of the email by accepting a string
|
624
660
|
#
|
625
661
|
# Example:
|
626
662
|
#
|
@@ -1052,7 +1088,7 @@ module Mail
|
|
1052
1088
|
case
|
1053
1089
|
when value == nil
|
1054
1090
|
@body = Mail::Body.new('')
|
1055
|
-
when @body &&
|
1091
|
+
when @body && @body.multipart?
|
1056
1092
|
@body << Mail::Part.new(value)
|
1057
1093
|
else
|
1058
1094
|
@body = Mail::Body.new(value)
|
@@ -1078,7 +1114,19 @@ module Mail
|
|
1078
1114
|
@body
|
1079
1115
|
end
|
1080
1116
|
end
|
1081
|
-
|
1117
|
+
|
1118
|
+
def body_encoding(value)
|
1119
|
+
if value.nil?
|
1120
|
+
body.encoding
|
1121
|
+
else
|
1122
|
+
body.encoding = value
|
1123
|
+
end
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
def body_encoding=(value)
|
1127
|
+
body.encoding = value
|
1128
|
+
end
|
1129
|
+
|
1082
1130
|
# Returns the list of addresses this message should be sent to by
|
1083
1131
|
# collecting the addresses off the to, cc and bcc fields.
|
1084
1132
|
#
|
@@ -1232,7 +1280,8 @@ module Mail
|
|
1232
1280
|
end
|
1233
1281
|
|
1234
1282
|
def has_content_transfer_encoding?
|
1235
|
-
|
1283
|
+
header[:content_transfer_encoding] &&
|
1284
|
+
header[:content_transfer_encoding].errors.blank?
|
1236
1285
|
end
|
1237
1286
|
|
1238
1287
|
def has_transfer_encoding? # :nodoc:
|
@@ -1262,8 +1311,8 @@ module Mail
|
|
1262
1311
|
|
1263
1312
|
# Creates a new empty Mime Version field and inserts it in the correct order
|
1264
1313
|
# into the Header. The MimeVersion object will automatically generate
|
1265
|
-
#
|
1266
|
-
# specifying a
|
1314
|
+
# set itself to '1.0' if you try and encode it or output it to_s without
|
1315
|
+
# specifying a version yourself.
|
1267
1316
|
#
|
1268
1317
|
# It will preserve any date you specify if you do.
|
1269
1318
|
def add_mime_version(ver_val = '')
|
@@ -1281,9 +1330,9 @@ module Mail
|
|
1281
1330
|
#
|
1282
1331
|
# Otherwise raises a warning
|
1283
1332
|
def add_charset
|
1284
|
-
if body.only_us_ascii?
|
1333
|
+
if body.only_us_ascii? and !body.empty?
|
1285
1334
|
header[:content_type].parameters['charset'] = 'US-ASCII'
|
1286
|
-
|
1335
|
+
elsif !body.empty?
|
1287
1336
|
warning = "Non US-ASCII detected and no charset defined.\nDefaulting to UTF-8, set your own if this is incorrect.\n"
|
1288
1337
|
STDERR.puts(warning)
|
1289
1338
|
header[:content_type].parameters['charset'] = 'UTF-8'
|
@@ -1313,7 +1362,7 @@ module Mail
|
|
1313
1362
|
content_transfer_encoding
|
1314
1363
|
end
|
1315
1364
|
|
1316
|
-
# Returns the
|
1365
|
+
# Returns the MIME media type of part we are on, this is taken from the content-type header
|
1317
1366
|
def mime_type
|
1318
1367
|
content_type ? header[:content_type].string : nil
|
1319
1368
|
end
|
@@ -1425,7 +1474,7 @@ module Mail
|
|
1425
1474
|
#
|
1426
1475
|
# mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
|
1427
1476
|
#
|
1428
|
-
# If you do this, then Mail will take the file name and work out the
|
1477
|
+
# If you do this, then Mail will take the file name and work out the MIME media type
|
1429
1478
|
# set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
|
1430
1479
|
# base64 encode the contents of the attachment all for you.
|
1431
1480
|
#
|
@@ -1509,7 +1558,7 @@ module Mail
|
|
1509
1558
|
|
1510
1559
|
# Adds a part to the parts list or creates the part list
|
1511
1560
|
def add_part(part)
|
1512
|
-
if body.
|
1561
|
+
if !body.multipart? && !self.body.decoded.blank?
|
1513
1562
|
@text_part = Mail::Part.new('Content-Type: text/plain;')
|
1514
1563
|
@text_part.body = body.decoded
|
1515
1564
|
self.body << @text_part
|
@@ -1537,7 +1586,7 @@ module Mail
|
|
1537
1586
|
|
1538
1587
|
# Adds a file to the message. You have two options with this method, you can
|
1539
1588
|
# just pass in the absolute path to the file you want and Mail will read the file,
|
1540
|
-
# get the filename from the path you pass in and guess the
|
1589
|
+
# get the filename from the path you pass in and guess the MIME media type, or you
|
1541
1590
|
# can pass in the filename as a string, and pass in the file content as a blob.
|
1542
1591
|
#
|
1543
1592
|
# Example:
|
@@ -1588,10 +1637,14 @@ module Mail
|
|
1588
1637
|
# Encodes the message, calls encode on all it's parts, gets an email message
|
1589
1638
|
# ready to send
|
1590
1639
|
def ready_to_send!
|
1591
|
-
|
1640
|
+
identify_and_set_transfer_encoding
|
1641
|
+
parts.each do |part|
|
1642
|
+
part.transport_encoding = transport_encoding
|
1643
|
+
part.ready_to_send!
|
1644
|
+
end
|
1592
1645
|
add_required_fields
|
1593
1646
|
end
|
1594
|
-
|
1647
|
+
|
1595
1648
|
def encode!
|
1596
1649
|
STDERR.puts("Deprecated in 1.1.0 in favour of :ready_to_send! as it is less confusing with encoding and decoding.")
|
1597
1650
|
ready_to_send!
|
@@ -1604,7 +1657,7 @@ module Mail
|
|
1604
1657
|
ready_to_send!
|
1605
1658
|
buffer = header.encoded
|
1606
1659
|
buffer << "\r\n"
|
1607
|
-
buffer << body.encoded
|
1660
|
+
buffer << body.encoded(content_transfer_encoding)
|
1608
1661
|
buffer
|
1609
1662
|
end
|
1610
1663
|
|
@@ -1617,8 +1670,11 @@ module Mail
|
|
1617
1670
|
end
|
1618
1671
|
|
1619
1672
|
def decoded
|
1620
|
-
|
1673
|
+
case
|
1674
|
+
when self.attachment?
|
1621
1675
|
decode_body
|
1676
|
+
when !self.multipart?
|
1677
|
+
body.decoded
|
1622
1678
|
else
|
1623
1679
|
raise NoMethodError, 'Can not decode an entire message, try calling #decoded on the various fields and body or parts if it is a multipart message.'
|
1624
1680
|
end
|
@@ -1633,11 +1689,7 @@ module Mail
|
|
1633
1689
|
end
|
1634
1690
|
|
1635
1691
|
def decode_body
|
1636
|
-
|
1637
|
-
Mail::Encodings.get_encoding(content_transfer_encoding).decode(body.encoded)
|
1638
|
-
else
|
1639
|
-
raise UnknownEncodingType, "Don't know how to decode #{content_transfer_encoding}, please call #encoded and decode it yourself."
|
1640
|
-
end
|
1692
|
+
body.decoded
|
1641
1693
|
end
|
1642
1694
|
|
1643
1695
|
# Returns true if this part is an attachment
|
@@ -1697,13 +1749,21 @@ module Mail
|
|
1697
1749
|
end
|
1698
1750
|
|
1699
1751
|
def add_encoding_to_body
|
1700
|
-
|
1752
|
+
if has_content_transfer_encoding?
|
1701
1753
|
body.encoding = content_transfer_encoding
|
1702
1754
|
end
|
1703
1755
|
end
|
1756
|
+
|
1757
|
+
def identify_and_set_transfer_encoding
|
1758
|
+
if body.multipart?
|
1759
|
+
self.content_transfer_encoding = @transport_encoding
|
1760
|
+
else
|
1761
|
+
self.content_transfer_encoding = body.get_best_encoding(@transport_encoding)
|
1762
|
+
end
|
1763
|
+
end
|
1704
1764
|
|
1705
1765
|
def add_required_fields
|
1706
|
-
add_multipart_mixed_header unless
|
1766
|
+
add_multipart_mixed_header unless !body.multipart?
|
1707
1767
|
@body = Mail::Body.new('') if body.nil?
|
1708
1768
|
add_message_id unless (has_message_id? || self.class == Mail::Part)
|
1709
1769
|
add_date unless has_date?
|
@@ -1739,14 +1799,26 @@ module Mail
|
|
1739
1799
|
@header = Mail::Header.new
|
1740
1800
|
@body = Mail::Body.new
|
1741
1801
|
|
1802
|
+
# We need to store the body until last, as we need all headers added first
|
1803
|
+
body_content = nil
|
1804
|
+
|
1742
1805
|
passed_in_options.each_pair do |k,v|
|
1743
1806
|
k = underscoreize(k).to_sym if k.class == String
|
1744
1807
|
if k == :headers
|
1745
1808
|
self.headers(v)
|
1809
|
+
elsif k == :body
|
1810
|
+
body_content = v
|
1746
1811
|
else
|
1747
1812
|
self[k] = v
|
1748
1813
|
end
|
1749
1814
|
end
|
1815
|
+
|
1816
|
+
if body_content
|
1817
|
+
self.body = body_content
|
1818
|
+
if has_content_transfer_encoding?
|
1819
|
+
body.encoding = content_transfer_encoding
|
1820
|
+
end
|
1821
|
+
end
|
1750
1822
|
end
|
1751
1823
|
|
1752
1824
|
def init_with_string(string)
|
@@ -27,7 +27,7 @@ module Mail
|
|
27
27
|
# Mail.defaults do
|
28
28
|
# delivery_method :smtp, { :address => "smtp.gmail.com",
|
29
29
|
# :port => 587,
|
30
|
-
# :domain => '
|
30
|
+
# :domain => 'your.host.name',
|
31
31
|
# :user_name => '<username>',
|
32
32
|
# :password => '<password>',
|
33
33
|
# :authentication => 'plain',
|
@@ -27,7 +27,10 @@ module Mail
|
|
27
27
|
start_index = index
|
28
28
|
if node_cache[:primary_address].has_key?(index)
|
29
29
|
cached = node_cache[:primary_address][index]
|
30
|
-
|
30
|
+
if cached
|
31
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
32
|
+
@index = cached.interval.end
|
33
|
+
end
|
31
34
|
return cached
|
32
35
|
end
|
33
36
|
|
@@ -49,7 +49,10 @@ module Mail
|
|
49
49
|
start_index = index
|
50
50
|
if node_cache[:content_disposition].has_key?(index)
|
51
51
|
cached = node_cache[:content_disposition][index]
|
52
|
-
|
52
|
+
if cached
|
53
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
54
|
+
@index = cached.interval.end
|
55
|
+
end
|
53
56
|
return cached
|
54
57
|
end
|
55
58
|
|
@@ -114,7 +117,10 @@ module Mail
|
|
114
117
|
start_index = index
|
115
118
|
if node_cache[:disposition_type].has_key?(index)
|
116
119
|
cached = node_cache[:disposition_type][index]
|
117
|
-
|
120
|
+
if cached
|
121
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
122
|
+
@index = cached.interval.end
|
123
|
+
end
|
118
124
|
return cached
|
119
125
|
end
|
120
126
|
|
@@ -169,7 +175,10 @@ module Mail
|
|
169
175
|
start_index = index
|
170
176
|
if node_cache[:extension_token].has_key?(index)
|
171
177
|
cached = node_cache[:extension_token][index]
|
172
|
-
|
178
|
+
if cached
|
179
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
180
|
+
@index = cached.interval.end
|
181
|
+
end
|
173
182
|
return cached
|
174
183
|
end
|
175
184
|
|
@@ -213,7 +222,10 @@ module Mail
|
|
213
222
|
start_index = index
|
214
223
|
if node_cache[:parameter].has_key?(index)
|
215
224
|
cached = node_cache[:parameter][index]
|
216
|
-
|
225
|
+
if cached
|
226
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
227
|
+
@index = cached.interval.end
|
228
|
+
end
|
217
229
|
return cached
|
218
230
|
end
|
219
231
|
|
@@ -270,7 +282,10 @@ module Mail
|
|
270
282
|
start_index = index
|
271
283
|
if node_cache[:attribute].has_key?(index)
|
272
284
|
cached = node_cache[:attribute][index]
|
273
|
-
|
285
|
+
if cached
|
286
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
287
|
+
@index = cached.interval.end
|
288
|
+
end
|
274
289
|
return cached
|
275
290
|
end
|
276
291
|
|
@@ -305,7 +320,10 @@ module Mail
|
|
305
320
|
start_index = index
|
306
321
|
if node_cache[:value].has_key?(index)
|
307
322
|
cached = node_cache[:value][index]
|
308
|
-
|
323
|
+
if cached
|
324
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
325
|
+
@index = cached.interval.end
|
326
|
+
end
|
309
327
|
return cached
|
310
328
|
end
|
311
329
|
|
@@ -31,7 +31,10 @@ module Mail
|
|
31
31
|
start_index = index
|
32
32
|
if node_cache[:primary].has_key?(index)
|
33
33
|
cached = node_cache[:primary][index]
|
34
|
-
|
34
|
+
if cached
|
35
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
36
|
+
@index = cached.interval.end
|
37
|
+
end
|
35
38
|
return cached
|
36
39
|
end
|
37
40
|
|
@@ -69,7 +72,10 @@ module Mail
|
|
69
72
|
start_index = index
|
70
73
|
if node_cache[:location].has_key?(index)
|
71
74
|
cached = node_cache[:location][index]
|
72
|
-
|
75
|
+
if cached
|
76
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
77
|
+
@index = cached.interval.end
|
78
|
+
end
|
73
79
|
return cached
|
74
80
|
end
|
75
81
|
|
@@ -25,13 +25,20 @@ module Mail
|
|
25
25
|
def CFWS2
|
26
26
|
elements[2]
|
27
27
|
end
|
28
|
+
|
29
|
+
def CFWS3
|
30
|
+
elements[4]
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def _nt_primary
|
31
35
|
start_index = index
|
32
36
|
if node_cache[:primary].has_key?(index)
|
33
37
|
cached = node_cache[:primary][index]
|
34
|
-
|
38
|
+
if cached
|
39
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
40
|
+
@index = cached.interval.end
|
41
|
+
end
|
35
42
|
return cached
|
36
43
|
end
|
37
44
|
|
@@ -44,6 +51,25 @@ module Mail
|
|
44
51
|
if r2
|
45
52
|
r3 = _nt_CFWS
|
46
53
|
s0 << r3
|
54
|
+
if r3
|
55
|
+
if has_terminal?(";", false, index)
|
56
|
+
r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
57
|
+
@index += 1
|
58
|
+
else
|
59
|
+
terminal_parse_failure(";")
|
60
|
+
r5 = nil
|
61
|
+
end
|
62
|
+
if r5
|
63
|
+
r4 = r5
|
64
|
+
else
|
65
|
+
r4 = instantiate_node(SyntaxNode,input, index...index)
|
66
|
+
end
|
67
|
+
s0 << r4
|
68
|
+
if r4
|
69
|
+
r6 = _nt_CFWS
|
70
|
+
s0 << r6
|
71
|
+
end
|
72
|
+
end
|
47
73
|
end
|
48
74
|
end
|
49
75
|
if s0.last
|
@@ -60,8 +86,21 @@ module Mail
|
|
60
86
|
end
|
61
87
|
|
62
88
|
module Encoding0
|
63
|
-
def
|
64
|
-
|
89
|
+
def ietf_token
|
90
|
+
elements[0]
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
module Encoding1
|
96
|
+
def text_value
|
97
|
+
ietf_token.text_value
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
module Encoding2
|
102
|
+
def text_value
|
103
|
+
x_token.text_value
|
65
104
|
end
|
66
105
|
end
|
67
106
|
|
@@ -69,103 +108,54 @@ module Mail
|
|
69
108
|
start_index = index
|
70
109
|
if node_cache[:encoding].has_key?(index)
|
71
110
|
cached = node_cache[:encoding][index]
|
72
|
-
|
111
|
+
if cached
|
112
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
113
|
+
@index = cached.interval.end
|
114
|
+
end
|
73
115
|
return cached
|
74
116
|
end
|
75
117
|
|
76
118
|
i0 = index
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
119
|
+
i1, s1 = index, []
|
120
|
+
r2 = _nt_ietf_token
|
121
|
+
s1 << r2
|
122
|
+
if r2
|
123
|
+
if has_terminal?("s", false, index)
|
124
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
125
|
+
@index += 1
|
84
126
|
else
|
85
|
-
|
86
|
-
|
87
|
-
if r3
|
88
|
-
r0 = r3
|
89
|
-
else
|
90
|
-
@index = i0
|
91
|
-
r0 = nil
|
92
|
-
end
|
127
|
+
terminal_parse_failure("s")
|
128
|
+
r4 = nil
|
93
129
|
end
|
130
|
+
if r4
|
131
|
+
r3 = r4
|
132
|
+
else
|
133
|
+
r3 = instantiate_node(SyntaxNode,input, index...index)
|
134
|
+
end
|
135
|
+
s1 << r3
|
94
136
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
def _nt_known_tokens
|
102
|
-
start_index = index
|
103
|
-
if node_cache[:known_tokens].has_key?(index)
|
104
|
-
cached = node_cache[:known_tokens][index]
|
105
|
-
@index = cached.interval.end if cached
|
106
|
-
return cached
|
107
|
-
end
|
108
|
-
|
109
|
-
i0 = index
|
110
|
-
if has_terminal?("7bit", false, index)
|
111
|
-
r1 = instantiate_node(SyntaxNode,input, index...(index + 4))
|
112
|
-
@index += 4
|
137
|
+
if s1.last
|
138
|
+
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
|
139
|
+
r1.extend(Encoding0)
|
140
|
+
r1.extend(Encoding1)
|
113
141
|
else
|
114
|
-
|
142
|
+
@index = i1
|
115
143
|
r1 = nil
|
116
144
|
end
|
117
145
|
if r1
|
118
146
|
r0 = r1
|
119
147
|
else
|
120
|
-
|
121
|
-
|
122
|
-
|
148
|
+
r5 = _nt_x_token
|
149
|
+
r5.extend(Encoding2)
|
150
|
+
if r5
|
151
|
+
r0 = r5
|
123
152
|
else
|
124
|
-
|
125
|
-
|
126
|
-
end
|
127
|
-
if r2
|
128
|
-
r0 = r2
|
129
|
-
else
|
130
|
-
if has_terminal?("binary", false, index)
|
131
|
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
132
|
-
@index += 6
|
133
|
-
else
|
134
|
-
terminal_parse_failure("binary")
|
135
|
-
r3 = nil
|
136
|
-
end
|
137
|
-
if r3
|
138
|
-
r0 = r3
|
139
|
-
else
|
140
|
-
if has_terminal?("quoted-printable", false, index)
|
141
|
-
r4 = instantiate_node(SyntaxNode,input, index...(index + 16))
|
142
|
-
@index += 16
|
143
|
-
else
|
144
|
-
terminal_parse_failure("quoted-printable")
|
145
|
-
r4 = nil
|
146
|
-
end
|
147
|
-
if r4
|
148
|
-
r0 = r4
|
149
|
-
else
|
150
|
-
if has_terminal?("base64", false, index)
|
151
|
-
r5 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
152
|
-
@index += 6
|
153
|
-
else
|
154
|
-
terminal_parse_failure("base64")
|
155
|
-
r5 = nil
|
156
|
-
end
|
157
|
-
if r5
|
158
|
-
r0 = r5
|
159
|
-
else
|
160
|
-
@index = i0
|
161
|
-
r0 = nil
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
153
|
+
@index = i0
|
154
|
+
r0 = nil
|
165
155
|
end
|
166
156
|
end
|
167
157
|
|
168
|
-
node_cache[:
|
158
|
+
node_cache[:encoding][start_index] = r0
|
169
159
|
|
170
160
|
r0
|
171
161
|
end
|