Hello community,

here is the log from the commit of package rubygem-addressable for 
openSUSE:Factory checked in at 2017-04-17 10:25:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-addressable (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-addressable.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-addressable"

Mon Apr 17 10:25:27 2017 rev:16 rq:484839 version:2.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-addressable/rubygem-addressable.changes  
2016-01-12 16:12:06.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-addressable.new/rubygem-addressable.changes 
    2017-04-17 10:25:31.960829918 +0200
@@ -1,0 +2,30 @@
+Thu Mar 30 04:28:46 UTC 2017 - [email protected]
+
+- updated to version 2.5.1
+ see installed CHANGELOG.md
+
+  # Addressable 2.5.1
+  - allow unicode normalization to be disabled for URI Template expansion
+  - removed duplicate test
+
+-------------------------------------------------------------------
+Sat Nov  5 05:28:41 UTC 2016 - [email protected]
+
+- updated to version 2.5.0
+ see installed CHANGELOG.md
+
+  # Addressable 2.5.0
+  - dropping support for Ruby 1.9
+  - adding support for Ruby 2.4 preview
+  - add support for public suffixes and tld; first runtime dependency
+  - hostname escaping should match RFC; underscores in hostnames no longer 
escaped
+  - paths beginning with // and missing an authority are now considered invalid
+  - validation now also takes place after setting a path
+  - handle backslashes in authority more like a browser for `heuristic_parse`
+  - unescaped backslashes in host now raise an `InvalidURIError`
+  - `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred 
validation
+  - `heuristic_parse` now trims whitespace before parsing
+  - host parts longer than 63 bytes will be ignored and not passed to libidn
+  - normalized values always encoded as UTF-8
+
+-------------------------------------------------------------------

Old:
----
  addressable-2.4.0.gem

New:
----
  addressable-2.5.1.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-addressable.spec ++++++
--- /var/tmp/diff_new_pack.BFU7cK/_old  2017-04-17 10:25:33.036677558 +0200
+++ /var/tmp/diff_new_pack.BFU7cK/_new  2017-04-17 10:25:33.040676991 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-addressable
 #
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,12 +24,12 @@
 #
 
 Name:           rubygem-addressable
-Version:        2.4.0
+Version:        2.5.1
 Release:        0
 %define mod_name addressable
 %define mod_full_name %{mod_name}-%{version}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildRequires:  %{ruby >= 1.9.0}
+BuildRequires:  %{ruby >= 2.0}
 BuildRequires:  %{rubygem gem2rpm}
 BuildRequires:  %{rubygem rdoc > 3.10}
 BuildRequires:  ruby-macros >= 5

++++++ addressable-2.4.0.gem -> addressable-2.5.1.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md    2015-12-07 05:38:26.000000000 +0100
+++ new/CHANGELOG.md    2017-03-29 23:14:40.000000000 +0200
@@ -1,3 +1,21 @@
+# Addressable 2.5.1
+- allow unicode normalization to be disabled for URI Template expansion
+- removed duplicate test
+
+# Addressable 2.5.0
+- dropping support for Ruby 1.9
+- adding support for Ruby 2.4 preview
+- add support for public suffixes and tld; first runtime dependency
+- hostname escaping should match RFC; underscores in hostnames no longer 
escaped
+- paths beginning with // and missing an authority are now considered invalid
+- validation now also takes place after setting a path
+- handle backslashes in authority more like a browser for `heuristic_parse`
+- unescaped backslashes in host now raise an `InvalidURIError`
+- `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred validation
+- `heuristic_parse` now trims whitespace before parsing
+- host parts longer than 63 bytes will be ignored and not passed to libidn
+- normalized values always encoded as UTF-8
+
 # Addressable 2.4.0
 - support for 1.8.x dropped
 - double quotes in a host now raises an error
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 2015-12-07 05:38:26.000000000 +0100
+++ new/Gemfile 2017-03-29 23:14:40.000000000 +0200
@@ -2,8 +2,6 @@
 
 gemspec
 
-gem 'rake', '~> 10.4', '>= 10.4.2'
-
 group :test do
   gem 'rspec', '~> 3.0'
   gem 'rspec-its', '~> 1.1'
@@ -16,12 +14,19 @@
 end
 
 group :test, :development do
+  gem 'rake', '> 10.0', '< 12'
   gem 'simplecov', :require => false
   gem 'coveralls', :require => false, :platforms => [
-    :ruby_19, :ruby_20, :ruby_21, :rbx, :jruby
+    :ruby_20, :ruby_21, :ruby_22, :ruby_23
   ]
   # Used to test compatibility.
   gem 'rack-mount', git: 'https://github.com/sporkmonger/rack-mount.git', 
require: 'rack/mount'
+
+  if RUBY_VERSION.start_with?('2.0', '2.1')
+    gem 'rack', '< 2', :require => false
+  else
+    gem 'rack', :require => false
+  end
 end
 
-gem 'idn-ruby', :platform => [:mri_19, :mri_20, :mri_21, :mri_22]
+gem 'idn-ruby', :platform => [:mri_20, :mri_21, :mri_22]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2015-12-07 05:38:26.000000000 +0100
+++ new/README.md       2017-03-29 23:14:40.000000000 +0200
@@ -3,16 +3,15 @@
 <dl>
   <dt>Homepage</dt><dd><a 
href="https://github.com/sporkmonger/addressable";>github.com/sporkmonger/addressable</a></dd>
   <dt>Author</dt><dd><a href="mailto:[email protected]";>Bob Aman</a></dd>
-  <dt>Copyright</dt><dd>Copyright © 2006-2015 Bob Aman</dd>
+  <dt>Copyright</dt><dd>Copyright © Bob Aman</dd>
   <dt>License</dt><dd>Apache 2.0</dd>
 </dl>
 
 [![Gem Version](http://img.shields.io/gem/dt/addressable.svg)][gem]
-[![Build 
Status](https://secure.travis-ci.org/sporkmonger/addressable.png?branch=master)][travis]
-[![Dependency 
Status](https://gemnasium.com/sporkmonger/addressable.png?travis)][gemnasium]
+[![Build 
Status](https://secure.travis-ci.org/sporkmonger/addressable.svg?branch=master)][travis]
+[![Dependency 
Status](https://gemnasium.com/sporkmonger/addressable.svg?travis)][gemnasium]
 [![Test Coverage 
Status](https://img.shields.io/coveralls/sporkmonger/addressable.svg)][coveralls]
 [![Documentation Coverage 
Status](http://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch]
-[![Gittip 
Donate](http://img.shields.io/gittip/sporkmonger.png)](https://www.gittip.com/sporkmonger/
 "Support Open Source Development w/ Gittip")
 
 [gem]: https://rubygems.org/gems/addressable
 [travis]: http://travis-ci.org/sporkmonger/addressable
@@ -92,7 +91,7 @@
 # Install
 
 ```console
-$ sudo gem install addressable
+$ gem install addressable
 ```
 
 You may optionally turn on native IDN support by installing libidn and the
@@ -103,3 +102,20 @@
 $ brew install libidn # OS X
 $ gem install idn-ruby
 ```
+
+# Semantic Versioning
+
+This project uses sementic versioning. You can (and should) specify your
+dependency using a pessimistic version constraint covering the major and minor
+values:
+
+```ruby
+spec.add_dependency 'addressable', '~> 2.5'
+```
+
+If you need a specific bug fix, you can also specify minimum tiny versions
+without preventing updates to the latest minor release:
+
+```ruby
+spec.add_dependency 'addressable', '~> 2.3', '>= 2.3.7'
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/addressable.gemspec new/addressable.gemspec
--- old/addressable.gemspec     2015-12-07 05:38:26.000000000 +0100
+++ new/addressable.gemspec     1970-01-01 01:00:00.000000000 +0100
@@ -1,34 +0,0 @@
-# -*- encoding: utf-8 -*-
-# stub: addressable 2.4.0 ruby lib
-
-Gem::Specification.new do |s|
-  s.name = "addressable"
-  s.version = "2.4.0"
-
-  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? 
:required_rubygems_version=
-  s.require_paths = ["lib"]
-  s.authors = ["Bob Aman"]
-  s.date = "2015-12-07"
-  s.description = "Addressable is a replacement for the URI implementation 
that is part of\nRuby's standard library. It more closely conforms to the 
relevant RFCs and\nadds support for IRIs and URI templates.\n"
-  s.email = "[email protected]"
-  s.extra_rdoc_files = ["README.md"]
-  s.files = ["CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", 
"Rakefile", "addressable.gemspec", "data/unicode.data", "lib/addressable.rb", 
"lib/addressable/idna.rb", "lib/addressable/idna/native.rb", 
"lib/addressable/idna/pure.rb", "lib/addressable/template.rb", 
"lib/addressable/uri.rb", "lib/addressable/version.rb", 
"spec/addressable/idna_spec.rb", "spec/addressable/net_http_compat_spec.rb", 
"spec/addressable/rack_mount_compat_spec.rb", 
"spec/addressable/security_spec.rb", "spec/addressable/template_spec.rb", 
"spec/addressable/uri_spec.rb", "spec/spec_helper.rb", "tasks/clobber.rake", 
"tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rspec.rake", 
"tasks/yard.rake"]
-  s.homepage = "https://github.com/sporkmonger/addressable";
-  s.licenses = ["Apache-2.0"]
-  s.rdoc_options = ["--main", "README.md"]
-  s.required_ruby_version = Gem::Requirement.new(">= 1.9.0")
-  s.rubygems_version = "2.5.0"
-  s.summary = "URI Implementation"
-
-  if s.respond_to? :specification_version then
-    s.specification_version = 4
-
-    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
-      s.add_development_dependency(%q<bundler>, ["~> 1.0"])
-    else
-      s.add_dependency(%q<bundler>, ["~> 1.0"])
-    end
-  else
-    s.add_dependency(%q<bundler>, ["~> 1.0"])
-  end
-end
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/addressable/idna/native.rb 
new/lib/addressable/idna/native.rb
--- old/lib/addressable/idna/native.rb  2015-12-07 05:38:26.000000000 +0100
+++ new/lib/addressable/idna/native.rb  2017-03-29 23:14:40.000000000 +0200
@@ -1,6 +1,6 @@
 # encoding:utf-8
 #--
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -34,8 +34,10 @@
 
     def self.to_ascii(value)
       value.to_s.split('.', -1).map do |segment|
-        if segment.size > 0
+        if segment.size > 0 && segment.size < 64
           IDN::Idna.toASCII(segment)
+        elsif segment.size >= 64
+          segment
         else
           ''
         end
@@ -44,8 +46,10 @@
 
     def self.to_unicode(value)
       value.to_s.split('.', -1).map do |segment|
-        if segment.size > 0
+        if segment.size > 0 && segment.size < 64
           IDN::Idna.toUnicode(segment)
+        elsif segment.size >= 64
+          segment
         else
           ''
         end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/addressable/idna/pure.rb 
new/lib/addressable/idna/pure.rb
--- old/lib/addressable/idna/pure.rb    2015-12-07 05:38:26.000000000 +0100
+++ new/lib/addressable/idna/pure.rb    2017-03-29 23:14:40.000000000 +0200
@@ -1,6 +1,6 @@
 # encoding:utf-8
 #--
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -94,7 +94,12 @@
       parts = input.split('.')
       parts.map! do |part|
         if part =~ /^#{ACE_PREFIX}(.+)/
-          punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1])
+          begin
+            punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1])
+          rescue Addressable::IDNA::PunycodeBadInput
+            # toUnicode is explicitly defined as never-fails by the spec
+            part
+          end
         else
           part
         end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/addressable/idna.rb new/lib/addressable/idna.rb
--- old/lib/addressable/idna.rb 2015-12-07 05:38:26.000000000 +0100
+++ new/lib/addressable/idna.rb 2017-03-29 23:14:40.000000000 +0200
@@ -1,6 +1,6 @@
 # encoding:utf-8
 #--
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/addressable/template.rb 
new/lib/addressable/template.rb
--- old/lib/addressable/template.rb     2015-12-07 05:38:26.000000000 +0100
+++ new/lib/addressable/template.rb     2017-03-29 23:14:40.000000000 +0200
@@ -1,6 +1,6 @@
 # encoding:utf-8
 #--
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -488,6 +488,8 @@
     # @param [Hash] mapping The mapping that corresponds to the pattern.
     # @param [#validate, #transform] processor
     #   An optional processor object may be supplied.
+    # @param [Boolean] normalize_values
+    #   Optional flag to enable/disable unicode normalization. Default: true
     #
     # The object should respond to either the <tt>validate</tt> or
     # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
@@ -518,11 +520,11 @@
     #     "http://example.com/{?one,two,three}/";
     #   ).partial_expand({"one" => "1", "three" => 3}).pattern
     #   #=> "http://example.com/?one=1{&two}&three=3";
-    def partial_expand(mapping, processor=nil)
+    def partial_expand(mapping, processor=nil, normalize_values=true)
       result = self.pattern.dup
       mapping = normalize_keys(mapping)
       result.gsub!( EXPRESSION ) do |capture|
-        transform_partial_capture(mapping, capture, processor)
+        transform_partial_capture(mapping, capture, processor, 
normalize_values)
       end
       return Addressable::Template.new(result)
     end
@@ -533,6 +535,8 @@
     # @param [Hash] mapping The mapping that corresponds to the pattern.
     # @param [#validate, #transform] processor
     #   An optional processor object may be supplied.
+    # @param [Boolean] normalize_values
+    #   Optional flag to enable/disable unicode normalization. Default: true
     #
     # The object should respond to either the <tt>validate</tt> or
     # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
@@ -583,11 +587,11 @@
     #     ExampleProcessor
     #   ).to_str
     #   #=> Addressable::Template::InvalidTemplateValueError
-    def expand(mapping, processor=nil)
+    def expand(mapping, processor=nil, normalize_values=true)
       result = self.pattern.dup
       mapping = normalize_keys(mapping)
       result.gsub!( EXPRESSION ) do |capture|
-        transform_capture(mapping, capture, processor)
+        transform_capture(mapping, capture, processor, normalize_values)
       end
       return Addressable::URI.parse(result)
     end
@@ -704,6 +708,8 @@
     #   The expression to expand
     # @param [#validate, #transform] processor
     #   An optional processor object may be supplied.
+    # @param [Boolean] normalize_values
+    #   Optional flag to enable/disable unicode normalization. Default: true
     #
     # The object should respond to either the <tt>validate</tt> or
     # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
@@ -718,7 +724,8 @@
     # after sending the value to the transform method.
     #
     # @return [String] The expanded expression
-    def transform_partial_capture(mapping, capture, processor = nil)
+    def transform_partial_capture(mapping, capture, processor = nil,
+                                  normalize_values = true)
       _, operator, varlist = *capture.match(EXPRESSION)
 
       vars = varlist.split(',')
@@ -740,7 +747,8 @@
           _, name, _ =  *varspec.match(VARSPEC)
 
           acc << if mapping.key? name
-                   transform_capture(mapping, "{#{op}#{varspec}}", processor)
+                   transform_capture(mapping, "{#{op}#{varspec}}",
+                                     processor, normalize_values)
                  else
                    "{#{op}#{varspec}}"
                  end
@@ -780,6 +788,9 @@
     #   The expression to replace
     # @param [#validate, #transform] processor
     #   An optional processor object may be supplied.
+    # @param [Boolean] normalize_values
+    #   Optional flag to enable/disable unicode normalization. Default: true
+    #
     #
     # The object should respond to either the <tt>validate</tt> or
     # <tt>transform</tt> messages or both. Both the <tt>validate</tt> and
@@ -794,7 +805,8 @@
     # after sending the value to the transform method.
     #
     # @return [String] The expanded expression
-    def transform_capture(mapping, capture, processor=nil)
+    def transform_capture(mapping, capture, processor=nil,
+                          normalize_values=true)
       _, operator, varlist = *capture.match(EXPRESSION)
       return_value = varlist.split(',').inject([]) do |acc, varspec|
         _, name, modifier = *varspec.match(VARSPEC)
@@ -814,7 +826,7 @@
               "Can't convert #{value.class} into String or Array."
           end
 
-          value = normalize_value(value)
+          value = normalize_value(value) if normalize_values
 
           if processor == nil || !processor.respond_to?(:transform)
             # Handle percent escaping
@@ -877,7 +889,9 @@
             end
             if processor.respond_to?(:transform)
               transformed_value = processor.transform(name, value)
-              transformed_value = normalize_value(transformed_value)
+              if normalize_values
+                transformed_value = normalize_value(transformed_value)
+              end
             end
           end
           acc << [name, transformed_value]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/addressable/uri.rb new/lib/addressable/uri.rb
--- old/lib/addressable/uri.rb  2015-12-07 05:38:26.000000000 +0100
+++ new/lib/addressable/uri.rb  2017-03-29 23:14:40.000000000 +0200
@@ -1,6 +1,6 @@
 # encoding:utf-8
 #--
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
 
 require "addressable/version"
 require "addressable/idna"
+require "public_suffix"
 
 ##
 # Addressable is a library for processing links and URIs.
@@ -44,7 +45,7 @@
       UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
       PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
       SCHEME = ALPHA + DIGIT + "\\-\\+\\."
-      HOST = ALPHA + DIGIT + "\\-\\.\\[\\:\\]"
+      HOST = UNRESERVED + SUB_DELIMS + "\\[\\:\\]"
       AUTHORITY = PCHAR
       PATH = PCHAR + "\\/"
       QUERY = PCHAR + "\\/\\?"
@@ -176,7 +177,7 @@
         raise TypeError, "Can't convert #{uri.class} into String."
       end
       # Otherwise, convert to a String
-      uri = uri.to_str.dup
+      uri = uri.to_str.dup.strip
       hints = {
         :scheme => "http"
       }.merge(hints)
@@ -194,6 +195,15 @@
       when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
         uri.gsub!(/^/, hints[:scheme] + "://")
       end
+      match = uri.match(URIREGEX)
+      fragments = match.captures
+      authority = fragments[3]
+      if authority && authority.length > 0
+        new_authority = authority.gsub(/\\/, '/').gsub(/ /, '%20')
+        # NOTE: We want offset 4, not 3!
+        offset = match.offset(4)
+        uri[offset[0]...offset[1]] = new_authority
+      end
       parsed = self.parse(uri)
       if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/
         parsed = self.parse(hints[:scheme] + "://" + uri)
@@ -367,12 +377,10 @@
       if character_class.kind_of?(String)
         character_class = /[^#{character_class}]/
       end
-      if component.respond_to?(:force_encoding)
-        # We can't perform regexps on invalid UTF sequences, but
-        # here we need to, so switch to ASCII.
-        component = component.dup
-        component.force_encoding(Encoding::ASCII_8BIT)
-      end
+      # We can't perform regexps on invalid UTF sequences, but
+      # here we need to, so switch to ASCII.
+      component = component.dup
+      component.force_encoding(Encoding::ASCII_8BIT)
       # Avoiding gsub! because there are edge cases with frozen strings
       component = component.gsub(character_class) do |sequence|
         (sequence.unpack('C*').map { |c| "%" + ("%02x" % c).upcase }).join
@@ -427,14 +435,14 @@
       end
       uri = uri.dup
       # Seriously, only use UTF-8. I'm really not kidding!
-      uri.force_encoding("utf-8") if uri.respond_to?(:force_encoding)
-      leave_encoded.force_encoding("utf-8") if 
leave_encoded.respond_to?(:force_encoding)
+      uri.force_encoding("utf-8")
+      leave_encoded.force_encoding("utf-8")
       result = uri.gsub(/%[0-9a-f]{2}/iu) do |sequence|
         c = sequence[1..3].to_i(16).chr
-        c.force_encoding("utf-8") if c.respond_to?(:force_encoding)
+        c.force_encoding("utf-8")
         leave_encoded.include?(c) ? sequence : c
       end
-      result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
+      result.force_encoding("utf-8")
       if return_type == String
         return result
       elsif return_type == ::Addressable::URI
@@ -521,12 +529,10 @@
 
         character_class = /[^#{character_class}]#{leave_re}/
       end
-      if component.respond_to?(:force_encoding)
-        # We can't perform regexps on invalid UTF sequences, but
-        # here we need to, so switch to ASCII.
-        component = component.dup
-        component.force_encoding(Encoding::ASCII_8BIT)
-      end
+      # We can't perform regexps on invalid UTF sequences, but
+      # here we need to, so switch to ASCII.
+      component = component.dup
+      component.force_encoding(Encoding::ASCII_8BIT)
       unencoded = self.unencode_component(component, String, leave_encoded)
       begin
         encoded = self.encode_component(
@@ -537,9 +543,7 @@
       rescue ArgumentError
         encoded = self.encode_component(unencoded)
       end
-      if encoded.respond_to?(:force_encoding)
-        encoded.force_encoding(Encoding::UTF_8)
-      end
+      encoded.force_encoding(Encoding::UTF_8)
       return encoded
     end
 
@@ -851,6 +855,9 @@
           )
         end
       end
+      # All normalized values should be UTF-8
+      @normalized_scheme.force_encoding(Encoding::UTF_8) if @normalized_scheme
+      @normalized_scheme
     end
 
     ##
@@ -903,6 +910,9 @@
           )
         end
       end
+      # All normalized values should be UTF-8
+      @normalized_user.force_encoding(Encoding::UTF_8) if @normalized_user
+      @normalized_user
     end
 
     ##
@@ -957,6 +967,11 @@
           )
         end
       end
+      # All normalized values should be UTF-8
+      if @normalized_password
+        @normalized_password.force_encoding(Encoding::UTF_8)
+      end
+      @normalized_password
     end
 
     ##
@@ -1022,6 +1037,11 @@
           "#{current_user}"
         end
       end
+      # All normalized values should be UTF-8
+      if @normalized_userinfo
+        @normalized_userinfo.force_encoding(Encoding::UTF_8)
+      end
+      @normalized_userinfo
     end
 
     ##
@@ -1084,6 +1104,9 @@
           EMPTY_STR
         end
       end
+      # All normalized values should be UTF-8
+      @normalized_host.force_encoding(Encoding::UTF_8) if @normalized_host
+      @normalized_host
     end
 
     ##
@@ -1096,14 +1119,6 @@
       end
       @host = new_host ? new_host.to_str : nil
 
-      unreserved = CharacterClasses::UNRESERVED
-      sub_delims = CharacterClasses::SUB_DELIMS
-      if [email protected]? && (@host =~ /[<>{}\/\?\#\@"[[:space:]]]/ ||
-          (@host[/^\[(.*)\]$/, 1] != nil && @host[/^\[(.*)\]$/, 1] !~
-          Regexp.new("^[#{unreserved}#{sub_delims}:]*$")))
-        raise InvalidURIError, "Invalid character in host: '#{@host.to_s}'"
-      end
-
       # Reset dependent values
       remove_instance_variable(:@authority) if defined?(@authority)
       remove_instance_variable(:@normalized_host) if defined?(@normalized_host)
@@ -1145,13 +1160,31 @@
     end
 
     ##
+    # Returns the top-level domain for this host.
+    #
+    # @example
+    #   Addressable::URI.parse("www.example.co.uk").tld # => "co.uk"
+    def tld
+      PublicSuffix.parse(self.host, ignore_private: true).tld
+    end
+
+    ##
+    # Returns the public suffix domain for this host.
+    #
+    # @example
+    #   Addressable::URI.parse("www.example.co.uk").domain # => "example.co.uk"
+    def domain
+      PublicSuffix.domain(self.host, ignore_private: true)
+    end
+
+    ##
     # The authority component for this URI.
     # Combines the user, password, host, and port components.
     #
     # @return [String] The authority component.
     def authority
       self.host && @authority ||= begin
-        authority = ""
+        authority = String.new
         if self.userinfo != nil
           authority << "#{self.userinfo}@"
         end
@@ -1170,7 +1203,7 @@
     def normalized_authority
       return nil unless self.authority
       @normalized_authority ||= begin
-        authority = ""
+        authority = String.new
         if self.normalized_userinfo != nil
           authority << "#{self.normalized_userinfo}@"
         end
@@ -1180,6 +1213,11 @@
         end
         authority
       end
+      # All normalized values should be UTF-8
+      if @normalized_authority
+        @normalized_authority.force_encoding(Encoding::UTF_8)
+      end
+      @normalized_authority
     end
 
     ##
@@ -1411,6 +1449,9 @@
         end
         site_string
       end
+      # All normalized values should be UTF-8
+      @normalized_site.force_encoding(Encoding::UTF_8) if @normalized_site
+      @normalized_site
     end
 
     ##
@@ -1471,6 +1512,9 @@
         end
         result
       end
+      # All normalized values should be UTF-8
+      @normalized_path.force_encoding(Encoding::UTF_8) if @normalized_path
+      @normalized_path
     end
 
     ##
@@ -1489,6 +1533,9 @@
       # Reset dependent values
       remove_instance_variable(:@normalized_path) if defined?(@normalized_path)
       remove_composite_values
+
+      # Ensure we haven't created an invalid URI
+      validate()
     end
 
     ##
@@ -1536,6 +1583,9 @@
         end.join("&")
         component == "" ? nil : component
       end
+      # All normalized values should be UTF-8
+      @normalized_query.force_encoding(Encoding::UTF_8) if @normalized_query
+      @normalized_query
     end
 
     ##
@@ -1727,6 +1777,11 @@
         )
         component == "" ? nil : component
       end
+      # All normalized values should be UTF-8
+      if @normalized_fragment
+        @normalized_fragment.force_encoding(Encoding::UTF_8)
+      end
+      @normalized_fragment
     end
 
     ##
@@ -2246,15 +2301,13 @@
           "Cannot assemble URI string with ambiguous path: '#{self.path}'"
       end
       @uri_string ||= begin
-        uri_string = ""
+        uri_string = String.new
         uri_string << "#{self.scheme}:" if self.scheme != nil
         uri_string << "//#{self.authority}" if self.authority != nil
         uri_string << self.path.to_s
         uri_string << "?#{self.query}" if self.query != nil
         uri_string << "##{self.fragment}" if self.fragment != nil
-        if uri_string.respond_to?(:force_encoding)
-          uri_string.force_encoding(Encoding::UTF_8)
-        end
+        uri_string.force_encoding(Encoding::UTF_8)
         uri_string
       end
     end
@@ -2371,6 +2424,19 @@
         raise InvalidURIError,
           "Cannot have a relative path with an authority set: '#{self.to_s}'"
       end
+      if self.path != nil && !self.path.empty? &&
+          self.path[0..1] == SLASH + SLASH && self.authority == nil
+        raise InvalidURIError,
+          "Cannot have a path with two leading slashes " +
+          "without an authority set: '#{self.to_s}'"
+      end
+      unreserved = CharacterClasses::UNRESERVED
+      sub_delims = CharacterClasses::SUB_DELIMS
+      if !self.host.nil? && (self.host =~ /[<>{}\/\\\?\#\@"[[:space:]]]/ ||
+          (self.host[/^\[(.*)\]$/, 1] != nil && self.host[/^\[(.*)\]$/, 1] !~
+          Regexp.new("^[#{unreserved}#{sub_delims}:]*$")))
+        raise InvalidURIError, "Invalid character in host: '#{self.host.to_s}'"
+      end
       return nil
     end
 
@@ -2384,7 +2450,9 @@
     def replace_self(uri)
       # Reset dependent values
       instance_variables.each do |var|
-        remove_instance_variable(var) if instance_variable_defined?(var)
+        if instance_variable_defined?(var) && var != :@validation_deferred
+          remove_instance_variable(var)
+        end
       end
 
       @scheme = uri.scheme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/addressable/version.rb 
new/lib/addressable/version.rb
--- old/lib/addressable/version.rb      2015-12-07 05:38:26.000000000 +0100
+++ new/lib/addressable/version.rb      2017-03-29 23:14:40.000000000 +0200
@@ -1,6 +1,6 @@
 # encoding:utf-8
 #--
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@
   module Addressable
     module VERSION
       MAJOR = 2
-      MINOR = 4
-      TINY  = 0
+      MINOR = 5
+      TINY  = 1
 
       STRING = [MAJOR, MINOR, TINY].join('.')
     end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2015-12-07 05:38:26.000000000 +0100
+++ new/metadata        2017-03-29 23:14:40.000000000 +0200
@@ -1,16 +1,36 @@
 --- !ruby/object:Gem::Specification
 name: addressable
 version: !ruby/object:Gem::Version
-  version: 2.4.0
+  version: 2.5.1
 platform: ruby
 authors:
 - Bob Aman
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2015-12-07 00:00:00.000000000 Z
+date: 2017-03-29 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
+  name: public_suffix
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '2.0'
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: 2.0.2
+  type: :runtime
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '2.0'
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: 2.0.2
+- !ruby/object:Gem::Dependency
   name: bundler
   requirement: !ruby/object:Gem::Requirement
     requirements:
@@ -39,7 +59,6 @@
 - LICENSE.txt
 - README.md
 - Rakefile
-- addressable.gemspec
 - data/unicode.data
 - lib/addressable.rb
 - lib/addressable/idna.rb
@@ -75,7 +94,7 @@
   requirements:
   - - ">="
     - !ruby/object:Gem::Version
-      version: 1.9.0
+      version: '2.0'
 required_rubygems_version: !ruby/object:Gem::Requirement
   requirements:
   - - ">="
@@ -83,7 +102,7 @@
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.5.0
+rubygems_version: 2.5.1
 signing_key: 
 specification_version: 4
 summary: URI Implementation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/addressable/idna_spec.rb 
new/spec/addressable/idna_spec.rb
--- old/spec/addressable/idna_spec.rb   2015-12-07 05:38:26.000000000 +0100
+++ new/spec/addressable/idna_spec.rb   2017-03-29 23:14:40.000000000 +0200
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -26,6 +26,11 @@
     expect(Addressable::IDNA.to_ascii("www.google.com")).to 
eq("www.google.com")
   end
 
+  LONG = 
'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com'
+  it "should convert '#{LONG}' correctly" do
+    expect(Addressable::IDNA.to_ascii(LONG)).to eq(LONG)
+  end
+
   it "should convert 'www.詹姆斯.com' correctly" do
     expect(Addressable::IDNA.to_ascii(
       "www.詹姆斯.com"
@@ -137,12 +142,23 @@
 end
 
 shared_examples_for "converting from ASCII to unicode" do
+  LONG = 
'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com'
+  it "should convert '#{LONG}' correctly" do
+    expect(Addressable::IDNA.to_unicode(LONG)).to eq(LONG)
+  end
+
+  it "should return the identity conversion when punycode decode fails" do
+    expect(Addressable::IDNA.to_unicode("xn--zckp1cyg1.sblo.jp")).to eq(
+      "xn--zckp1cyg1.sblo.jp")
+  end
+
   it "should return the identity conversion when the ACE prefix has no suffix" 
do
     expect(Addressable::IDNA.to_unicode("xn--...-")).to eq("xn--...-")
   end
 
   it "should convert 'www.google.com' correctly" do
-    expect(Addressable::IDNA.to_unicode("www.google.com")).to 
eq("www.google.com")
+    expect(Addressable::IDNA.to_unicode("www.google.com")).to eq(
+      "www.google.com")
   end
 
   it "should convert 'www.詹姆斯.com' correctly" do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/addressable/net_http_compat_spec.rb 
new/spec/addressable/net_http_compat_spec.rb
--- old/spec/addressable/net_http_compat_spec.rb        2015-12-07 
05:38:26.000000000 +0100
+++ new/spec/addressable/net_http_compat_spec.rb        2017-03-29 
23:14:40.000000000 +0200
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/addressable/rack_mount_compat_spec.rb 
new/spec/addressable/rack_mount_compat_spec.rb
--- old/spec/addressable/rack_mount_compat_spec.rb      2015-12-07 
05:38:26.000000000 +0100
+++ new/spec/addressable/rack_mount_compat_spec.rb      2017-03-29 
23:14:40.000000000 +0200
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/addressable/security_spec.rb 
new/spec/addressable/security_spec.rb
--- old/spec/addressable/security_spec.rb       2015-12-07 05:38:26.000000000 
+0100
+++ new/spec/addressable/security_spec.rb       2017-03-29 23:14:40.000000000 
+0200
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/addressable/template_spec.rb 
new/spec/addressable/template_spec.rb
--- old/spec/addressable/template_spec.rb       2015-12-07 05:38:26.000000000 
+0100
+++ new/spec/addressable/template_spec.rb       2017-03-29 23:14:40.000000000 
+0200
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -91,7 +91,7 @@
     '{hello}' => '1234',
     '{nothing}' => '',
     '{sym}' => 'symbolic',
-    '{decimal}' => '0.1E1'
+    '{decimal}' => RUBY_VERSION < '2.4.0' ? '0.1E1' : '0.1e1'
   }
 end
 
@@ -851,6 +851,7 @@
         expect(match_data.uri).to eq(uri)
         expect(match_data.template).to eq(subject)
         expect(match_data.mapping).to be_empty
+        expect(match_data.inspect).to be_an String
       end
     end
   end
@@ -968,6 +969,24 @@
         )
       end
     end
+    context "partial expand with unicode values" do
+      subject do
+        Addressable::Template.new("http://example.com/{resource}/{query}/";)
+      end
+      it "normalizes unicode by default" do
+        template = subject.partial_expand("query" => "Cafe\u0301")
+        expect(template.pattern).to eq(
+          "http://example.com/{resource}/Caf%C3%A9/";
+        )
+      end
+
+      it "does not normalize unicode when byte semantics requested" do
+        template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, 
false)
+        expect(template.pattern).to eq(
+          "http://example.com/{resource}/Cafe%CC%81/";
+        )
+      end
+    end
   end
   describe "Partial expand with strings" do
     context "partial_expand with two simple values" do
@@ -1012,6 +1031,20 @@
     end
   end
   describe "Expand" do
+    context "expand with unicode values" do
+      subject do
+        Addressable::Template.new("http://example.com/search/{query}/";)
+      end
+      it "normalizes unicode by default" do
+        uri = subject.expand("query" => "Cafe\u0301").to_str
+        expect(uri).to eq("http://example.com/search/Caf%C3%A9/";)
+      end
+
+      it "does not normalize unicode when byte semantics requested" do
+        uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
+        expect(uri).to eq("http://example.com/search/Cafe%CC%81/";)
+      end
+    end
     context "expand with a processor" do
       subject {
         Addressable::Template.new("http://example.com/search/{query}/";)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/addressable/uri_spec.rb 
new/spec/addressable/uri_spec.rb
--- old/spec/addressable/uri_spec.rb    2015-12-07 05:38:26.000000000 +0100
+++ new/spec/addressable/uri_spec.rb    2017-03-29 23:14:40.000000000 +0200
@@ -1,5 +1,5 @@
 # coding: utf-8
-# Copyright (C) 2006-2015 Bob Aman
+# Copyright (C) Bob Aman
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -125,14 +125,6 @@
   end
 end
 
-describe Addressable::URI, "when created with a non-string authority" do
-  it "should raise an error" do
-    expect(lambda do
-      Addressable::URI.new(:authority => :bogus)
-    end).to raise_error(TypeError)
-  end
-end
-
 describe Addressable::URI, "when created with a non-string path" do
   it "should raise an error" do
     expect(lambda do
@@ -409,6 +401,10 @@
     expect(@uri.normalized_host).to eq("example.com")
   end
 
+  it "returns 'com' for #tld" do
+    expect(@uri.tld).to eq("com")
+  end
+
   it "returns 'user:[email protected]:8080' for #authority" do
     expect(@uri.authority).to eq("user:[email protected]:8080")
   end
@@ -1073,6 +1069,30 @@
   end
 end
 
+describe Addressable::URI, "when created with a host with a backslash" do
+  it "should raise an error" do
+    expect(lambda do
+      Addressable::URI.new(:authority => "example\\example")
+    end).to raise_error(Addressable::URI::InvalidURIError)
+  end
+end
+
+describe Addressable::URI, "when created with a host with a slash" do
+  it "should raise an error" do
+    expect(lambda do
+      Addressable::URI.new(:authority => "example/example")
+    end).to raise_error(Addressable::URI::InvalidURIError)
+  end
+end
+
+describe Addressable::URI, "when created with a host with a space" do
+  it "should raise an error" do
+    expect(lambda do
+      Addressable::URI.new(:authority => "example example")
+    end).to raise_error(Addressable::URI::InvalidURIError)
+  end
+end
+
 describe Addressable::URI, "when created with both a userinfo and a user" do
   it "should raise an error" do
     expect(lambda do
@@ -1775,7 +1795,7 @@
   end
 
   it "should have the same hash as http://EXAMPLE.com after assignment" do
-    @uri.host = "EXAMPLE.com"
+    @uri.origin = "http://EXAMPLE.com";
     expect(@uri.hash).to eq(Addressable::URI.parse("http://EXAMPLE.com";).hash)
   end
 
@@ -1783,6 +1803,24 @@
     expect(@uri.hash).not_to 
eq(Addressable::URI.parse("http://EXAMPLE.com";).hash)
   end
 
+  it "should not allow origin assignment without scheme" do
+    expect(lambda do
+      @uri.origin = "example.com"
+    end).to raise_error(Addressable::URI::InvalidURIError)
+  end
+
+  it "should not allow origin assignment without host" do
+    expect(lambda do
+      @uri.origin = "http://";
+    end).to raise_error(Addressable::URI::InvalidURIError)
+  end
+
+  it "should not allow origin assignment with bogus type" do
+    expect(lambda do
+      @uri.origin = :bogus
+    end).to raise_error(TypeError)
+  end
+
   # Section 6.2.3 of RFC 3986
   it "should be equivalent to http://example.com/"; do
     expect(@uri).to eq(Addressable::URI.parse("http://example.com/";))
@@ -2321,6 +2359,80 @@
 end
 
 describe Addressable::URI, "when parsed from " +
+    "'HTTP://EXAMPLE.COM/'" do
+  before do
+    @uri = Addressable::URI.parse("HTTP://EXAMPLE.COM/")
+  end
+
+  it "should be equivalent to http://example.com"; do
+    expect(@uri).to eq(Addressable::URI.parse("http://example.com";))
+  end
+
+  it "should correctly convert to a hash" do
+    expect(@uri.to_hash).to eq({
+      :scheme => "HTTP",
+      :user => nil,
+      :password => nil,
+      :host => "EXAMPLE.COM",
+      :port => nil,
+      :path => "/",
+      :query => nil,
+      :fragment => nil
+    })
+  end
+
+  it "should be identical to its duplicate" do
+    expect(@uri).to eq(@uri.dup)
+  end
+
+  it "should have an origin of 'http://example.com'" do
+    expect(@uri.origin).to eq('http://example.com')
+  end
+
+  it "should have a tld of 'com'" do
+    expect(@uri.tld).to eq('com')
+  end
+end
+
+describe Addressable::URI, "when parsed from " +
+    "'http://www.example.co.uk/'" do
+  before do
+    @uri = Addressable::URI.parse("http://www.example.co.uk/";)
+  end
+
+  it "should have an origin of 'http://www.example.co.uk'" do
+    expect(@uri.origin).to eq('http://www.example.co.uk')
+  end
+
+  it "should have a tld of 'co.uk'" do
+    expect(@uri.tld).to eq('co.uk')
+  end
+
+  it "should have a domain of 'example.co.uk'" do
+    expect(@uri.domain).to eq('example.co.uk')
+  end
+end
+
+describe Addressable::URI, "when parsed from " +
+    "'http://sub_domain.blogspot.com/'" do
+  before do
+    @uri = Addressable::URI.parse("http://sub_domain.blogspot.com/";)
+  end
+
+  it "should have an origin of 'http://sub_domain.blogspot.com'" do
+    expect(@uri.origin).to eq('http://sub_domain.blogspot.com')
+  end
+
+  it "should have a tld of 'com'" do
+    expect(@uri.tld).to eq('com')
+  end
+
+  it "should have a domain of 'blogspot.com'" do
+    expect(@uri.domain).to eq('blogspot.com')
+  end
+end
+
+describe Addressable::URI, "when parsed from " +
     "'http://example.com/~smith/'" do
   before do
     @uri = Addressable::URI.parse("http://example.com/~smith/";)
@@ -2961,6 +3073,23 @@
   end
 end
 
+describe Addressable::URI, "when parsed from " +
+    "'/..//example.com'" do
+  before do
+    @uri = Addressable::URI.parse("/..//example.com")
+  end
+
+  it "should become invalid when normalized" do
+    expect(lambda do
+      @uri.normalize
+    end).to raise_error(Addressable::URI::InvalidURIError, /authority/)
+  end
+
+  it "should have a path of '/..//example.com'" do
+    expect(@uri.path).to eq("/..//example.com")
+  end
+end
+
 describe Addressable::URI, "when parsed from '/a/b/c/./../../g'" do
   before do
     @uri = Addressable::URI.parse("/a/b/c/./../../g")
@@ -5476,7 +5605,7 @@
   it "should raise a TypeError for objects than cannot be converted" do
     expect(lambda do
       Addressable::URI.parse(42)
-    end).to raise_error(TypeError, "Can't convert Fixnum into String.")
+    end).to raise_error(TypeError)
   end
 
   it "should correctly parse heuristically anything with a 'to_str' method" do
@@ -5486,7 +5615,7 @@
   it "should raise a TypeError for objects than cannot be converted" do
     expect(lambda do
       Addressable::URI.heuristic_parse(42)
-    end).to raise_error(TypeError, "Can't convert Fixnum into String.")
+    end).to raise_error(TypeError)
   end
 end
 
@@ -5532,7 +5661,7 @@
   it "should raise a TypeError for objects than cannot be converted" do
     expect(lambda do
       Addressable::URI.form_encode(42)
-    end).to raise_error(TypeError, "Can't convert Fixnum into Array.")
+    end).to raise_error(TypeError)
   end
 end
 
@@ -5600,7 +5729,7 @@
   it "should raise a TypeError for objects than cannot be converted" do
     expect(lambda do
       Addressable::URI.form_unencode(42)
-    end).to raise_error(TypeError, "Can't convert Fixnum into String.")
+    end).to raise_error(TypeError)
   end
 end
 
@@ -5612,7 +5741,7 @@
   it "should raise a TypeError for objects than cannot be converted" do
     expect(lambda do
       Addressable::URI.normalize_component(42)
-    end).to raise_error(TypeError, "Can't convert Fixnum into String.")
+    end).to raise_error(TypeError)
   end
 
   it "should raise a TypeError for objects than cannot be converted" do
@@ -5878,6 +6007,136 @@
   end
 end
 
+describe Addressable::URI, "when given the input " +
+    "'http://prefix\\.example.com/'" do
+  before do
+    @input = "http://prefix\\.example.com/";
+  end
+
+  it "should heuristically parse to 'http://prefix/.example.com/'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.authority).to eq("prefix")
+    expect(@uri.to_s).to eq("http://prefix/.example.com/";)
+  end
+
+  it "should heuristically parse to 'http://prefix/.example.com/' " +
+      "even with a scheme hint of 'ftp'" do
+    @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
+    expect(@uri.to_s).to eq("http://prefix/.example.com/";)
+  end
+end
+
+describe Addressable::URI, "when given the input " +
+    "'http://p:\\/'" do
+  before do
+    @input = "http://p:\\/";
+  end
+
+  it "should heuristically parse to 'http://p//'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.authority).to eq("p")
+    expect(@uri.to_s).to eq("http://p//";)
+  end
+
+  it "should heuristically parse to 'http://p//' " +
+      "even with a scheme hint of 'ftp'" do
+    @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
+    expect(@uri.to_s).to eq("http://p//";)
+  end
+end
+
+describe Addressable::URI, "when given the input " +
+    "'http://p://'" do
+  before do
+    @input = "http://p://";
+  end
+
+  it "should heuristically parse to 'http://p//'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.authority).to eq("p")
+    expect(@uri.to_s).to eq("http://p//";)
+  end
+
+  it "should heuristically parse to 'http://p//' " +
+      "even with a scheme hint of 'ftp'" do
+    @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
+    expect(@uri.to_s).to eq("http://p//";)
+  end
+end
+
+describe Addressable::URI, "when given the input " +
+    "'http://p://p'" do
+  before do
+    @input = "http://p://p";
+  end
+
+  it "should heuristically parse to 'http://p//p'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.authority).to eq("p")
+    expect(@uri.to_s).to eq("http://p//p";)
+  end
+
+  it "should heuristically parse to 'http://p//p' " +
+      "even with a scheme hint of 'ftp'" do
+    @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
+    expect(@uri.to_s).to eq("http://p//p";)
+  end
+end
+
+describe Addressable::URI, "when given the input " +
+    "'http://prefix .example.com/'" do
+  before do
+    @input = "http://prefix .example.com/"
+  end
+
+  # Justification here being that no browser actually tries to resolve this.
+  # They all treat this as a web search.
+  it "should heuristically parse to 'http://prefix%20.example.com/'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.authority).to eq("prefix%20.example.com")
+    expect(@uri.to_s).to eq("http://prefix%20.example.com/";)
+  end
+
+  it "should heuristically parse to 'http://prefix%20.example.com/' " +
+      "even with a scheme hint of 'ftp'" do
+    @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
+    expect(@uri.to_s).to eq("http://prefix%20.example.com/";)
+  end
+end
+
+describe Addressable::URI, "when given the input " +
+    "'  http://www.example.com/  '" do
+  before do
+    @input = "  http://www.example.com/  "
+  end
+
+  it "should heuristically parse to 'http://prefix%20.example.com/'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.scheme).to eq("http")
+    expect(@uri.path).to eq("/")
+    expect(@uri.to_s).to eq("http://www.example.com/";)
+  end
+end
+
+describe Addressable::URI, "when given the input " +
+    "'http://prefix%2F.example.com/'" do
+  before do
+    @input = "http://prefix%2F.example.com/";
+  end
+
+  it "should heuristically parse to 'http://prefix%2F.example.com/'" do
+    @uri = Addressable::URI.heuristic_parse(@input)
+    expect(@uri.authority).to eq("prefix%2F.example.com")
+    expect(@uri.to_s).to eq("http://prefix%2F.example.com/";)
+  end
+
+  it "should heuristically parse to 'http://prefix%2F.example.com/' " +
+      "even with a scheme hint of 'ftp'" do
+    @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'})
+    expect(@uri.to_s).to eq("http://prefix%2F.example.com/";)
+  end
+end
+
 describe Addressable::URI, "when given the input " +
     "'/path/to/resource'" do
   before do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tasks/gem.rake new/tasks/gem.rake
--- old/tasks/gem.rake  2015-12-07 05:38:26.000000000 +0100
+++ new/tasks/gem.rake  2017-03-29 23:14:40.000000000 +0200
@@ -18,8 +18,9 @@
       exit(1)
     end
 
-    s.required_ruby_version = '>= 1.9.0'
+    s.required_ruby_version = '>= 2.0'
 
+    s.add_runtime_dependency 'public_suffix', '~> 2.0', '>= 2.0.2'
     s.add_development_dependency 'bundler', '~> 1.0'
 
     s.require_path = "lib"
@@ -39,15 +40,8 @@
   desc "Generates .gemspec file"
   task :gemspec do
     spec_string = GEM_SPEC.to_ruby
-
-    begin
-      Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
-    rescue
-      abort "unsafe gemspec: #{$!}"
-    else
-      File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file|
-        file.write spec_string
-      end
+    File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file|
+      file.write spec_string
     end
   end
 


Reply via email to