mail-jdec 1.0.10 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe56489a85031c3cbc6d898b9c35a132bc3a01683d7f2682b582727bf2318706
4
- data.tar.gz: a7825201050257f08d640ad8a267bb66b31a87cef3068d6ea4936a741de27b17
3
+ metadata.gz: f4cba29f251d5a8fe9a696f6e965b9fd2b52c622f64aedb23f63567e3ebc15d0
4
+ data.tar.gz: ae6a610eee21b581f474fedf651a90e54bc9e5dde5d613daeebd621c0520da86
5
5
  SHA512:
6
- metadata.gz: 3029fcabe732faa31f6eabf0dce16fd3fbeda58ad8d9dba875bddf3263163ae91ac147c38d8c76fdbdc56850a86634e8446b8385463d3de80a298acc230724f6
7
- data.tar.gz: f8d774c612e83d0adc375f4ff81bcc57a50b9c399c4b849a6e0383704110a99d9905023de07092861441c2115ea63b48dc7576c4883feedcaa7983f3ea4e392b
6
+ metadata.gz: c5a8e19b16e943c41890c0652433f1607b15c08108440dbbe0fbe4ca6e3360f3aed4d43328e46aa4230b390bac46b9566db890b123f675444972054231af7514
7
+ data.tar.gz: 9cd358e45c80af8aab96e8d995d16720028ec657c224a0faeb07ba2eec12b39be15b76f2c778524f4a420b499c7649eea13e751eeefdf55deb53dbf083f1549b
@@ -8,8 +8,8 @@ jobs:
8
8
  strategy:
9
9
  fail-fast: false
10
10
  matrix:
11
- ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0', 3.1]
12
- gemfile: ['mail27']
11
+ ruby: [2.5, 2.6, 2.7, '3.0', 3.1, 3.2]
12
+ gemfile: ['mail28']
13
13
 
14
14
  name: ruby ${{ matrix.ruby }}, ${{ matrix.gemfile }}
15
15
 
@@ -17,7 +17,7 @@ jobs:
17
17
  BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
18
18
 
19
19
  steps:
20
- - uses: actions/checkout@v2
20
+ - uses: actions/checkout@v3
21
21
  - uses: ruby/setup-ruby@v1
22
22
  with:
23
23
  ruby-version: ${{ matrix.ruby }}
data/.gitignore CHANGED
@@ -1,6 +1,6 @@
1
1
  .bundle/
2
- .project
3
2
  Gemfile.lock
3
+ gemfiles/*.lock
4
4
  coverage/
5
5
  pkg/
6
6
  tmp/
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.1.1
4
+
5
+ * Support charset detection including message parts.
6
+
7
+ ## 1.1.0
8
+
9
+ * Change supported mail version to 2.8.
10
+ * Drop support for ruby 2.3 and 2.4.
11
+
3
12
  ## 1.0.10
4
13
 
5
14
  * Fix mail version to < 2.8.0.
data/README.md CHANGED
@@ -4,8 +4,8 @@ A mail patch for decoding some improper mails.
4
4
 
5
5
  ## Dependencies
6
6
 
7
- * ruby 2.3+
8
- * mail 2.7
7
+ * ruby 2.5+
8
+ * mail 2.8
9
9
  * charlock_holmes (using libicu)
10
10
 
11
11
  ## Installation
@@ -1,6 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem "mail", "~> 2.7.1"
4
- gem "net-smtp"
3
+ gem "mail", "~> 2.8.1"
5
4
 
6
5
  gemspec path: "../"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module BodyPatch
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  class Decoder
4
6
  class << self
5
7
  def decode_if_needed(text)
6
- return text if text.nil? || text.encoding == Encoding::UTF_8
8
+ return text if text.nil? || !text.respond_to?(:encoding) || text.encoding == Encoding::UTF_8
7
9
 
8
10
  detected = Detector.detect(text)
9
11
 
@@ -57,7 +59,7 @@ module Mail
57
59
  if content =~ ENCODED_VALUE
58
60
  bytes = content.scan(/\=\?([^?]+)\?([QB])\?([^?]*?)\?\=/mi).map do |_, encoding, encoded|
59
61
  case encoding
60
- when *B_VALUES then Mail::RubyVer.decode_base64(encoded)
62
+ when *B_VALUES then Mail::Utilities.decode_base64(encoded)
61
63
  when *Q_VALUES then Mail::Encodings::QuotedPrintable.decode(encoded.gsub(/_/, '=20').sub(/\=$/, ''))
62
64
  end
63
65
  end.join('')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  class Detector
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module ContentDispositionElementPatch
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module ContentTypeElementPatch
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module EncodingsPatch
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mail
4
+ module Jdec
5
+ module CommonAddressFieldPatch
6
+ def element
7
+ super
8
+ rescue Mail::Field::ParseError => e
9
+ if Jdec.enabled?
10
+ @errors = [name, value, e]
11
+ @element = AddressList.new('')
12
+ else
13
+ raise e
14
+ end
15
+ end
16
+
17
+ def errors
18
+ @errors
19
+ end
20
+
21
+ def address_list
22
+ element
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ klasses = ObjectSpace.each_object(Class).select { |klass| klass < Mail::CommonAddressField }
29
+ klasses.each do |klass|
30
+ unless klass.included_modules.include?(Mail::Jdec::CommonAddressFieldPatch)
31
+ klass.prepend Mail::Jdec::CommonAddressFieldPatch
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mail
4
+ module Jdec
5
+ module CommonDateFieldPatch
6
+ def element
7
+ super
8
+ rescue Mail::Field::ParseError => e
9
+ if Jdec.enabled?
10
+ @errors = [name, value, e]
11
+ @element = nil
12
+ else
13
+ raise e
14
+ end
15
+ end
16
+
17
+ def date_time
18
+ if Jdec.enabled?
19
+ if element
20
+ begin
21
+ ::DateTime.parse("#{element.date_string} #{element.time_string}")
22
+ rescue ArgumentError => e
23
+ require 'time'
24
+ begin
25
+ Time.parse(value).to_datetime
26
+ rescue ArgumentError => e
27
+ nil
28
+ end
29
+ end
30
+ else
31
+ nil
32
+ end
33
+ else
34
+ super
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ klasses = ObjectSpace.each_object(Class).select { |klass| klass < Mail::CommonDateField }
42
+ klasses.each do |klass|
43
+ unless klass.included_modules.include?(Mail::Jdec::CommonDateFieldPatch)
44
+ klass.prepend Mail::Jdec::CommonDateFieldPatch
45
+ end
46
+ end
@@ -1,31 +1,33 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- module Mail
3
+ require 'mail/constants'
4
+ require 'mail/indifferent_hash'
5
+ require 'mail/encodings'
4
6
 
7
+ module Mail
5
8
  # ParameterHash is an intelligent Hash that allows you to add
6
9
  # parameter values including the MIME extension paramaters that
7
10
  # have the name*0="blah", name*1="bleh" keys, and will just return
8
11
  # a single key called name="blahbleh" and do any required un-encoding
9
12
  # to make that happen
10
- # Parameters are defined in RFC2045, split keys are in RFC2231
11
-
12
- class ParameterHash < IndifferentHash
13
-
14
- include Mail::Utilities
15
-
13
+ #
14
+ # Parameters are defined in RFC2045. Split keys are in RFC2231.
15
+ class ParameterHash < IndifferentHash #:nodoc:
16
16
  def [](key_name)
17
17
  key_pattern = Regexp.escape(key_name.to_s)
18
18
  pairs = []
19
19
  exact = nil
20
+
20
21
  each do |k,v|
21
22
  if k =~ /^#{key_pattern}(\*|$)/i
22
- if $1 == ASTERISK
23
+ if $1 == Constants::ASTERISK
23
24
  pairs << [k, v]
24
25
  else
25
26
  exact = k
26
27
  end
27
28
  end
28
29
  end
30
+
29
31
  if pairs.empty? # Just dealing with a single value pair
30
32
  super(exact || key_name)
31
33
  else # Dealing with a multiple value pair or a single encoded value pair
@@ -46,13 +48,13 @@ module Mail
46
48
  value = Mail::Encodings.param_encode(value)
47
49
  key_name = "#{key_name}*"
48
50
  end
49
- %Q{#{key_name}=#{quote_token(value)}}
51
+ %Q{#{key_name}=#{Utilities.quote_token(value)}}
50
52
  end.join(";\r\n\s")
51
53
  end
52
54
 
53
55
  def decoded
54
56
  map.sort_by { |a| a.first.to_s =~ /^([^*]+)\*(\d+)/ ? [$1, $2.to_i] : [a.first.to_s, 0] }.map! do |key_name, value|
55
- %Q{#{key_name}=#{quote_token(value)}}
57
+ %Q{#{key_name}=#{Utilities.quote_token(value)}}
56
58
  end.join("; ")
57
59
  end
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module StructuredFieldPatch
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module UnstructuredFieldPatch
@@ -1,16 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
5
  module MessagePatch
4
6
  def decoded
5
7
  decoded = super
6
8
 
7
- if Jdec.enabled? && (!has_content_type? || (text? && !has_charset? && !attachment? && !multipart?))
9
+ if Jdec.enabled? && MessagePatch.autodetect?(self)
8
10
  detected = Detector.detect(decoded)
9
11
  if detected && detected[:type] == :text
10
12
  charset = detected[:encoding].downcase
11
13
  decoded = Mail::Encodings.transcode_charset(decoded.dup.force_encoding(charset), charset, 'utf-8')
12
- header[:content_type] = 'text/plain'
13
- header[:content_type].parameters[:charset] = charset
14
+ header[:content_type] = 'text/plain' unless has_content_type?
15
+ header[:content_type].parameters[:charset] = charset unless has_charset?
14
16
  else
15
17
  decoded = Mail::Encodings.transcode_charset(decoded, decoded.encoding, 'utf-8')
16
18
  end
@@ -18,6 +20,23 @@ module Mail
18
20
 
19
21
  decoded
20
22
  end
23
+
24
+ class << self
25
+ def autodetect?(message)
26
+ !message.has_content_type? ||
27
+ (mime_types_for_autodetect?(message.mime_type) && !message.has_charset? && !message.attachment? && !message.multipart?)
28
+ end
29
+
30
+ def mime_types_for_autodetect?(mime_type)
31
+ Jdec.mime_types_for_autodetect.any? do |type|
32
+ if type.is_a?(Regexp)
33
+ type.match?(mime_type)
34
+ else
35
+ type == mime_type
36
+ end
37
+ end
38
+ end
39
+ end
21
40
  end
22
41
  end
23
42
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
- module Ruby19Patch
5
+ module UtilitiesPatch
4
6
  def pick_encoding(charset)
5
7
  if Jdec.enabled?
6
8
  Jdec.preferred_charsets.each do |from, to|
@@ -33,6 +35,6 @@ module Mail
33
35
  end
34
36
  end
35
37
 
36
- unless Mail::Ruby19.singleton_class.included_modules.include?(Mail::Jdec::Ruby19Patch)
37
- Mail::Ruby19.singleton_class.prepend Mail::Jdec::Ruby19Patch
38
+ unless Mail::Utilities.singleton_class.included_modules.include?(Mail::Jdec::UtilitiesPatch)
39
+ Mail::Utilities.singleton_class.prepend Mail::Jdec::UtilitiesPatch
38
40
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mail
2
4
  module Jdec
3
- VERSION = '1.0.10'
5
+ VERSION = '1.1.1'
4
6
  end
5
7
  end
data/lib/mail/jdec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mail'
2
4
  require 'charlock_holmes'
3
5
 
@@ -11,6 +13,7 @@ module Mail
11
13
  attr_reader :enabled
12
14
  attr_accessor :autodetect_confidence
13
15
  attr_accessor :autodetect_skip_charsets
16
+ attr_accessor :mime_types_for_autodetect
14
17
  attr_accessor :preferred_charsets
15
18
 
16
19
  def enabled?
@@ -29,6 +32,7 @@ module Mail
29
32
  self.enable
30
33
  self.autodetect_confidence = 50
31
34
  self.autodetect_skip_charsets = %w()
35
+ self.mime_types_for_autodetect = [%r{^text/}, 'message/delivery-status', 'message/disposition-notification']
32
36
  self.preferred_charsets = {
33
37
  'iso-2022-jp' => 'cp50221',
34
38
  'iso-2022-jp-1' => 'cp50221',
data/mail-jdec.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_dependency "mail", ">= 2.7.1", "< 2.8.0"
20
+ spec.add_dependency "mail", ">= 2.8.1"
21
21
  spec.add_dependency "charlock_holmes", ">= 0.7.0"
22
22
 
23
23
  spec.add_development_dependency "rake"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail-jdec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshikazu Kaneta
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-08 00:00:00.000000000 Z
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mail
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.7.1
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: 2.8.0
19
+ version: 2.8.1
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 2.7.1
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: 2.8.0
26
+ version: 2.8.1
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: charlock_holmes
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -103,7 +97,7 @@ files:
103
97
  - Rakefile
104
98
  - bin/console
105
99
  - bin/setup
106
- - gemfiles/mail27.gemfile
100
+ - gemfiles/mail28.gemfile
107
101
  - lib/mail/jdec.rb
108
102
  - lib/mail/jdec/body_patch.rb
109
103
  - lib/mail/jdec/decoder.rb
@@ -111,14 +105,13 @@ files:
111
105
  - lib/mail/jdec/elements/content_disposition_element_patch.rb
112
106
  - lib/mail/jdec/elements/content_type_element_patch.rb
113
107
  - lib/mail/jdec/encodings_patch.rb
114
- - lib/mail/jdec/fields/address_field_patch.rb
115
- - lib/mail/jdec/fields/date_field_patch.rb
108
+ - lib/mail/jdec/fields/common_address_field_patch.rb
109
+ - lib/mail/jdec/fields/common_date_field_patch.rb
116
110
  - lib/mail/jdec/fields/parameter_hash_patch.rb
117
- - lib/mail/jdec/fields/references_field_patch.rb
118
111
  - lib/mail/jdec/fields/structured_field_patch.rb
119
112
  - lib/mail/jdec/fields/unstructured_field_patch.rb
120
113
  - lib/mail/jdec/message_patch.rb
121
- - lib/mail/jdec/ruby_1_9_patch.rb
114
+ - lib/mail/jdec/utilities_patch.rb
122
115
  - lib/mail/jdec/version.rb
123
116
  - mail-jdec.gemspec
124
117
  homepage: https://github.com/kanety/mail-jdec
@@ -139,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
132
  - !ruby/object:Gem::Version
140
133
  version: '0'
141
134
  requirements: []
142
- rubygems_version: 3.1.2
135
+ rubygems_version: 3.3.3
143
136
  signing_key:
144
137
  specification_version: 4
145
138
  summary: A mail patch for decoding some improper mails
@@ -1,27 +0,0 @@
1
- module Mail
2
- module Jdec
3
- module AddressFieldPatch
4
- def parse(val = value)
5
- super
6
- rescue Mail::Field::ParseError => e
7
- if Jdec.enabled?
8
- @errors = [name, val, e]
9
- @address_list = AddressList.new('')
10
- else
11
- raise e
12
- end
13
- end
14
-
15
- def errors
16
- @errors
17
- end
18
- end
19
- end
20
- end
21
-
22
- klasses = ObjectSpace.each_object(Class).select { |klass| klass < Mail::CommonAddress }
23
- klasses.each do |klass|
24
- unless klass.included_modules.include?(Mail::Jdec::AddressFieldPatch)
25
- klass.prepend Mail::Jdec::AddressFieldPatch
26
- end
27
- end
@@ -1,54 +0,0 @@
1
- module Mail
2
- module Jdec
3
- module DateFieldPatch
4
- def date_time
5
- super
6
- rescue ArgumentError, Mail::Field::ParseError => e
7
- if Jdec.enabled?
8
- begin
9
- require 'time'
10
- Time.parse(value).to_datetime
11
- rescue ArgumentError => e
12
- nil
13
- end
14
- else
15
- raise e
16
- end
17
- end
18
- end
19
- end
20
- end
21
-
22
- module Mail
23
- class DateField < StructuredField
24
- def initialize(value = nil, charset = nil)
25
- super(CAPITALIZED_FIELD, self.class.normalize_datetime(value), charset)
26
- end
27
-
28
- def self.normalize_datetime(string)
29
- if Utilities.blank?(string)
30
- datetime = ::DateTime.now
31
- else
32
- stripped = string.to_s.gsub(/\(.*?\)/, '').squeeze(' ')
33
- begin
34
- datetime = ::DateTime.parse(stripped)
35
- rescue ArgumentError => e
36
- raise unless 'invalid date' == e.message
37
- end
38
- end
39
-
40
- if datetime
41
- datetime.strftime('%a, %d %b %Y %H:%M:%S %z')
42
- else
43
- string
44
- end
45
- end
46
- end
47
- end
48
-
49
- klasses = ObjectSpace.each_object(Class).select { |klass| klass < Mail::CommonDate }
50
- klasses.each do |klass|
51
- unless klass.included_modules.include?(Mail::Jdec::DateFieldPatch)
52
- klass.prepend Mail::Jdec::DateFieldPatch
53
- end
54
- end
@@ -1,18 +0,0 @@
1
- module Mail
2
- module Jdec
3
- module ReferencesFieldPatch
4
- def initialize(value = nil, charset = 'utf-8')
5
- if Jdec.enabled?
6
- if value.is_a?(String)
7
- value = value.gsub(/>\s*,\s*</, ">\r\n <")
8
- end
9
- end
10
- super
11
- end
12
- end
13
- end
14
- end
15
-
16
- unless Mail::ReferencesField.included_modules.include?(Mail::Jdec::ReferencesFieldPatch)
17
- Mail::ReferencesField.prepend Mail::Jdec::ReferencesFieldPatch
18
- end