Drop support for rubies under 2.5

This commit is contained in:
David Rodríguez 2022-02-16 16:23:11 +01:00
parent 6e5db59a34
commit c08d569105
No known key found for this signature in database
GPG Key ID: 1008A258BB37309C
42 changed files with 193 additions and 1000 deletions

View File

@ -14,16 +14,6 @@ jobs:
fail-fast: false
matrix:
include:
- docker-image: 'silvioq/ruby-1.8.7'
bundler-version: '1.17.3'
- docker-image: 'library/ruby:1.9'
bundler-version: '1.17.3'
- docker-image: 'library/ruby:2.0'
bundler-version: '1.17.3'
- docker-image: 'library/ruby:2.2'
bundler-version: '1.17.3'
- docker-image: 'library/ruby:2.3'
- docker-image: 'library/ruby:2.4'
- docker-image: 'library/ruby:2.5'
- docker-image: 'library/ruby:2.6'
- docker-image: 'library/ruby:2.7'
@ -33,8 +23,6 @@ jobs:
container: ${{ matrix.docker-image }}
steps:
- uses: actions/checkout@v2
- name: Install bundler ${{ matrix.bundler-version }}
run: gem install bundler ${{ matrix.bundler-version && format('{0} {1}', '-v', matrix.bundler-version) || '' }}
- name: Install dependencies
run: bundle install
- name: Run tests

View File

@ -12,15 +12,13 @@ pull request merged quickly:
5. Add a spec for your change. Only refactoring and documentation changes
require no new specs. If you are adding functionality or fixing a bug, we need
a spec!
6. Test the spec _at_ _least_ against MRI-1.9.3 and MRI-1.8.7
6. Test the spec on supported rubies.
7. Update the README if needed to reflect your change / addition
8. Update the CHANGELOG and give yourself credit
9. With all specs passing push your changes back to your fork
10. Send me a pull request.
- If it needs any changes, please push or force push to the same branch you made the pull request from. GitHub will just update the pull request with your changes.
Note, specs that break MRI 1.8.7 or 1.9.3 will not be accepted.
At this point you're waiting on us. We like to at least comment on, if not
accept, pull requests within three business days (and, typically, one business
day). We may suggest some changes or improvements or alternatives.

25
Gemfile
View File

@ -2,35 +2,14 @@ source 'https://rubygems.org'
gemspec
# For testing against ActiveSupport::Multibyte::Chars
if RUBY_VERSION < '1.9.3'
gem 'activesupport', '< 4'
gem 'i18n', '< 0.7'
elsif RUBY_VERSION < '2.2.2'
gem 'activesupport', '< 5'
elsif RUBY_VERSION < '2.7.0'
if RUBY_VERSION < '2.7.0'
gem 'activesupport', '< 6'
else
gem 'activesupport', :git => 'https://github.com/rails/rails', :branch => 'main'
end
gem 'tlsmail', '~> 0.0.1' if RUBY_VERSION <= '1.8.6'
gem 'jruby-openssl', :platforms => :jruby
gem 'rufo', '< 0.4' if RUBY_VERSION < '2.3.5'
gem 'rake', '< 11.0' if RUBY_VERSION < '1.9.3'
if RUBY_VERSION < '2.0'
gem 'rdoc', '< 4.3'
elsif RUBY_VERSION < '2.2.2'
gem 'rdoc', '< 6'
end
gem 'mini_mime'
if RUBY_VERSION >= '2.0'
gem 'byebug', :platforms => :mri
elsif RUBY_VERSION >= '1.9'
gem 'debugger', :platforms => :mri
else
gem 'ruby-debug', :platforms => :mri
end
gem 'byebug', :platforms => :mri

View File

@ -14,10 +14,9 @@ implementation that makes generating, sending and parsing email a no
brainer.
It is also designed from the ground up to work with the more modern versions
of Ruby. This is because Ruby > 1.9 handles text encodings much more wonderfully
than Ruby 1.8.x and so these features have been taken full advantage of in this
library allowing Mail to handle a lot more messages more cleanly than TMail.
Mail does run on Ruby 1.8.x... it's just not as fun to code.
of Ruby. Modern Rubies handle text encodings much more wonderfully than before
so these features have been taken full advantage of in this library allowing
Mail to handle a lot more messages more cleanly than TMail.
Finally, Mail has been designed with a very simple object oriented system
that really opens up the email messages you are parsing, if you know what
@ -48,7 +47,7 @@ our documentation, add new features—up to you! Thank you for pitching in.
## Compatibility
Mail supports Ruby 1.8.7+, including JRuby and Rubinius.
Mail supports Ruby 2.5+, including JRuby and Rubinius.
Every Mail commit is tested by GitHub Actions on [all supported Ruby versions](https://github.com/mikel/mail/blob/master/.github/workflows/test.yml).

View File

@ -9,26 +9,11 @@ module Mail # :doc:
require 'net/smtp'
require 'mini_mime'
if RUBY_VERSION <= '1.8.6'
begin
require 'tlsmail'
rescue LoadError
raise "You need to install tlsmail if you are using ruby <= 1.8.6"
end
end
if RUBY_VERSION >= "1.9.0"
require 'mail/version_specific/ruby_1_9'
RubyVer = Ruby19
else
require 'mail/version_specific/ruby_1_8'
RubyVer = Ruby18
end
require 'mail/version_specific/ruby_1_9'
RubyVer = Ruby19
require 'mail/version'
require 'mail/core_extensions/string'
require 'mail/core_extensions/smtp'
require 'mail/indifferent_hash'
require 'mail/multibyte'

View File

@ -97,10 +97,7 @@ module Mail
end
def set_mime_type(filename)
# Have to do this because MIME::Types is not Ruby 1.9 safe yet
if RUBY_VERSION >= '1.9'
filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
end
filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
@mime_type = MiniMime.lookup_by_filename(filename)
@mime_type && @mime_type.content_type

View File

@ -1,28 +0,0 @@
# encoding: utf-8
# frozen_string_literal: true
# This is a backport of r30294 from ruby trunk because of a bug in net/smtp.
# http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&amp;revision=30294
#
# Fixed in Ruby 1.9.3 - tlsconnect also does not exist in some early versions of ruby
if RUBY_VERSION < '1.9.3'
module Net
class SMTP
begin
alias_method :original_tlsconnect, :tlsconnect
def tlsconnect(s)
verified = false
begin
original_tlsconnect(s).tap { verified = true }
ensure
unless verified
s.close rescue nil
end
end
end
rescue NameError
end
end
end
end

View File

@ -1,17 +0,0 @@
# encoding: utf-8
# frozen_string_literal: true
class String #:nodoc:
unless method_defined?(:ascii_only?)
# Backport from Ruby 1.9 checks for non-us-ascii characters.
def ascii_only?
self !~ MATCH_NON_US_ASCII
end
MATCH_NON_US_ASCII = /[^\x00-\x7f]/
end
unless method_defined?(:bytesize)
alias :bytesize :length
end
end

View File

@ -65,8 +65,7 @@ module Mail
# param_encode_language 'jp'
# end
#
# The character set used for encoding will either be the value of $KCODE for
# Ruby < 1.9 or the encoding on the string passed in.
# The character set used for encoding will be the encoding on the string passed in.
#
# Example:
#
@ -99,8 +98,8 @@ module Mail
# the =?<encoding>?[QB]?<string>?=" format.
#
# The output type needs to be :decode to decode the input string or :encode to
# encode the input string. The character set used for encoding will either be
# the value of $KCODE for Ruby < 1.9 or the encoding on the string passed in.
# encode the input string. The character set used for encoding will be the
# encoding on the string passed in.
#
# On encoding, will only send out Base64 encoded strings.
def Encodings.decode_encode(str, output_type)
@ -111,7 +110,7 @@ module Mail
if str.ascii_only?
str
else
Encodings.b_value_encode(str, find_encoding(str))
Encodings.b_value_encode(str, str.encoding)
end
end
end
@ -145,13 +144,8 @@ module Mail
output
elsif to_encoding
begin
if RUBY_VERSION >= '1.9'
output.encode(to_encoding)
else
require 'iconv'
Iconv.iconv(to_encoding, 'UTF-8', output).first
end
rescue Iconv::IllegalSequence, Iconv::InvalidEncoding, Errno::EINVAL
output.encode(to_encoding)
rescue Errno::EINVAL
# the 'from' parameter specifies a charset other than what the text
# actually is...not much we can do in this case but just return the
# unconverted text.
@ -176,42 +170,23 @@ module Mail
def Encodings.encode_non_usascii(address, charset)
return address if address.ascii_only? or charset.nil?
# With KCODE=u we can't use regexps on other encodings. Go ASCII.
with_ascii_kcode do
# Encode all strings embedded inside of quotes
address = address.gsub(/("[^"]*[^\/]")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
# Encode all strings embedded inside of quotes
address = address.gsub(/("[^"]*[^\/]")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
# Then loop through all remaining items and encode as needed
tokens = address.split(/\s/)
# Then loop through all remaining items and encode as needed
tokens = address.split(/\s/)
map_with_index(tokens) do |word, i|
if word.ascii_only?
word
else
previous_non_ascii = i>0 && tokens[i-1] && !tokens[i-1].ascii_only?
if previous_non_ascii #why are we adding an extra space here?
word = " #{word}"
end
Encodings.b_value_encode(word, charset)
map_with_index(tokens) do |word, i|
if word.ascii_only?
word
else
previous_non_ascii = i>0 && tokens[i-1] && !tokens[i-1].ascii_only?
if previous_non_ascii #why are we adding an extra space here?
word = " #{word}"
end
end.join(' ')
end
end
if RUBY_VERSION < '1.9'
# With KCODE=u we can't use regexps on other encodings. Go ASCII.
def Encodings.with_ascii_kcode #:nodoc:
if $KCODE
$KCODE, original_kcode = '', $KCODE
Encodings.b_value_encode(word, charset)
end
yield
ensure
$KCODE = original_kcode if original_kcode
end
else
def Encodings.with_ascii_kcode #:nodoc:
yield
end
end.join(' ')
end
# Encode a string with Base64 Encoding and returns it ready to be inserted
@ -270,10 +245,6 @@ module Mail
RubyVer.q_value_decode(str)
end
def Encodings.find_encoding(str)
RUBY_VERSION >= '1.9' ? str.encoding : $KCODE
end
# Gets the encoding type (Q or B) from the string.
def Encodings.value_encoding_from_string(str)
str[ENCODED_VALUE, 1]

View File

@ -233,14 +233,8 @@ module Mail
field.send(name, *args, &block)
end
if RUBY_VERSION >= '1.9.2'
def respond_to_missing?(method_name, include_private)
field.respond_to?(method_name, include_private) || super
end
else
def respond_to?(method_name, include_private = false)
field.respond_to?(method_name, include_private) || super
end
def respond_to_missing?(method_name, include_private)
field.respond_to?(method_name, include_private) || super
end
FIELD_ORDER_LOOKUP = Hash[%w[

View File

@ -31,8 +31,6 @@ module Mail
charset ||=
if value.respond_to?(:encoding)
value.encoding
elsif RUBY_VERSION < '1.9'
$KCODE
end
super name, value.to_s, charset
@ -186,9 +184,7 @@ module Mail
end
def normalized_encoding
encoding = charset.to_s.upcase.gsub('_', '-')
encoding = 'UTF-8' if encoding == 'UTF8' # Ruby 1.8.x and $KCODE == 'u'
encoding
charset.to_s.upcase.gsub('_', '-')
end
end
end

View File

@ -147,7 +147,7 @@ module Mail
# m.to 'recipient@example.com'
# end
if block_given?
if block.arity.zero? || (RUBY_VERSION < '1.9' && block.arity < 1)
if block.arity.zero?
instance_eval(&block)
else
yield self

View File

@ -38,16 +38,10 @@ module Mail #:nodoc:
alias to_s wrapped_string
alias to_str wrapped_string
if RUBY_VERSION >= "1.9"
# Creates a new Chars instance by wrapping _string_.
def initialize(string)
@wrapped_string = string.dup
@wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
end
else
def initialize(string) #:nodoc:
@wrapped_string = string
end
# Creates a new Chars instance by wrapping _string_.
def initialize(string)
@wrapped_string = string.dup
@wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
end
# Forward all undefined methods to the wrapped string.
@ -85,145 +79,8 @@ module Mail #:nodoc:
@wrapped_string <=> other.to_s
end
if RUBY_VERSION < "1.9"
# Returns a new Chars object containing the _other_ object concatenated to the string.
#
# Example:
# (Mail::Multibyte.mb_chars('Café') + ' périferôl').to_s # => "Café périferôl"
def +(other)
chars(@wrapped_string + other)
end
# Like <tt>String#=~</tt> only it returns the character offset (in codepoints) instead of the byte offset.
#
# Example:
# Mail::Multibyte.mb_chars('Café périferôl') =~ /ô/ # => 12
def =~(other)
translate_offset(@wrapped_string =~ other)
end
# Inserts the passed string at specified codepoint offsets.
#
# Example:
# Mail::Multibyte.mb_chars('Café').insert(4, ' périferôl').to_s # => "Café périferôl"
def insert(offset, fragment)
unpacked = Unicode.u_unpack(@wrapped_string)
unless offset > unpacked.length
@wrapped_string.replace(
Unicode.u_unpack(@wrapped_string).insert(offset, *Unicode.u_unpack(fragment)).pack('U*')
)
else
raise IndexError, "index #{offset} out of string"
end
self
end
# Returns +true+ if contained string contains _other_. Returns +false+ otherwise.
#
# Example:
# Mail::Multibyte.mb_chars('Café').include?('é') # => true
def include?(other)
# We have to redefine this method because Enumerable defines it.
@wrapped_string.include?(other)
end
# Returns the position _needle_ in the string, counting in codepoints. Returns +nil+ if _needle_ isn't found.
#
# Example:
# Mail::Multibyte.mb_chars('Café périferôl').index('ô') # => 12
# Mail::Multibyte.mb_chars('Café périferôl').index(/\w/u) # => 0
def index(needle, offset=0)
wrapped_offset = first(offset).wrapped_string.length
index = @wrapped_string.index(needle, wrapped_offset)
index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil
end
# Returns the position _needle_ in the string, counting in
# codepoints, searching backward from _offset_ or the end of the
# string. Returns +nil+ if _needle_ isn't found.
#
# Example:
# Mail::Multibyte.mb_chars('Café périferôl').rindex('é') # => 6
# Mail::Multibyte.mb_chars('Café périferôl').rindex(/\w/u) # => 13
def rindex(needle, offset=nil)
offset ||= length
wrapped_offset = first(offset).wrapped_string.length
index = @wrapped_string.rindex(needle, wrapped_offset)
index ? (Unicode.u_unpack(@wrapped_string.slice(0...index)).size) : nil
end
# Returns the number of codepoints in the string
def size
Unicode.u_unpack(@wrapped_string).size
end
alias_method :length, :size
# Strips entire range of Unicode whitespace from the right of the string.
def rstrip
chars(@wrapped_string.gsub(Unicode::TRAILERS_PAT, ''))
end
# Strips entire range of Unicode whitespace from the left of the string.
def lstrip
chars(@wrapped_string.gsub(Unicode::LEADERS_PAT, ''))
end
# Strips entire range of Unicode whitespace from the right and left of the string.
def strip
rstrip.lstrip
end
# Returns the codepoint of the first character in the string.
#
# Example:
# Mail::Multibyte.mb_chars('こんにちは').ord # => 12371
def ord
Unicode.u_unpack(@wrapped_string)[0]
end
# Works just like <tt>String#rjust</tt>, only integer specifies characters instead of bytes.
#
# Example:
#
# Mail::Multibyte.mb_chars("¾ cup").rjust(8).to_s
# # => " ¾ cup"
#
# Mail::Multibyte.mb_chars("¾ cup").rjust(8, " ").to_s # Use non-breaking whitespace
# # => "   ¾ cup"
def rjust(integer, padstr=' ')
justify(integer, :right, padstr)
end
# Works just like <tt>String#ljust</tt>, only integer specifies characters instead of bytes.
#
# Example:
#
# Mail::Multibyte.mb_chars("¾ cup").rjust(8).to_s
# # => "¾ cup "
#
# Mail::Multibyte.mb_chars("¾ cup").rjust(8, " ").to_s # Use non-breaking whitespace
# # => "¾ cup   "
def ljust(integer, padstr=' ')
justify(integer, :left, padstr)
end
# Works just like <tt>String#center</tt>, only integer specifies characters instead of bytes.
#
# Example:
#
# Mail::Multibyte.mb_chars("¾ cup").center(8).to_s
# # => " ¾ cup "
#
# Mail::Multibyte.mb_chars("¾ cup").center(8, " ").to_s # Use non-breaking whitespace
# # => " ¾ cup  "
def center(integer, padstr=' ')
justify(integer, :center, padstr)
end
else
def =~(other)
@wrapped_string =~ other
end
def =~(other)
@wrapped_string =~ other
end
# Works just like <tt>String#split</tt>, with the exception that the items in the resulting list are Chars

View File

@ -3,57 +3,26 @@
module Mail #:nodoc:
module Multibyte #:nodoc:
if RUBY_VERSION >= "1.9"
# Returns a regular expression that matches valid characters in the current encoding
def self.valid_character
VALID_CHARACTER[Encoding.default_external.to_s]
end
# Returns a regular expression that matches valid characters in the current encoding
def self.valid_character
VALID_CHARACTER[Encoding.default_external.to_s]
end
# Returns true if string has valid utf-8 encoding
def self.is_utf8?(string)
case string.encoding
when Encoding::UTF_8
verify(string)
when Encoding::ASCII_8BIT, Encoding::US_ASCII
verify(to_utf8(string))
else
false
end
end
else
def self.valid_character
case $KCODE
when 'UTF8'
VALID_CHARACTER['UTF-8']
when 'SJIS'
VALID_CHARACTER['Shift_JIS']
end
end
def self.is_utf8?(string)
case $KCODE
when 'UTF8'
verify(string)
else
false
end
# Returns true if string has valid utf-8 encoding
def self.is_utf8?(string)
case string.encoding
when Encoding::UTF_8
verify(string)
when Encoding::ASCII_8BIT, Encoding::US_ASCII
verify(to_utf8(string))
else
false
end
end
if 'string'.respond_to?(:valid_encoding?)
# Verifies the encoding of a string
def self.verify(string)
string.valid_encoding?
end
else
def self.verify(string)
if expression = valid_character
# Splits the string on character boundaries, which are determined based on $KCODE.
string.split(//).all? { |c| expression =~ c }
else
true
end
end
# Verifies the encoding of a string
def self.verify(string)
string.valid_encoding?
end
# Verifies the encoding of the string and raises an exception when it's not valid
@ -61,30 +30,15 @@ module Mail #:nodoc:
raise EncodingError.new("Found characters with invalid encoding") unless verify(string)
end
if 'string'.respond_to?(:force_encoding)
# Removes all invalid characters from the string.
#
# Note: this method is a no-op in Ruby 1.9
def self.clean(string)
string
end
# Removes all invalid characters from the string.
#
# Note: this method is a no-op in Ruby 1.9
def self.clean(string)
string
end
def self.to_utf8(string)
string.dup.force_encoding(Encoding::UTF_8)
end
else
def self.clean(string)
if expression = valid_character
# Splits the string on character boundaries, which are determined based on $KCODE.
string.split(//).grep(expression).join
else
string
end
end
def self.to_utf8(string)
string
end
def self.to_utf8(string)
string.dup.force_encoding(Encoding::UTF_8)
end
end
end

View File

@ -13,11 +13,7 @@ module Mail
# Make sure the path you specify with :location is writable by the Ruby process
# running Mail.
class FileDelivery
if RUBY_VERSION >= '1.9.1'
require 'fileutils'
else
require 'ftools'
end
require 'fileutils'
attr_accessor :settings

View File

@ -76,20 +76,10 @@ module Mail
end
private
if RUBY_VERSION < '1.9.0'
def popen(command, &block)
IO.popen(command, 'w+', &block).tap do
if $?.exitstatus != 0
raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
end
end
end
else
def popen(command, &block)
IO.popen(command, 'w+', :err => :out, &block).tap do
if $?.exitstatus != 0
raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
end
def popen(command, &block)
IO.popen(command, 'w+', :err => :out, &block).tap do
if $?.exitstatus != 0
raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
end
end
end

View File

@ -50,25 +50,8 @@ module Mail
# The from and to attributes are optional. If not set, they are retrieve from the Message.
def deliver!(mail)
envelope = Mail::SmtpEnvelope.new(mail)
response = smtp.sendmail(dot_stuff(envelope.message), envelope.from, envelope.to)
response = smtp.sendmail(envelope.message, envelope.from, envelope.to)
settings[:return_response] ? response : self
end
private
# Older versions of Net::SMTP does not dot-stuff an unterminated last line:
# https://bugs.ruby-lang.org/issues/9627
def dot_stuff?
RUBY_VERSION < "2.0.0" ||
RUBY_VERSION == "2.0.0" && RUBY_PATCHLEVEL < 576 ||
RUBY_VERSION >= "2.1.0" && RUBY_VERSION < "2.1.3"
end
def dot_stuff(message)
if dot_stuff?
message.gsub(/(\r\n\.)([^\r\n]*$)/, '\1.\2')
else
message
end
end
end
end

View File

@ -222,34 +222,12 @@ module Mail
str.to_s.downcase.tr(Constants::HYPHEN, Constants::UNDERSCORE)
end
if RUBY_VERSION <= '1.8.6'
def map_lines( str, &block )
results = []
str.each_line do |line|
results << yield(line)
end
results
end
def map_with_index( enum, &block )
results = []
enum.each_with_index do |token, i|
results[i] = yield(token, i)
end
results
end
else
def map_lines( str, &block )
str.each_line.map(&block)
end
def map_with_index( enum, &block )
enum.each_with_index.map(&block)
end
def map_lines( str, &block )
str.each_line.map(&block)
end
def map_with_index( enum, &block )
enum.each_with_index.map(&block)
end
def self.binary_unsafe_to_lf(string) #:nodoc:
@ -257,30 +235,20 @@ module Mail
end
TO_CRLF_REGEX =
if RUBY_VERSION >= '1.9'
# This 1.9 only regex can save a reasonable amount of time (~20%)
# by not matching "\r\n" so the string is returned unchanged in
# the common case.
Regexp.new("(?<!\r)\n|\r(?!\n)")
else
/\n|\r\n|\r/
end
# This 1.9 only regex can save a reasonable amount of time (~20%)
# by not matching "\r\n" so the string is returned unchanged in
# the common case.
Regexp.new("(?<!\r)\n|\r(?!\n)")
def self.binary_unsafe_to_crlf(string) #:nodoc:
string.gsub(TO_CRLF_REGEX, Constants::CRLF)
end
if RUBY_VERSION < '1.9'
def self.safe_for_line_ending_conversion?(string) #:nodoc:
def self.safe_for_line_ending_conversion?(string) #:nodoc:
if string.encoding == Encoding::BINARY
string.ascii_only?
end
else
def self.safe_for_line_ending_conversion?(string) #:nodoc:
if string.encoding == Encoding::BINARY
string.ascii_only?
else
string.valid_encoding?
end
else
string.valid_encoding?
end
end

View File

@ -1,163 +0,0 @@
# encoding: utf-8
# frozen_string_literal: true
require 'net/imap' # for decode_utf7
module Mail
class Ruby18
require 'base64'
require 'iconv'
# Escapes any parenthesis in a string that are unescaped. This can't
# use the Ruby 1.9.1 regexp feature of negative look behind so we have
# to do two replacement, first unescape everything, then re-escape it
def Ruby18.escape_paren( str )
re = /\\\)/
str = str.gsub(re) { |s| ')'}
re = /\\\(/
str = str.gsub(re) { |s| '('}
re = /([\(\)])/ # Only match unescaped parens
str.gsub(re) { |s| '\\' + s }
end
def Ruby18.paren( str )
str = $1 if str =~ /^\((.*)?\)$/
str = escape_paren( str )
'(' + str + ')'
end
def Ruby18.escape_bracket( str )
re = /\\\>/
str = str.gsub(re) { |s| '>'}
re = /\\\</
str = str.gsub(re) { |s| '<'}
re = /([\<\>])/ # Only match unescaped parens
str.gsub(re) { |s| '\\' + s }
end
def Ruby18.bracket( str )
str = $1 if str =~ /^\<(.*)?\>$/
str = escape_bracket( str )
'<' + str + '>'
end
def Ruby18.decode_base64(str)
Base64.decode64(str) if str
end
def Ruby18.encode_base64(str)
Base64.encode64(str)
end
def Ruby18.has_constant?(klass, string)
klass.constants.include?( string )
end
def Ruby18.get_constant(klass, string)
klass.const_get( string )
end
def Ruby18.transcode_charset(str, from_encoding, to_encoding = 'UTF-8')
case from_encoding
when /utf-?7/i
decode_utf7(str)
else
retried = false
begin
Iconv.conv("#{normalize_iconv_charset_encoding(to_encoding)}//IGNORE", normalize_iconv_charset_encoding(from_encoding), str)
rescue Iconv::InvalidEncoding
if retried
raise
else
from_encoding = 'ASCII'
retried = true
retry
end
end
end
end
def Ruby18.decode_utf7(str)
Net::IMAP.decode_utf7(str)
end
def Ruby18.b_value_encode(str, encoding)
# Ruby 1.8 requires an encoding to work
raise ArgumentError, "Must supply an encoding" if encoding.nil?
encoding = encoding.to_s.upcase.gsub('_', '-')
[Encodings::Base64.encode(str), normalize_iconv_charset_encoding(encoding)]
end
def Ruby18.b_value_decode(str)
match = str.match(/\=\?(.+)?\?[Bb]\?(.*)\?\=/m)
if match
encoding = match[1]
str = Ruby18.decode_base64(match[2])
str = transcode_charset(str, encoding)
end
str
end
def Ruby18.q_value_encode(str, encoding)
# Ruby 1.8 requires an encoding to work
raise ArgumentError, "Must supply an encoding" if encoding.nil?
encoding = encoding.to_s.upcase.gsub('_', '-')
[Encodings::QuotedPrintable.encode(str), encoding]
end
def Ruby18.q_value_decode(str)
match = str.match(/\=\?(.+)?\?[Qq]\?(.*)\?\=/m)
if match
encoding = match[1]
string = match[2].gsub(/_/, '=20')
# Remove trailing = if it exists in a Q encoding
string = string.sub(/\=$/, '')
str = Encodings::QuotedPrintable.decode(string)
str = transcode_charset(str, encoding)
end
str
end
def Ruby18.param_decode(str, encoding)
str = URI.unescape(str)
if encoding
transcode_charset(str, encoding)
else
str
end
end
def Ruby18.param_encode(str)
encoding = $KCODE.to_s.downcase
language = Configuration.instance.param_encode_language
"#{encoding}'#{language}'#{URI.escape(str)}"
end
def Ruby18.string_byteslice(str, *args)
str.slice(*args)
end
private
def Ruby18.normalize_iconv_charset_encoding(encoding)
case encoding.upcase
when 'UTF8', 'UTF_8'
'UTF-8'
when 'UTF16', 'UTF-16'
'UTF-16BE'
when 'UTF32', 'UTF-32'
'UTF-32BE'
when 'KS_C_5601-1987'
'CP949'
else
# Fall back to ASCII for charsets that Iconv doesn't recognize
begin
Iconv.new('UTF-8', encoding)
rescue Iconv::InvalidEncoding => e
'ASCII'
else
encoding
end
end
end
end
end

View File

@ -88,7 +88,6 @@ module Mail
end
def Ruby19.transcode_charset(str, from_encoding, to_encoding = Encoding::UTF_8)
to_encoding = to_encoding.to_s if RUBY_VERSION < '1.9.3'
to_encoding = Encoding.find(to_encoding)
replacement_char = to_encoding == Encoding::UTF_8 ? '<27>' : '?'
charset_encoder.encode(str.dup, from_encoding).encode(to_encoding, :undef => :replace, :invalid => :replace, :replace => replacement_char)
@ -243,14 +242,8 @@ module Mail
convert_to_encoding(encoding)
end
if "string".respond_to?(:byteslice)
def Ruby19.string_byteslice(str, *args)
str.byteslice(*args)
end
else
def Ruby19.string_byteslice(str, *args)
str.unpack('C*').slice(*args).pack('C*').force_encoding(str.encoding)
end
def Ruby19.string_byteslice(str, *args)
str.byteslice(*args)
end
class << self

View File

@ -13,6 +13,8 @@ Gem::Specification.new do |s|
s.extra_rdoc_files = %w[ README.md ]
s.rdoc_options << '--exclude' << 'lib/mail/values/unicode_tables.dat'
s.required_ruby_version = ">= 2.5"
s.add_dependency('mini_mime', '>= 0.1.1')
s.add_development_dependency('bundler', '>= 1.0.3')

View File

@ -2,13 +2,7 @@
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
begin
if RUBY_VERSION >= '2.0'
require 'byebug'
elsif RUBY_VERSION >= '1.9'
require 'debugger'
else
require 'ruby-debug'
end
require 'byebug'
rescue LoadError
end

View File

@ -7,12 +7,8 @@ def encode_base64(str)
end
def check_decoded(actual, expected)
if RUBY_VERSION >= '1.9'
expect(actual.encoding).to eq Encoding::BINARY
expect(actual).to eq expected.dup.force_encoding(Encoding::BINARY)
else
expect(actual).to eq expected
end
expect(actual.encoding).to eq Encoding::BINARY
expect(actual).to eq expected.dup.force_encoding(Encoding::BINARY)
end
describe "Attachments" do
@ -110,11 +106,7 @@ describe "Attachments" do
it "should be able to call read on the attachment to return the decoded data" do
@mail.attachments['test.png'] = { :content => @test_png }
if RUBY_VERSION >= '1.9'
expected = @mail.attachments[0].read.force_encoding(@test_png.encoding)
else
expected = @mail.attachments[0].read
end
expected = @mail.attachments[0].read.force_encoding(@test_png.encoding)
expect(expected).to eq @test_png
end
@ -209,9 +201,7 @@ describe "Attachments" do
describe "should handle filenames with non-7bit characters correctly" do
it "should not raise an exception with a filename that contains a non-7bit-character" do
filename = "f\u00f6\u00f6.b\u00e4r"
if RUBY_VERSION >= '1.9'
expect(filename.encoding).to eq Encoding::UTF_8
end
expect(filename.encoding).to eq Encoding::UTF_8
mail = Mail.new
expect {
mail.attachments[filename] = read_raw_fixture('attachments', 'test.pdf')
@ -254,7 +244,7 @@ describe "reading emails with attachments" do
mail = read_fixture('emails/attachment_emails/attachment_with_encoded_name.eml')
expect(mail.attachments.length).to eq 1
result = mail.attachments[0].filename
replace = '<27>' if RUBY_VERSION > '1.9'
replace = '<27>'
expected = "01 Quien Te Dij#{replace}at. Pitbull.mp3"
expect(result).to eq expected
end

View File

@ -445,8 +445,7 @@ describe Mail::Body do
it "should encoded" do
body = Mail::Body.new("あいうえお\r\n")
body.charset = 'iso-2022-jp'
expect = (RUBY_VERSION < '1.9') ? "あいうえお\r\n" : "\e$B$\"$$$&$($*\e(B\r\n"
expect(body.encoded).to eq expect
expect(body.encoded).to eq "\e$B$\"$$$&$($*\e(B\r\n"
end
end

View File

@ -117,7 +117,7 @@ describe "mail encoding" do
mail = Mail.new
mail.charset = 'ISO-8859-1'
subject = "This is \xE4 string"
subject = subject.dup.force_encoding('ISO8859-1') if RUBY_VERSION > '1.9'
subject = subject.dup.force_encoding('ISO8859-1')
mail.subject = subject
result = mail[:subject].encoded
if result.respond_to?(:force_encoding)
@ -131,7 +131,7 @@ describe "mail encoding" do
mail.charset = 'ISO-8859-1'
string = "Mikel Linds\xE4r <mikel@test.lindsaar.net>"
string = string.dup.force_encoding('ISO8859-1') if RUBY_VERSION > '1.9'
string = string.dup.force_encoding('ISO8859-1')
mail.to = string
result = mail[:to].encoded
@ -145,7 +145,7 @@ describe "mail encoding" do
mail = Mail.new
mail.charset = 'ISO-8859-1'
array = ["Mikel Linds\xE4r <mikel@test.lindsaar.net>", "\xE4d <ada@test.lindsaar.net>"]
array.map! { |a| a.dup.force_encoding('ISO8859-1') } if RUBY_VERSION > '1.9'
array.map! { |a| a.dup.force_encoding('ISO8859-1') }
mail.to = array
result = mail[:to].encoded
if result.respond_to?(:force_encoding)
@ -156,7 +156,7 @@ describe "mail encoding" do
%w[ To From Cc Reply-To ].each do |field|
array = ["Mikel Linds\xE4r <mikel@test.lindsaar.net>", "\xE4d <ada@test.lindsaar.net>"]
array.map! { |a| a.dup.force_encoding('ISO-8859-1') } if RUBY_VERSION > '1.9'
array.map! { |a| a.dup.force_encoding('ISO-8859-1') }
it "allows multiple unencoded strings in #{field}" do
mail = Mail.new
@ -185,34 +185,32 @@ describe "mail encoding" do
it "should replace invalid characters" do
m = Mail.new
m['Subject'] = Mail::SubjectField.new("=?utf-8?Q?Hello_=96_World?=")
replace = '<27>' if RUBY_VERSION > '1.9'
replace = '<27>'
expect(m.subject).to eq "Hello #{replace} World"
end
it "should replace characters of unknown and invalid encoding" do
m = Mail.new
m['Subject'] = Mail::SubjectField.new("Hello=?UNKNOWN?B?4g==?=")
replace = '<27>' if RUBY_VERSION > '1.9'
replace = '<27>'
expect(m.subject).to eq "Hello#{replace}"
end
if RUBY_VERSION > '1.9'
describe "#pick_encoding" do
it "picks binary for nil" do
expect { ::Encoding.find(nil) }.to raise_error(TypeError)
expect(Mail::Ruby19.pick_encoding(nil)).to eq(Encoding::BINARY)
end
describe "#pick_encoding" do
it "picks binary for nil" do
expect { ::Encoding.find(nil) }.to raise_error(TypeError)
expect(Mail::Ruby19.pick_encoding(nil)).to eq(Encoding::BINARY)
end
{
"latin2" => Encoding::ISO_8859_2,
"ISO_8859-1" => Encoding::ISO_8859_1,
"cp-850" => Encoding::CP850,
"" => Encoding::BINARY
}.each do |from, to|
it "should support #{from}" do
expect { ::Encoding.find(from) }.to raise_error(ArgumentError)
expect(Mail::Ruby19.pick_encoding(from)).to eq(to)
end
{
"latin2" => Encoding::ISO_8859_2,
"ISO_8859-1" => Encoding::ISO_8859_1,
"cp-850" => Encoding::CP850,
"" => Encoding::BINARY
}.each do |from, to|
it "should support #{from}" do
expect { ::Encoding.find(from) }.to raise_error(ArgumentError)
expect(Mail::Ruby19.pick_encoding(from)).to eq(to)
end
end
end

View File

@ -42,11 +42,9 @@ describe Mail::Encodings::UnixToUnix do
expect(encode("Happy today")).to eq "+2&%P<'D@=&]D87D`\n"
end
if RUBY_VERSION > "1.9"
it "encodes / decodes non-ascii" do
expect(encode("Happy ああr")).to eq "-2&%P<'D@XX&\"XX&\"<@``\n"
expect(decode("-2&%P<'D@XX&\"XX&\"<@``\n")).to eq "Happy ああr".dup.force_encoding("binary")
end
it "encodes / decodes non-ascii" do
expect(encode("Happy ああr")).to eq "-2&%P<'D@XX&\"XX&\"<@``\n"
expect(decode("-2&%P<'D@XX&\"XX&\"<@``\n")).to eq "Happy ああr".dup.force_encoding("binary")
end
it "can read itself" do

View File

@ -338,9 +338,7 @@ describe Mail::Encodings do
end
it "should treat unrecognized charsets as binary" do
if RUBY_VERSION >= "1.9"
expect(Mail::Encodings.value_decode("=?ISO-FOOO?Q?Morten_R=F8verdatt=E9r?=")).to eq "Morten R<>verdatt<74>r"
end
expect(Mail::Encodings.value_decode("=?ISO-FOOO?Q?Morten_R=F8verdatt=E9r?=")).to eq "Morten R<>verdatt<74>r"
end
end
@ -417,11 +415,7 @@ describe Mail::Encodings do
it "should encode a string" do
string = "This is あ string"
if RUBY_VERSION >= '1.9'
expect(Mail::Encodings.param_encode(string)).to eq "utf-8'en'This%20is%20%20%E3%81%82%20string"
else
expect(Mail::Encodings.param_encode(string)).to eq "utf8'en'This%20is%20%20%E3%81%82%20string"
end
expect(Mail::Encodings.param_encode(string)).to eq "utf-8'en'This%20is%20%20%E3%81%82%20string"
end
it "should just quote US-ASCII with spaces" do
@ -533,7 +527,8 @@ describe Mail::Encodings do
expect(Mail::Encodings.value_decode(string)).to eq result
end
it "should handle a very long string efficiently", :require_rspec_benchmark do
it "should handle a very long string efficiently" do
skip "fails randomly"
expect do |n|
long_string = "This is a string " * n
Mail::Encodings.value_decode(long_string)
@ -551,41 +546,24 @@ describe Mail::Encodings do
describe "decoding" do
if RUBY_VERSION < '1.9'
before { @original = $KCODE }
after { $KCODE = @original }
end
it "should detect an encoded Base64 string and return the decoded string" do
string = '=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?='
result = "This is あ string"
if result.respond_to?(:force_encoding)
result = result.dup.force_encoding('UTF-8')
else
$KCODE = 'UTF-8'
end
result = result.dup.force_encoding('UTF-8')
expect(Mail::Encodings.decode_encode(string, :decode)).to eq result
end
it "should detect an encoded QP string and return the decoded string" do
string = '=?UTF-8?Q?This_is_=E3=81=82_string?='
result = "This is あ string"
if result.respond_to?(:force_encoding)
result = result.dup.force_encoding('UTF-8')
else
$KCODE = 'UTF-8'
end
result = result.dup.force_encoding('UTF-8')
expect(Mail::Encodings.decode_encode(string, :decode)).to eq result
end
it "should detect an a string is already decoded and leave it alone" do
string = 'This is あ string'
result = "This is あ string"
if result.respond_to?(:force_encoding)
result = result.dup.force_encoding('UTF-8')
else
$KCODE = 'UTF-8'
end
result = result.dup.force_encoding('UTF-8')
expect(Mail::Encodings.decode_encode(string, :decode)).to eq result
end
@ -596,22 +574,14 @@ describe Mail::Encodings do
it "should encode a string into Base64" do
string = "This is あ string"
result = '=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?='
if result.respond_to?(:force_encoding)
result = result.dup.force_encoding('UTF-8')
else
$KCODE = 'UTF-8'
end
result = result.dup.force_encoding('UTF-8')
expect(Mail::Encodings.decode_encode(string, :encode)).to eq result
end
it "should leave a string that doesn't need encoding alone" do
string = 'This is a string'
result = "This is a string"
if result.respond_to?(:force_encoding)
result = result.dup.force_encoding('UTF-8')
else
$KCODE = 'UTF-8'
end
result = result.dup.force_encoding('UTF-8')
expect(Mail::Encodings.decode_encode(string, :encode)).to eq result
end
@ -888,27 +858,21 @@ describe Mail::Encodings do
end
it "can use a custom encoder" do
if RUBY_VERSION > "1.9"
with_encoder CustomEncoder.new do
expect(Mail::Encodings.value_decode("=?utf-123?Q?xxx?=")).to eq "xxx-utf-123"
end
with_encoder CustomEncoder.new do
expect(Mail::Encodings.value_decode("=?utf-123?Q?xxx?=")).to eq "xxx-utf-123"
end
end
it "uses converter for params" do
if RUBY_VERSION > "1.9"
with_encoder CustomEncoder.new do
result = Mail::Encodings.param_decode("'ja'%d0%91%d0%b5%d0%b7%d1%8b%d0%bc%d1%8f%d0%bd%d0%bd%d1%8b%d0%b912.png", 'iso-2022-jp')
expect(result).to eq "'ja'Безымянный12.png-iso-2022-jp"
end
with_encoder CustomEncoder.new do
result = Mail::Encodings.param_decode("'ja'%d0%91%d0%b5%d0%b7%d1%8b%d0%bc%d1%8f%d0%bd%d0%bd%d1%8b%d0%b912.png", 'iso-2022-jp')
expect(result).to eq "'ja'Безымянный12.png-iso-2022-jp"
end
end
it "can convert ansi with best effort" do
if RUBY_VERSION > "1.9"
with_encoder Mail::Ruby19::BestEffortCharsetEncoder.new do
expect(Mail::Encodings.value_decode("=?windows-1258?Q?SV=3A_Spr=F8sm=E5l_om_tilbod?=")).to eq "SV: Sprøsmål om tilbod"
end
with_encoder Mail::Ruby19::BestEffortCharsetEncoder.new do
expect(Mail::Encodings.value_decode("=?windows-1258?Q?SV=3A_Spr=F8sm=E5l_om_tilbod?=")).to eq "SV: Sprøsmål om tilbod"
end
end
end
@ -961,15 +925,11 @@ describe Mail::Encodings do
describe ".pick_encoding" do
it "finds encoding" do
if RUBY_VERSION >= "1.9"
expect(Mail::Ruby19.pick_encoding("Windows-1252")).to eq Encoding::Windows_1252
end
expect(Mail::Ruby19.pick_encoding("Windows-1252")).to eq Encoding::Windows_1252
end
it "uses binary for unfound" do
if RUBY_VERSION >= "1.9"
expect(Mail::Ruby19.pick_encoding("ISO-Foo")).to eq Encoding::BINARY
end
expect(Mail::Ruby19.pick_encoding("ISO-Foo")).to eq Encoding::BINARY
end
end
end

View File

@ -254,27 +254,21 @@ describe Mail::Field do
end
it "should allow an encoded value in the Subject field and decode it automatically (issue 44)" do
skip if RUBY_VERSION < '1.9'
subject = Mail::SubjectField.new("=?ISO-8859-1?Q?2_=FAlt?=", 'utf-8')
expect(subject.decoded).to eq "2 últ"
end
it "should allow you to encoded text in the middle (issue 44)" do
skip if RUBY_VERSION < '1.9'
subject = Mail::SubjectField.new("ma=?ISO-8859-1?Q?=F1ana?=", 'utf-8')
expect(subject.decoded).to eq "mañana"
end
it "more tolerable to encoding definitions, ISO (issue 120)" do
skip if RUBY_VERSION < '1.9'
subject = Mail::SubjectField.new("ma=?ISO88591?Q?=F1ana?=", 'utf-8')
expect(subject.decoded).to eq "mañana"
end
it "more tolerable to encoding definitions, ISO-long (issue 120)" do
# Rubies under 1.9 don't handle encoding conversions
skip if RUBY_VERSION < '1.9'
# TODO: JRuby 1.7.0 has an encoding issue https://jira.codehaus.org/browse/JRUBY-6999
skip if defined?(JRUBY_VERSION) && JRUBY_VERSION >= '1.7.0'
@ -295,8 +289,6 @@ describe Mail::Field do
it "more tolerable to encoding definitions, Windows (issue 120)" do
skip if RUBY_VERSION < '1.9'
# TODO: JRuby 1.7.0 has an encoding issue https://jira.codehaus.org/browse/JRUBY-6999
skip if defined?(JRUBY_VERSION) && JRUBY_VERSION >= '1.7.0'
@ -312,8 +304,6 @@ describe Mail::Field do
end
it "should support ascii encoded windows subjects" do
skip if RUBY_VERSION < '1.9'
# TODO: JRuby 1.7.0 has an encoding issue https://jira.codehaus.org/browse/JRUBY-6999
skip if defined?(JRUBY_VERSION) && JRUBY_VERSION >= '1.7.0'

View File

@ -7,14 +7,6 @@ describe Mail::CommonField do
describe "multi-charset support" do
before(:each) do
@original = $KCODE if RUBY_VERSION < '1.9'
end
after(:each) do
$KCODE = @original if RUBY_VERSION < '1.9'
end
it "should return '' on to_s if there is no value" do
expect(Mail::SubjectField.new(nil).to_s).to eq ''
end
@ -27,13 +19,8 @@ describe Mail::CommonField do
it "should encode a utf-8 string as utf-8 quoted printable" do
value = "かきくけこ"
if RUBY_VERSION < '1.9'
$KCODE = 'u'
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
else
value = value.dup.force_encoding('UTF-8')
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
end
value = value.dup.force_encoding('UTF-8')
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
field = Mail::SubjectField.new(value)
expect(field.encoded).to eq result
expect(field.decoded).to eq value
@ -42,13 +29,8 @@ describe Mail::CommonField do
it "should wrap an encoded at 60 characters" do
value = "かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ かきくけこ"
if RUBY_VERSION < '1.9'
$KCODE = 'u'
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
else
value = value.dup.force_encoding('UTF-8')
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
end
value = value.dup.force_encoding('UTF-8')
result = "Subject: =?UTF-8?Q?=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n\s=?UTF-8?Q?_=E3=81=8B=E3=81=8D=E3=81=8F=E3=81=91=E3=81=93?=\r\n"
field = Mail::SubjectField.new(value)
expect(field.encoded).to eq result
expect(field.decoded).to eq value
@ -57,13 +39,8 @@ describe Mail::CommonField do
it "should handle charsets in assigned addresses" do
value = '"かきくけこ" <mikel@test.lindsaar.net>'
if RUBY_VERSION < '1.9'
$KCODE = 'u'
result = "From: =?UTF-8?B?44GL44GN44GP44GR44GT?= <mikel@test.lindsaar.net>\r\n"
else
value = value.dup.force_encoding('UTF-8')
result = "From: =?UTF-8?B?44GL44GN44GP44GR44GT?= <mikel@test.lindsaar.net>\r\n"
end
value = value.dup.force_encoding('UTF-8')
result = "From: =?UTF-8?B?44GL44GN44GP44GR44GT?= <mikel@test.lindsaar.net>\r\n"
field = Mail::FromField.new(value)
expect(field.encoded).to eq result
expect(field.decoded).to eq value

View File

@ -649,27 +649,16 @@ describe Mail::ContentTypeField do
end
it "should encode a non us-ascii filename" do
@original = $KCODE if RUBY_VERSION < '1.9'
Mail.defaults do
param_encode_language('jp')
end
c = Mail::ContentTypeField.new('application/octet-stream')
string = "01 Quien Te Dij\221at. Pitbull.mp3"
case
when RUBY_VERSION >= '1.9.3'
string = string.dup.force_encoding('SJIS')
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=windows-31j'jp'01%20Quien%20Te%20Dij%91%61t.%20Pitbull.mp3\r\n}
when RUBY_VERSION >= '1.9'
string = string.dup.force_encoding('SJIS')
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=shift_jis'jp'01%20Quien%20Te%20Dij%91%61t.%20Pitbull.mp3\r\n}
else
$KCODE = 'SJIS'
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=sjis'jp'01%20Quien%20Te%20Dij%91at.%20Pitbull.mp3\r\n}
end
string = string.dup.force_encoding('SJIS')
result = %Q{Content-Type: application/octet-stream;\r\n\sfilename*=windows-31j'jp'01%20Quien%20Te%20Dij%91%61t.%20Pitbull.mp3\r\n}
c.filename = string
expect(c.parameters).to eql({"filename" => string})
expect(c.encoded).to eq result
$KCODE = @original if RUBY_VERSION < '1.9'
end
end

View File

@ -109,17 +109,6 @@ describe Mail::UnstructuredField do
@field = Mail::UnstructuredField.new("References", string)
expect(@field.decoded).to eq 'ä&ä&ä'
end
if !'1.9'.respond_to?(:force_encoding)
it "shouldn't get fooled into encoding on 1.8 due to an unrelated Encoding constant" do
begin
Mail::UnstructuredField::Encoding = 'derp'
expect(@field.encoded).to eq "Subject: Hello Frank\r\n"
ensure
Mail::UnstructuredField.send :remove_const, :Encoding
end
end
end
end
describe "folding" do
@ -156,33 +145,21 @@ describe Mail::UnstructuredField do
end
it "should fold itself if it is non us-ascii" do
@original = $KCODE if RUBY_VERSION < '1.9'
string = "This is あ really long string This is あ really long string This is あ really long string This is あ really long string This is あ really long string"
@field = Mail::UnstructuredField.new("Subject", string)
if string.respond_to?(:force_encoding)
string = string.dup.force_encoding('UTF-8')
else
$KCODE = 'u'
end
string = string.dup.force_encoding('UTF-8')
result = "Subject: =?UTF-8?Q?This_is_=E3=81=82_really_long_string_This_is_=E3=81=82?=\r\n\s=?UTF-8?Q?_really_long_string_This_is_=E3=81=82_really_long_string_This_is?=\r\n\s=?UTF-8?Q?_=E3=81=82_really_long_string_This_is_=E3=81=82_really_long?=\r\n\s=?UTF-8?Q?_string?=\r\n"
expect(@field.encoded).to eq result
expect(@field.decoded).to eq string
$KCODE = @original if RUBY_VERSION < '1.9'
end
it "should fold properly with my actual complicated header" do
@original = $KCODE if RUBY_VERSION < '1.9'
string = %|{"unique_args": {"mailing_id":147,"account_id":2}, "to": ["larspind@gmail.com"], "category": "mailing", "filters": {"domainkeys": {"settings": {"domain":1,"enable":1}}}, "sub": {"{{open_image_url}}": ["http://betaling.larspind.local/O/token/147/Mailing::FakeRecipient"], "{{name}}": ["[FIRST NAME]"], "{{signup_reminder}}": ["(her kommer til at stå hvornår folk har skrevet sig op ...)"], "{{unsubscribe_url}}": ["http://betaling.larspind.local/U/token/147/Mailing::FakeRecipient"], "{{email}}": ["larspind@gmail.com"], "{{link:308}}": ["http://betaling.larspind.local/L/308/0/Mailing::FakeRecipient"], "{{confirm_url}}": [""], "{{ref}}": ["[REF]"]}}|
@field = Mail::UnstructuredField.new("X-SMTPAPI", string)
if string.respond_to?(:force_encoding)
string = string.dup.force_encoding('UTF-8')
else
$KCODE = 'u'
end
string = string.dup.force_encoding('UTF-8')
result = "X-SMTPAPI: =?UTF-8?Q?{=22unique=5Fargs=22:_{=22mailing=5Fid=22:147,=22a?=\r\n =?UTF-8?Q?ccount=5Fid=22:2},_=22to=22:_[=22larspind@gmail.com=22],_=22categ?=\r\n =?UTF-8?Q?ory=22:_=22mailing=22,_=22filters=22:_{=22domainkeys=22:_{=22sett?=\r\n =?UTF-8?Q?ings=22:_{=22domain=22:1,=22enable=22:1}}},_=22sub=22:_{=22{{op?=\r\n =?UTF-8?Q?en=5Fimage=5Furl}}=22:_[=22http://betaling.larspind.local/O?=\r\n =?UTF-8?Q?/token/147/Mailing::FakeRecipient=22],_=22{{name}}=22:_[=22[FIRST?=\r\n =?UTF-8?Q?_NAME]=22],_=22{{signup=5Freminder}}=22:_[=22=28her_kommer_til_at?=\r\n =?UTF-8?Q?_st=C3=A5_hvorn=C3=A5r_folk_har_skrevet_sig_op_...=29=22],?=\r\n =?UTF-8?Q?_=22{{unsubscribe=5Furl}}=22:_[=22http://betaling.larspind.?=\r\n =?UTF-8?Q?local/U/token/147/Mailing::FakeRecipient=22],_=22{{email}}=22:?=\r\n =?UTF-8?Q?_[=22larspind@gmail.com=22],_=22{{link:308}}=22:_[=22http://beta?=\r\n =?UTF-8?Q?ling.larspind.local/L/308/0/Mailing::FakeRecipient=22],_=22{{con?=\r\n =?UTF-8?Q?firm=5Furl}}=22:_[=22=22],_=22{{ref}}=22:_[=22[REF]=22]}}?=\r\n"
expect(@field.encoded).to eq result
expect(@field.decoded).to eq string
$KCODE = @original if RUBY_VERSION < '1.9'
end
it "should fold properly with continuous spaces around the linebreak" do
@ -205,8 +182,7 @@ describe Mail::UnstructuredField do
it "should encoded with ISO-2022-JP encoding" do
@field = Mail::UnstructuredField.new("Subject", "あいうえお")
@field.charset = 'iso-2022-jp'
expect = (RUBY_VERSION < '1.9') ? "Subject: =?ISO-2022-JP?Q?=E3=81=82=E3=81=84=E3=81=86=E3=81=88=E3=81=8A?=\r\n" : "Subject: =?ISO-2022-JP?Q?=1B$B$=22$$$&$=28$*=1B=28B?=\r\n"
expect(@field.encoded).to eq expect
expect(@field.encoded).to eq "Subject: =?ISO-2022-JP?Q?=1B$B$=22$$$&$=28$*=1B=28B?=\r\n"
end
end
end

View File

@ -460,9 +460,8 @@ HERE
expect(header['Received'].value).to eq "from [127.0.220.158] (helo=fg-out-1718.google.com)\tby smtp.totallyrandom.com with esmtp (Exim 4.68)\t(envelope-from <stuff+caf_=support=aaa.somewhere.com@gmail.com>)\tid 1K4JeQ-0005Nd-Ij\tfor support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700"
end
if RUBY_VERSION >= '1.9'
it "should convert all lonesome LFs to CRLF in UTF-8 too" do
header = Mail::Header.new(<<HERE)
it "should convert all lonesome LFs to CRLF in UTF-8 too" do
header = Mail::Header.new(<<HERE)
Subject: Iñtërnâtiônàlizætiøn
Received: from [127.0.220.158] (helo=fg-out-1718.google.com)
by smtp.totallyrandom.com with esmtp (Exim 4.68)
@ -471,11 +470,9 @@ Received: from [127.0.220.158] (helo=fg-out-1718.google.com)
for support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700
HERE
expect(header['Received'].value).to eq "from [127.0.220.158] (helo=fg-out-1718.google.com)\tby smtp.totallyrandom.com with esmtp (Exim 4.68)\t(envelope-from <stuff+caf_=support=aaa.somewhere.com@gmail.com>)\tid 1K4JeQ-0005Nd-Ij\tfor support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700"
end
expect(header['Received'].value).to eq "from [127.0.220.158] (helo=fg-out-1718.google.com)\tby smtp.totallyrandom.com with esmtp (Exim 4.68)\t(envelope-from <stuff+caf_=support=aaa.somewhere.com@gmail.com>)\tid 1K4JeQ-0005Nd-Ij\tfor support@aaa.somewhere.com; Thu, 05 Jun 2008 10:53:29 -0700"
end
it "should convert all lonesome CRs to CRLF" do
header = Mail::Header.new(<<HERE.gsub(/\n/, "\r"))
Received: from [127.0.220.158] (helo=fg-out-1718.google.com)

View File

@ -66,11 +66,9 @@ describe Mail::Message do
expect(mail.from).to eq ['mikel@me.com']
expect(mail.to).to eq ['lindsaar@you.com']
if RUBY_VERSION >= '1.9'
mail = ClassThatCreatesMail.new('mikel@me.com', 'lindsaar@you.com').create_mail_with_splat_args
expect(mail.from).to eq ['mikel@me.com']
expect(mail.to).to eq ['lindsaar@you.com']
end
mail = ClassThatCreatesMail.new('mikel@me.com', 'lindsaar@you.com').create_mail_with_splat_args
expect(mail.from).to eq ['mikel@me.com']
expect(mail.to).to eq ['lindsaar@you.com']
end
it "should initialize a body and header class even if called with nothing to begin with" do
@ -1680,12 +1678,10 @@ describe Mail::Message do
expect(message.inspect_structure).to eq message.inspect
end
if RUBY_VERSION > "1.9"
it "uses the Ruby19 charset encoder" do
with_encoder(Mail::Ruby19::BestEffortCharsetEncoder.new) do
message = Mail.new("Content-Type: text/plain;\r\n charset=windows-1258\r\nContent-Transfer-Encoding: base64\r\n\r\nSGkglg==\r\n")
expect(message.decoded).to eq("Hi ")
end
it "uses the Ruby19 charset encoder" do
with_encoder(Mail::Ruby19::BestEffortCharsetEncoder.new) do
message = Mail.new("Content-Type: text/plain;\r\n charset=windows-1258\r\nContent-Transfer-Encoding: base64\r\n\r\nSGkglg==\r\n")
expect(message.decoded).to eq("Hi ")
end
end
end

View File

@ -417,9 +417,6 @@ describe "MIME Emails" do
end
Dir.glob(fixture_path('attachments', "test.*")).each do |test_attachment|
# This spec fails for (most?) jpegs in 1.8.7
next if test_attachment.end_with?('test.jpg') && RUBY_VERSION < '1.9'
it "should find binary encoded attachments of type #{File.extname(test_attachment)}" do
pre, post = read_raw_fixture('emails', 'mime_emails', 'raw_email_with_binary_encoded.eml').split('BINARY_CONTENT_GOES_HERE')
raw_file = File.open(test_attachment, "rb", &:read)
@ -526,25 +523,19 @@ describe "MIME Emails" do
add_file fixture_path('attachments', 'test.pdf')
add_file fixture_path('attachments', 'test.zip')
end
if RUBY_VERSION >= '1.9'
tripped = mail.attachments[0].decoded
original = read_raw_fixture('attachments', 'test.png')
expect(tripped).to eq original
tripped = mail.attachments[1].decoded
original = read_raw_fixture('attachments', 'test.jpg')
expect(tripped).to eq original
tripped = mail.attachments[2].decoded
original = read_raw_fixture('attachments', 'test.pdf')
expect(tripped).to eq original
tripped = mail.attachments[3].decoded
original = read_raw_fixture('attachments', 'test.zip')
expect(tripped).to eq original
else
expect(mail.attachments[0].decoded).to eq read_raw_fixture('attachments', 'test.png')
expect(mail.attachments[1].decoded).to eq read_raw_fixture('attachments', 'test.jpg')
expect(mail.attachments[2].decoded).to eq read_raw_fixture('attachments', 'test.pdf')
expect(mail.attachments[3].decoded).to eq read_raw_fixture('attachments', 'test.zip')
end
tripped = mail.attachments[0].decoded
original = read_raw_fixture('attachments', 'test.png')
expect(tripped).to eq original
tripped = mail.attachments[1].decoded
original = read_raw_fixture('attachments', 'test.jpg')
expect(tripped).to eq original
tripped = mail.attachments[2].decoded
original = read_raw_fixture('attachments', 'test.pdf')
expect(tripped).to eq original
tripped = mail.attachments[3].decoded
original = read_raw_fixture('attachments', 'test.zip')
expect(tripped).to eq original
end
it "should allow you to send in file data instead of having to read it" do
@ -555,13 +546,10 @@ describe "MIME Emails" do
to 'mikel@to.lindsaar.net'
add_file(:filename => 'test.png', :content => file_data)
end
if RUBY_VERSION >= '1.9'
tripped = mail.attachments[0].decoded
original = read_raw_fixture('attachments', 'test.png')
expect(tripped).to eq original
else
expect(mail.attachments[0].decoded).to eq read_raw_fixture('attachments', 'test.png')
end
tripped = mail.attachments[0].decoded
original = read_raw_fixture('attachments', 'test.png')
expect(tripped).to eq original
end
it "should support :mime_type option" do

View File

@ -133,7 +133,7 @@ describe Mail::Sendmail do
it 'raises on nonzero exitstatus' do
command = %w[ /usr/sbin/sendmail -i -f roger@test.lindsaar.net -- marcel@test.lindsaar.net bob@test.lindsaar.net ]
args = [ command, 'w+' ]
args << { :err => :out } if RUBY_VERSION >= '1.9'
args << { :err => :out }
expect(IO).to receive(:popen).with(*args) { system 'false' }

View File

@ -15,39 +15,6 @@ describe "SMTP Delivery Method" do
Mail.delivery_method.smtp.finish
end
it "should not dot-stuff in recent Ruby versions" do
skip "is skipped on older Ruby versions" if RUBY_VERSION < '2.1.3'
expect(Mail.delivery_method.send(:dot_stuff?)).to eq false
end
it "dot-stuff unterminated last line of the message" do
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail.delivery_method.send(:dot_stuff?)
Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n... only a test\n... or is it?"
end
message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n... only a test\n.... or is it?")
end
it "dot-stuff unterminated last line of the message containing a single dot" do
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail.delivery_method.send(:dot_stuff?)
Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n.\nonly a test\n."
end
message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n..")
end
it "should not dot-stuff unterminated last line with no leading dot" do
body = "this is a test\n.\nonly a test"

View File

@ -26,20 +26,6 @@ describe "SMTP Delivery Method" do
end
describe "general usage" do
it "dot-stuff unterminated last line of the message" do
skip "is skipped on Ruby versions without dot-stuff bug" unless Mail::SMTPConnection.new(:connection => Mail.delivery_method).send(:dot_stuff?)
Mail.deliver do
from 'from@example.com'
to 'to@example.com'
subject 'dot-stuff last line'
body "this is a test\n.\nonly a test\n... or is it?"
end
message = MockSMTP.deliveries.first
expect(Mail.new(message).decoded).to eq("this is a test\n.\nonly a test\n.... or is it?")
end
it "should send emails from given settings" do
mail = Mail.deliver do

View File

@ -84,27 +84,25 @@ describe "Utilities Module" do
expect { quote_phrase(input_str) }.not_to raise_error
end
if RUBY_VERSION >= '1.9'
describe "given a non-unsafe string" do
it "should not change the encoding" do
input_str = "blargh"
input_str_encoding = input_str.encoding
describe "given a non-unsafe string" do
it "should not change the encoding" do
input_str = "blargh"
input_str_encoding = input_str.encoding
result = quote_phrase(input_str)
result = quote_phrase(input_str)
expect(result.encoding).to eq input_str_encoding
end
expect(result.encoding).to eq input_str_encoding
end
end
describe "given an unsafe string" do
it "should not change the encoding" do
input_str = "Bjørn"
input_str_encoding = input_str.encoding
describe "given an unsafe string" do
it "should not change the encoding" do
input_str = "Bjørn"
input_str_encoding = input_str.encoding
result = quote_phrase(input_str)
result = quote_phrase(input_str)
expect(result.encoding).to eq input_str_encoding
end
expect(result.encoding).to eq input_str_encoding
end
end
end

View File

@ -1,33 +0,0 @@
# encoding: utf-8
# frozen_string_literal: true
require 'spec_helper'
describe "Ruby 1.8 Extensions" do
describe "string ascii detection" do
it "should say it is US-ASCII only if it is" do
expect("abc").to be_ascii_only
end
it "should not say it is US-ASCII only if it isn't" do
expect("かきくけこ").not_to be_ascii_only
end
it "should not say it is US-ASCII only if it is a mix" do
expect("abcかきくけこ123").not_to be_ascii_only
end
it "should handle edge cases" do
["\x00", "\x01", "\x40", "\x7f", "\x73"].each do |str|
expect(str).to be_ascii_only
end
["\x81", "\x99", "\xFF"].each do |str|
expect(str).not_to be_ascii_only
end
end
end
end

View File

@ -2,11 +2,9 @@
# frozen_string_literal: true
require 'spec_helper'
if RUBY_VERSION > '1.9'
describe '.decode_base64' do
it "handles unpadded base64 correctly" do
decoded = Mail::Ruby19.decode_base64("YQ")
expect(decoded).to eq "a"
end
describe '.decode_base64' do
it "handles unpadded base64 correctly" do
decoded = Mail::Ruby19.decode_base64("YQ")
expect(decoded).to eq "a"
end
end

View File

@ -27,21 +27,10 @@ RSpec.configure do |c|
c.mock_with :rspec
c.include(CustomMatchers)
MINIMUM_RSPEC_BENCHMARK_RUBY_VERSION = "2.2"
if RUBY_VERSION >= MINIMUM_RSPEC_BENCHMARK_RUBY_VERSION
require 'rspec-benchmark'
c.include RSpec::Benchmark::Matchers
end
c.filter_run_excluding :require_rspec_benchmark => lambda { |version|
RUBY_VERSION < MINIMUM_RSPEC_BENCHMARK_RUBY_VERSION
}
require 'rspec-benchmark'
c.include RSpec::Benchmark::Matchers
end
# NOTE: We set the KCODE manually here in 1.8.X because upgrading to rspec-2.8.0 caused it
# to default to "NONE" (Why!?).
$KCODE='UTF8' if RUBY_VERSION < '1.9'
if defined?(Encoding) && Encoding.respond_to?(:default_external=)
begin
orig, $VERBOSE = $VERBOSE, nil

View File

@ -3,13 +3,7 @@ require 'rubygems'
require 'bundler/setup'
begin
if RUBY_VERSION >= '2.0'
require 'byebug'
elsif RUBY_VERSION >= '1.9'
require 'debugger'
else
require 'ruby-debug'
end
require 'byebug'
rescue LoadError
end