Hello community, here is the log from the commit of package rubygem-addressable for openSUSE:Leap:15.2 checked in at 2020-02-09 15:02:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/rubygem-addressable (Old) and /work/SRC/openSUSE:Leap:15.2/.rubygem-addressable.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-addressable" Sun Feb 9 15:02:23 2020 rev:12 rq:770018 version:2.7.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/rubygem-addressable/rubygem-addressable.changes 2020-01-15 15:58:29.027768477 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.rubygem-addressable.new.26092/rubygem-addressable.changes 2020-02-09 15:02:24.258742447 +0100 @@ -1,0 +2,32 @@ +Mon Sep 2 07:45:01 UTC 2019 - Dan Čermák <dcer...@suse.com> + +- New upstream release 2.7.0 + + * added `:compacted` flag to `normalized_query` + * `heuristic_parse` handles `mailto:` more intuitively + * refactored validation to use a prepended module + * dropped explicit support for JRuby 9.0.5.0 + * compatibility w/ public_suffix 4.x + * performance improvements + +------------------------------------------------------------------- +Wed Aug 7 14:14:46 UTC 2019 - Dan Čermák <dcer...@suse.com> + +- Update public_suffix gem dependency to < 5.0 + +------------------------------------------------------------------- +Fri Feb 8 11:24:50 UTC 2019 - mschnit...@suse.com + +- updated to version 2.6.0 + + * added `tld=` method to allow assignment to the public suffix + * most `heuristic_parse` patterns are now case-insensitive + * `heuristic_parse` handles more `file://` URI variations + * fixes bug in `heuristic_parse` when uri starts with digit + * fixes bug in `request_uri=` with query strings + * fixes template issues with `nil` and `?` operator + * `frozen_string_literal` pragmas added + * minor performance improvements in regexps + * fixes to eliminate warnings + +------------------------------------------------------------------- Old: ---- addressable-2.5.2.gem New: ---- addressable-2.7.0.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-addressable.spec ++++++ --- /var/tmp/diff_new_pack.QoKePC/_old 2020-02-09 15:02:24.606742643 +0100 +++ /var/tmp/diff_new_pack.QoKePC/_new 2020-02-09 15:02:24.610742646 +0100 @@ -1,7 +1,7 @@ # # spec file for package rubygem-addressable # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 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 @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -24,7 +24,7 @@ # Name: rubygem-addressable -Version: 2.5.2 +Version: 2.7.0 Release: 0 %define mod_name addressable %define mod_full_name %{mod_name}-%{version} @@ -34,16 +34,16 @@ BuildRequires: %{rubygem rdoc > 3.10} BuildRequires: ruby-macros >= 5 Url: https://github.com/sporkmonger/addressable -Source: http://rubygems.org/gems/%{mod_full_name}.gem +Source: https://rubygems.org/gems/%{mod_full_name}.gem Source1: gem2rpm.yml Summary: URI Implementation License: Apache-2.0 Group: Development/Languages/Ruby %description -Addressable is a replacement for the URI implementation that is part of -Ruby's standard library. It more closely conforms to the relevant RFCs and -adds support for IRIs and URI templates. +Addressable is an alternative implementation to the URI implementation that is +part of Ruby's standard library. It is flexible, offers heuristic parsing, and +additionally provides extensive support for IRIs and URI templates. %prep ++++++ addressable-2.5.2.gem -> addressable-2.7.0.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2017-08-25 02:00:11.000000000 +0200 +++ new/CHANGELOG.md 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,22 @@ +# Addressable 2.7.0 +- added `:compacted` flag to `normalized_query` +- `heuristic_parse` handles `mailto:` more intuitively +- refactored validation to use a prepended module +- dropped explicit support for JRuby 9.0.5.0 +- compatibility w/ public_suffix 4.x +- performance improvements + +# Addressable 2.6.0 +- added `tld=` method to allow assignment to the public suffix +- most `heuristic_parse` patterns are now case-insensitive +- `heuristic_parse` handles more `file://` URI variations +- fixes bug in `heuristic_parse` when uri starts with digit +- fixes bug in `request_uri=` with query strings +- fixes template issues with `nil` and `?` operator +- `frozen_string_literal` pragmas added +- minor performance improvements in regexps +- fixes to eliminate warnings + # Addressable 2.5.2 - better support for frozen string literals - fixed bug w/ uppercase characters in scheme diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Gemfile new/Gemfile --- old/Gemfile 2017-08-25 02:00:11.000000000 +0200 +++ new/Gemfile 2019-08-31 05:32:55.000000000 +0200 @@ -3,8 +3,8 @@ gemspec group :test do - gem 'rspec', '~> 3.0' - gem 'rspec-its', '~> 1.1' + gem 'rspec', '~> 3.8' + gem 'rspec-its', '~> 1.3' end group :development do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2017-08-25 02:00:11.000000000 +0200 +++ new/README.md 2019-08-31 05:32:55.000000000 +0200 @@ -9,21 +9,21 @@ [![Gem Version](http://img.shields.io/gem/dt/addressable.svg)][gem] [![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] [gem]: https://rubygems.org/gems/addressable [travis]: http://travis-ci.org/sporkmonger/addressable -[gemnasium]: https://gemnasium.com/sporkmonger/addressable [coveralls]: https://coveralls.io/r/sporkmonger/addressable [inch]: http://inch-ci.org/github/sporkmonger/addressable # Description -Addressable is a replacement for the URI implementation that is part of -Ruby's standard library. It more closely conforms to RFC 3986, RFC 3987, and -RFC 6570 (level 4), providing support for IRIs and URI templates. +Addressable is an alternative implementation to the URI implementation +that is part of Ruby's standard library. It is flexible, offers heuristic +parsing, and additionally provides extensive support for IRIs and URI templates. + +Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4). # Reference @@ -58,7 +58,7 @@ require "addressable/template" -template = Addressable::Template.new("http://example.com/{?query*}/") +template = Addressable::Template.new("http://example.com/{?query*}") template.expand({ "query" => { 'foo' => 'bar', @@ -105,7 +105,7 @@ # Semantic Versioning -This project uses sementic versioning. You can (and should) specify your +This project uses [Semantic Versioning](https://semver.org/). You can (and should) specify your dependency using a pessimistic version constraint covering the major and minor values: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Rakefile new/Rakefile --- old/Rakefile 2017-08-25 02:00:11.000000000 +0200 +++ new/Rakefile 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rubygems' require 'rake' @@ -12,9 +14,9 @@ PKG_SUMMARY = "URI Implementation" PKG_DESCRIPTION = <<-TEXT -Addressable is a replacement for the URI implementation that is part of -Ruby's standard library. It more closely conforms to the relevant RFCs and -adds support for IRIs and URI templates. +Addressable is an alternative implementation to the URI implementation that is +part of Ruby's standard library. It is flexible, offers heuristic parsing, and +additionally provides extensive support for IRIs and URI templates. TEXT PKG_FILES = FileList[ 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 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable/idna/native.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # encoding:utf-8 #-- # Copyright (C) Bob Aman 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 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable/idna/pure.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # encoding:utf-8 #-- # Copyright (C) Bob Aman @@ -133,7 +135,7 @@ unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) } return unpacked.pack("U*") end - (class <<self; private :unicode_downcase; end) + private_class_method :unicode_downcase def self.unicode_compose(unpacked) unpacked_result = [] @@ -146,22 +148,19 @@ starter_cc = 256 if starter_cc != 0 for i in 1...length ch = unpacked[i] - cc = lookup_unicode_combining_class(ch) if (starter_cc == 0 && (composite = unicode_compose_pair(starter, ch)) != nil) starter = composite - startercc = lookup_unicode_combining_class(composite) else unpacked_result << starter starter = ch - startercc = cc end end unpacked_result << starter return unpacked_result end - (class <<self; private :unicode_compose; end) + private_class_method :unicode_compose def self.unicode_compose_pair(ch_one, ch_two) if ch_one >= HANGUL_LBASE && ch_one < HANGUL_LBASE + HANGUL_LCOUNT && @@ -215,7 +214,7 @@ return lookup_unicode_composition(p) end - (class <<self; private :unicode_compose_pair; end) + private_class_method :unicode_compose_pair def self.unicode_sort_canonical(unpacked) unpacked = unpacked.dup @@ -239,7 +238,7 @@ end return unpacked end - (class <<self; private :unicode_sort_canonical; end) + private_class_method :unicode_sort_canonical def self.unicode_decompose(unpacked) unpacked_result = [] @@ -260,7 +259,7 @@ end return unpacked_result end - (class <<self; private :unicode_decompose; end) + private_class_method :unicode_decompose def self.unicode_decompose_hangul(codepoint) sindex = codepoint - HANGUL_SBASE; @@ -277,7 +276,7 @@ end return l, v, t end - (class <<self; private :unicode_decompose_hangul; end) + private_class_method :unicode_decompose_hangul def self.lookup_unicode_combining_class(codepoint) codepoint_data = UNICODE_DATA[codepoint] @@ -285,14 +284,14 @@ (codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) : 0) end - (class <<self; private :lookup_unicode_combining_class; end) + private_class_method :lookup_unicode_combining_class def self.lookup_unicode_compatibility(codepoint) codepoint_data = UNICODE_DATA[codepoint] (codepoint_data ? codepoint_data[UNICODE_DATA_COMPATIBILITY] : nil) end - (class <<self; private :lookup_unicode_compatibility; end) + private_class_method :lookup_unicode_compatibility def self.lookup_unicode_lowercase(codepoint) codepoint_data = UNICODE_DATA[codepoint] @@ -300,12 +299,12 @@ (codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) : codepoint) end - (class <<self; private :lookup_unicode_lowercase; end) + private_class_method :lookup_unicode_lowercase def self.lookup_unicode_composition(unpacked) return COMPOSITION_TABLE[unpacked] end - (class <<self; private :lookup_unicode_composition; end) + private_class_method :lookup_unicode_composition HANGUL_SBASE = 0xac00 HANGUL_LBASE = 0x1100 @@ -342,7 +341,7 @@ end COMPOSITION_TABLE = {} - for codepoint, data in UNICODE_DATA + UNICODE_DATA.each do |codepoint, data| canonical = data[UNICODE_DATA_CANONICAL] exclusion = data[UNICODE_DATA_EXCLUSION] @@ -501,7 +500,7 @@ output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "") end - (class <<self; private :punycode_encode; end) + private_class_method :punycode_encode def self.punycode_decode(punycode) input = [] @@ -623,22 +622,22 @@ output.pack("U*") end - (class <<self; private :punycode_decode; end) + private_class_method :punycode_decode def self.punycode_basic?(codepoint) codepoint < 0x80 end - (class <<self; private :punycode_basic?; end) + private_class_method :punycode_basic? def self.punycode_delimiter?(codepoint) codepoint == PUNYCODE_DELIMITER end - (class <<self; private :punycode_delimiter?; end) + private_class_method :punycode_delimiter? def self.punycode_encode_digit(d) d + 22 + 75 * ((d < 26) ? 1 : 0) end - (class <<self; private :punycode_encode_digit; end) + private_class_method :punycode_encode_digit # Returns the numeric value of a basic codepoint # (for use in representing integers) in the range 0 to @@ -654,7 +653,7 @@ PUNYCODE_BASE end end - (class <<self; private :punycode_decode_digit; end) + private_class_method :punycode_decode_digit # Bias adaptation method def self.punycode_adapt(delta, numpoints, firsttime) @@ -671,7 +670,7 @@ k + (difference + 1) * delta / (delta + PUNYCODE_SKEW) end - (class <<self; private :punycode_adapt; end) + private_class_method :punycode_adapt end # :startdoc: 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 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable/idna.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # encoding:utf-8 #-- # Copyright (C) Bob Aman 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 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable/template.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # encoding:utf-8 #-- # Copyright (C) Bob Aman @@ -728,54 +730,32 @@ normalize_values = true) _, operator, varlist = *capture.match(EXPRESSION) - vars = varlist.split(',') + vars = varlist.split(",") - if '?' == operator + if operator == "?" # partial expansion of form style query variables sometimes requires a # slight reordering of the variables to produce a valid url. first_to_expand = vars.find { |varspec| _, name, _ = *varspec.match(VARSPEC) - mapping.key? name + mapping.key?(name) && !mapping[name].nil? } vars = [first_to_expand] + vars.reject {|varspec| varspec == first_to_expand} if first_to_expand end - vars - .zip(operator_sequence(operator).take(vars.length)) - .reduce("".dup) do |acc, (varspec, op)| + vars. + inject("".dup) do |acc, varspec| _, name, _ = *varspec.match(VARSPEC) - - acc << if mapping.key? name - transform_capture(mapping, "{#{op}#{varspec}}", - processor, normalize_values) - else - "{#{op}#{varspec}}" - end - end - end - - ## - # Creates a lazy Enumerator of the operators that should be used to expand - # variables in a varlist starting with `operator`. For example, an operator - # `"?"` results in the sequence `"?","&","&"...` - # - # @param [String] operator from which to generate a sequence - # - # @return [Enumerator] sequence of operators - def operator_sequence(operator) - rest_operator = if "?" == operator - "&" - else - operator - end - head_operator = operator - - Enumerator.new do |y| - y << head_operator.to_s - while true - y << rest_operator.to_s - end + next_val = if mapping.key? name + transform_capture(mapping, "{#{operator}#{varspec}}", + processor, normalize_values) + else + "{#{operator}#{varspec}}" + end + # If we've already expanded at least one '?' operator with non-empty + # value, change to '&' + operator = "&" if (operator == "?") && (next_val != "") + acc << next_val end end 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 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable/uri.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # encoding:utf-8 #-- # Copyright (C) Bob Aman @@ -122,9 +124,9 @@ user = userinfo.strip[/^([^:]*):?/, 1] password = userinfo.strip[/:(.*)$/, 1] end - host = authority.gsub( + host = authority.sub( /^([^\[\]]*)@/, EMPTY_STR - ).gsub( + ).sub( /:([^:@\[\]]*?)$/, EMPTY_STR ) port = authority[/:([^:@\[\]]*?)$/, 1] @@ -182,26 +184,33 @@ :scheme => "http" }.merge(hints) case uri - when /^http:\/+/ - uri.gsub!(/^http:\/+/, "http://") - when /^https:\/+/ - uri.gsub!(/^https:\/+/, "https://") - when /^feed:\/+http:\/+/ - uri.gsub!(/^feed:\/+http:\/+/, "feed:http://") - when /^feed:\/+/ - uri.gsub!(/^feed:\/+/, "feed://") - when /^file:\/+/ - uri.gsub!(/^file:\/+/, "file:///") + when /^http:\//i + uri.sub!(/^http:\/+/i, "http://") + when /^https:\//i + uri.sub!(/^https:\/+/i, "https://") + when /^feed:\/+http:\//i + uri.sub!(/^feed:\/+http:\/+/i, "feed:http://") + when /^feed:\//i + uri.sub!(/^feed:\/+/i, "feed://") + when %r[^file:/{4}]i + uri.sub!(%r[^file:/+]i, "file:////") + when %r[^file://localhost/]i + uri.sub!(%r[^file://localhost/+]i, "file:///") + when %r[^file:/+]i + uri.sub!(%r[^file:/+]i, "file:///") when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ - uri.gsub!(/^/, hints[:scheme] + "://") + uri.sub!(/^/, hints[:scheme] + "://") + when /\A\d+\..*:\d+\z/ + uri = "#{hints[:scheme]}://#{uri}" end match = uri.match(URIREGEX) fragments = match.captures authority = fragments[3] if authority && authority.length > 0 - new_authority = authority.gsub(/\\/, '/').gsub(/ /, '%20') + new_authority = authority.tr("\\", "/").gsub(" ", "%20") # NOTE: We want offset 4, not 3! offset = match.offset(4) + uri = uri.dup uri[offset[0]...offset[1]] = new_authority end parsed = self.parse(uri) @@ -209,10 +218,11 @@ parsed = self.parse(hints[:scheme] + "://" + uri) end if parsed.path.include?(".") - new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1] - if new_host + if parsed.path[/\b@\b/] + parsed.scheme = "mailto" unless parsed.scheme + elsif new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1] parsed.defer_validation do - new_path = parsed.path.gsub( + new_path = parsed.path.sub( Regexp.new("^" + Regexp.escape(new_host)), EMPTY_STR) parsed.host = new_host parsed.path = new_path @@ -263,24 +273,24 @@ # Otherwise, convert to a String path = path.to_str.strip - path.gsub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/ + path.sub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/ path = SLASH + path if path =~ /^([a-zA-Z])[\|:]/ uri = self.parse(path) if uri.scheme == nil # Adjust windows-style uris - uri.path.gsub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do + uri.path.sub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do "/#{$1.downcase}:/" end - uri.path.gsub!(/\\/, SLASH) + uri.path.tr!("\\", SLASH) if File.exist?(uri.path) && File.stat(uri.path).directory? - uri.path.gsub!(/\/$/, EMPTY_STR) + uri.path.chomp!(SLASH) uri.path = uri.path + '/' end # If the path is absolute, set the scheme and host. - if uri.path =~ /^\// + if uri.path.start_with?(SLASH) uri.scheme = "file" uri.host = EMPTY_STR end @@ -318,6 +328,21 @@ end ## + # Tables used to optimize encoding operations in `self.encode_component` + # and `self.normalize_component` + SEQUENCE_ENCODING_TABLE = Hash.new do |hash, sequence| + hash[sequence] = sequence.unpack("C*").map do |c| + format("%02x", c) + end.join + end + + SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = Hash.new do |hash, sequence| + hash[sequence] = sequence.unpack("C*").map do |c| + format("%%%02X", c) + end.join + end + + ## # Percent encodes a URI component. # # @param [String, #to_str] component The URI component to encode. @@ -383,12 +408,14 @@ 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 + SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[sequence] end if upcase_encoded.length > 0 - component = component.gsub(/%(#{upcase_encoded.chars.map do |char| - char.unpack('C*').map { |c| '%02x' % c }.join - end.join('|')})/i) { |s| s.upcase } + upcase_encoded_chars = upcase_encoded.chars.map do |char| + SEQUENCE_ENCODING_TABLE[char] + end + component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/, + &:upcase) end return component end @@ -522,7 +549,7 @@ character_class = "#{character_class}%" unless character_class.include?('%') "|%(?!#{leave_encoded.chars.map do |char| - seq = char.unpack('C*').map { |c| '%02x' % c }.join + seq = SEQUENCE_ENCODING_TABLE[char] [seq.upcase, seq.downcase] end.flatten.join('|')})" end @@ -1163,16 +1190,25 @@ # Returns the top-level domain for this host. # # @example - # Addressable::URI.parse("www.example.co.uk").tld # => "co.uk" + # Addressable::URI.parse("http://www.example.co.uk").tld # => "co.uk" def tld PublicSuffix.parse(self.host, ignore_private: true).tld end ## + # Sets the top-level domain for this URI. + # + # @param [String, #to_str] new_tld The new top-level domain. + def tld=(new_tld) + replaced_tld = host.sub(/#{tld}\z/, new_tld) + self.host = PublicSuffix::Domain.new(replaced_tld).to_s + end + + ## # Returns the public suffix domain for this host. # # @example - # Addressable::URI.parse("www.example.co.uk").domain # => "example.co.uk" + # Addressable::URI.parse("http://www.example.co.uk").domain # => "example.co.uk" def domain PublicSuffix.domain(self.host, ignore_private: true) end @@ -1235,9 +1271,9 @@ new_user = new_userinfo.strip[/^([^:]*):?/, 1] new_password = new_userinfo.strip[/:(.*)$/, 1] end - new_host = new_authority.gsub( + new_host = new_authority.sub( /^([^\[\]]*)@/, EMPTY_STR - ).gsub( + ).sub( /:([^:@\[\]]*?)$/, EMPTY_STR ) new_port = @@ -1544,7 +1580,7 @@ # @return [String] The path's basename. def basename # Path cannot be nil - return File.basename(self.path).gsub(/;[^\/]*$/, EMPTY_STR) + return File.basename(self.path).sub(/;[^\/]*$/, EMPTY_STR) end ## @@ -1577,6 +1613,7 @@ # Make sure possible key-value pair delimiters are escaped. modified_query_class.sub!("\\&", "").sub!("\\;", "") pairs = (self.query || "").split("&", -1) + pairs.delete_if(&:empty?) if flags.include?(:compacted) pairs.sort! if flags.include?(:sorted) component = pairs.map do |pair| Addressable::URI.normalize_component(pair, modified_query_class, "+") @@ -1642,7 +1679,7 @@ # Treating '+' as a space was just an unbelievably bad idea. # There was nothing wrong with '%20'! # If it ain't broke, don't fix it! - pair[1] = URI.unencode_component(pair[1].to_str.gsub(/\+/, " ")) + pair[1] = URI.unencode_component(pair[1].to_str.tr("+", " ")) end if return_type == Hash accu[pair[0]] = pair[1] @@ -1744,7 +1781,7 @@ "Cannot set an HTTP request URI for a non-HTTP URI." end new_request_uri = new_request_uri.to_str - path_component = new_request_uri[/^([^\?]*)\?(?:.*)$/, 1] + path_component = new_request_uri[/^([^\?]*)\??(?:.*)$/, 1] query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1] path_component = path_component.to_s path_component = (!path_component.empty? ? path_component : SLASH) @@ -1899,8 +1936,8 @@ # Section 5.2.3 of RFC 3986 # # Removes the right-most path segment from the base path. - if base_path =~ /\// - base_path.gsub!(/\/[^\/]+$/, SLASH) + if base_path.include?(SLASH) + base_path.sub!(/\/[^\/]+$/, SLASH) else base_path = EMPTY_STR end @@ -2349,10 +2386,10 @@ # # @param [Proc] block # A set of operations to perform on a given URI. - def defer_validation(&block) - raise LocalJumpError, "No block given." unless block + def defer_validation + raise LocalJumpError, "No block given." unless block_given? @validation_deferred = true - block.call() + yield @validation_deferred = false validate return nil 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 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable/version.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # encoding:utf-8 #-- # Copyright (C) Bob Aman @@ -21,8 +23,8 @@ module Addressable module VERSION MAJOR = 2 - MINOR = 5 - TINY = 2 + MINOR = 7 + TINY = 0 STRING = [MAJOR, MINOR, TINY].join('.') end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/addressable.rb new/lib/addressable.rb --- old/lib/addressable.rb 2017-08-25 02:00:11.000000000 +0200 +++ new/lib/addressable.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,2 +1,4 @@ +# frozen_string_literal: true + require 'addressable/uri' require 'addressable/template' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2017-08-25 02:00:11.000000000 +0200 +++ new/metadata 2019-08-31 05:32:55.000000000 +0200 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: addressable version: !ruby/object:Gem::Version - version: 2.5.2 + version: 2.7.0 platform: ruby authors: - Bob Aman autorequire: bindir: bin cert_chain: [] -date: 2017-08-25 00:00:00.000000000 Z +date: 2019-08-31 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: public_suffix @@ -19,7 +19,7 @@ version: 2.0.2 - - "<" - !ruby/object:Gem::Version - version: '4.0' + version: '5.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement @@ -29,25 +29,31 @@ version: 2.0.2 - - "<" - !ruby/object:Gem::Version - version: '4.0' + version: '5.0' - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - - "~>" + - - ">=" - !ruby/object:Gem::Version version: '1.0' + - - "<" + - !ruby/object:Gem::Version + version: '3.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - "~>" + - - ">=" - !ruby/object:Gem::Version version: '1.0' + - - "<" + - !ruby/object:Gem::Version + version: '3.0' description: | - Addressable is a replacement for the URI implementation that is part of - Ruby's standard library. It more closely conforms to the relevant RFCs and - adds support for IRIs and URI templates. + Addressable is an alternative implementation to the URI implementation that is + part of Ruby's standard library. It is flexible, offers heuristic parsing, and + additionally provides extensive support for IRIs and URI templates. email: b...@sporkmonger.com executables: [] extensions: [] @@ -102,7 +108,7 @@ version: '0' requirements: [] rubyforge_project: -rubygems_version: 2.5.1 +rubygems_version: 2.5.2.3 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 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/addressable/idna_spec.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # coding: utf-8 # Copyright (C) Bob Aman # @@ -26,9 +28,9 @@ 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) + 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 @@ -148,9 +150,9 @@ 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) + 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 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 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/addressable/net_http_compat_spec.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # coding: utf-8 # Copyright (C) Bob Aman # 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 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/addressable/rack_mount_compat_spec.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # coding: utf-8 # Copyright (C) Bob Aman # 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 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/addressable/security_spec.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # coding: utf-8 # Copyright (C) Bob Aman # 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 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/addressable/template_spec.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # coding: utf-8 # Copyright (C) Bob Aman # @@ -82,7 +84,7 @@ :hello => 1234, :nothing => nil, :sym => :symbolic, - :decimal => BigDecimal.new('1') + :decimal => BigDecimal('1') } } @@ -949,6 +951,36 @@ ) end end + context "issue #307 - partial_expand form query with nil params" do + subject do + Addressable::Template.new("http://example.com/{?one,two,three}/") + end + it "builds a new pattern with two=nil" do + expect(subject.partial_expand(two: nil).pattern).to eq( + "http://example.com/{?one}{&three}/" + ) + end + it "builds a new pattern with one=nil and two=nil" do + expect(subject.partial_expand(one: nil, two: nil).pattern).to eq( + "http://example.com/{?three}/" + ) + end + it "builds a new pattern with one=1 and two=nil" do + expect(subject.partial_expand(one: 1, two: nil).pattern).to eq( + "http://example.com/?one=1{&three}/" + ) + end + it "builds a new pattern with one=nil and two=2" do + expect(subject.partial_expand(one: nil, two: 2).pattern).to eq( + "http://example.com/?two=2{&three}/" + ) + end + it "builds a new pattern with one=nil" do + expect(subject.partial_expand(one: nil).pattern).to eq( + "http://example.com/{?two}{&three}/" + ) + end + end context "partial_expand with query string" do subject { Addressable::Template.new("http://example.com/{?two,one}/") 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 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/addressable/uri_spec.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # coding: utf-8 # Copyright (C) Bob Aman # @@ -1985,6 +1987,20 @@ end it "should have the correct request URI after assignment" do + @uri.request_uri = "/pub/WWW/TheProject.html?" + expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html?") + expect(@uri.path).to eq("/pub/WWW/TheProject.html") + expect(@uri.query).to eq("") + end + + it "should have the correct request URI after assignment" do + @uri.request_uri = "/some/where/else.html" + expect(@uri.request_uri).to eq("/some/where/else.html") + expect(@uri.path).to eq("/some/where/else.html") + expect(@uri.query).to eq(nil) + end + + it "should have the correct request URI after assignment" do @uri.request_uri = "/some/where/else.html?query?string" expect(@uri.request_uri).to eq("/some/where/else.html?query?string") expect(@uri.path).to eq("/some/where/else.html") @@ -3928,7 +3944,7 @@ it "should raise an error if assigning a bogus object to the hostname" do expect(lambda do @uri.hostname = Object.new - end).to raise_error + end).to raise_error(TypeError) end it "should have the correct port after assignment" do @@ -4287,6 +4303,26 @@ end end +describe Addressable::URI, "when parsed from 'http://example/?b=1&a=2&c=3'" do + before do + @uri = Addressable::URI.parse("http://example/?b=1&a=2&c=3") + end + + it "should have a sorted normalized query of 'a=2&b=1&c=3'" do + expect(@uri.normalized_query(:sorted)).to eq("a=2&b=1&c=3") + end +end + +describe Addressable::URI, "when parsed from 'http://example/?&a&&c&'" do + before do + @uri = Addressable::URI.parse("http://example/?&a&&c&") + end + + it "should have a compacted normalized query of 'a&c'" do + expect(@uri.normalized_query(:compacted)).to eq("a&c") + end +end + describe Addressable::URI, "when parsed from " + "'http://example.com/sound%2bvision'" do before do @@ -4401,7 +4437,7 @@ expect(lambda do # This would create an invalid URI @uri.authority = nil - end).to raise_error + end).to raise_error(Addressable::URI::InvalidURIError) end end @@ -4804,7 +4840,7 @@ it "should raise an error for invalid return type values" do expect(lambda do - @uri.query_values(Fixnum) + @uri.query_values(Integer) end).to raise_error(ArgumentError) end @@ -5490,6 +5526,31 @@ end end +describe Addressable::URI, "when given the tld " do + it "'uk' should have a tld of 'uk'" do + uri = Addressable::URI.parse("http://example.com") + uri.tld = "uk" + + expect(uri.tld).to eq("uk") + end + + context "which " do + let (:uri) { Addressable::URI.parse("http://www.comrade.net/path/to/source/") } + + it "contains a subdomain" do + uri.tld = "co.uk" + + expect(uri.to_s).to eq("http://www.comrade.co.uk/path/to/source/") + end + + it "is part of the domain" do + uri.tld = "com" + + expect(uri.to_s).to eq("http://www.comrade.com/path/to/source/") + end + end +end + describe Addressable::URI, "when given the path " + "'c:\\windows\\My Documents 100%20\\foo.txt'" do before do @@ -6227,6 +6288,18 @@ end end +describe Addressable::URI, "when given the input which "\ + "start with digits and has specified port" do + before do + @input = "7777.example.org:8089" + end + + it "should heuristically parse to 'http://7777.example.org:8089'" do + uri = Addressable::URI.heuristic_parse(@input) + expect(uri.to_s).to eq("http://7777.example.org:8089") + end +end + describe Addressable::URI, "when given the input " + "'feed:///example.com'" do before do @@ -6240,6 +6313,18 @@ end describe Addressable::URI, "when given the input " + + "'file://localhost/path/to/resource/'" do + before do + @input = "file://localhost/path/to/resource/" + end + + it "should heuristically parse to 'file:///path/to/resource/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("file:///path/to/resource/") + end +end + +describe Addressable::URI, "when given the input " + "'file://path/to/resource/'" do before do @input = "file://path/to/resource/" @@ -6252,6 +6337,18 @@ end describe Addressable::URI, "when given the input " + + "'file://///path/to/resource/'" do + before do + @input = "file:///////path/to/resource/" + end + + it "should heuristically parse to 'file:////path/to/resource/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("file:////path/to/resource/") + end +end + +describe Addressable::URI, "when given the input " + "'feed://http://example.com'" do before do @input = "feed://http://example.com" @@ -6275,6 +6372,44 @@ end end +describe Addressable::URI, "when given the input: 'u...@domain.com'" do + before do + @input = "u...@domain.com" + end + + context "for heuristic parse" do + it "should remain 'mailto:u...@domain.com'" do + uri = Addressable::URI.heuristic_parse("mailto:#{@input}") + expect(uri.to_s).to eq("mailto:u...@domain.com") + end + + it "should have a scheme of 'mailto'" do + uri = Addressable::URI.heuristic_parse(@input) + expect(uri.to_s).to eq("mailto:u...@domain.com") + expect(uri.scheme).to eq("mailto") + end + + it "should remain 'acct:u...@domain.com'" do + uri = Addressable::URI.heuristic_parse("acct:#{@input}") + expect(uri.to_s).to eq("acct:u...@domain.com") + end + + context "HTTP" do + before do + @uri = Addressable::URI.heuristic_parse("http://#{@input}/") + end + + it "should remain 'http://u...@domain.com/'" do + expect(@uri.to_s).to eq("http://u...@domain.com/") + end + + it "should have the username 'user' for HTTP basic authentication" do + expect(@uri.user).to eq("user") + end + end + end +end + describe Addressable::URI, "when assigning query values" do before do @uri = Addressable::URI.new diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spec/spec_helper.rb new/spec/spec_helper.rb --- old/spec/spec_helper.rb 2017-08-25 02:00:11.000000000 +0200 +++ new/spec/spec_helper.rb 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'bundler/setup' require 'rspec/its' @@ -18,4 +20,5 @@ RSpec.configure do |config| config.warnings = true + config.filter_run_when_matching :focus end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/clobber.rake new/tasks/clobber.rake --- old/tasks/clobber.rake 2017-08-25 02:00:11.000000000 +0200 +++ new/tasks/clobber.rake 2019-08-31 05:32:55.000000000 +0200 @@ -1,2 +1,4 @@ +# frozen_string_literal: true + desc "Remove all build products" task "clobber" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/gem.rake new/tasks/gem.rake --- old/tasks/gem.rake 2017-08-25 02:00:11.000000000 +0200 +++ new/tasks/gem.rake 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rubygems/package_task" namespace :gem do @@ -18,10 +20,10 @@ exit(1) end - s.required_ruby_version = '>= 2.0' + s.required_ruby_version = ">= 2.0" - s.add_runtime_dependency 'public_suffix', '>= 2.0.2', '< 4.0' - s.add_development_dependency 'bundler', '~> 1.0' + s.add_runtime_dependency "public_suffix", ">= 2.0.2", "< 5.0" + s.add_development_dependency "bundler", ">= 1.0", "< 3.0" s.require_path = "lib" @@ -40,7 +42,7 @@ desc "Generates .gemspec file" task :gemspec do spec_string = GEM_SPEC.to_ruby - File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file| + File.open("#{GEM_SPEC.name}.gemspec", "w") do |file| file.write spec_string end end @@ -70,9 +72,9 @@ desc "Reinstall the gem" task :reinstall => [:uninstall, :install] - desc 'Package for release' + desc "Package for release" task :release => ["gem:package", "gem:gemspec"] do |t| - v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z' + v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z" abort "Versions don't match #{v} vs #{PROJ.version}" if v != PKG_VERSION pkg = "pkg/#{GEM_SPEC.full_name}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/git.rake new/tasks/git.rake --- old/tasks/git.rake 2017-08-25 02:00:11.000000000 +0200 +++ new/tasks/git.rake 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + namespace :git do namespace :tag do desc "List tags from the Git repository" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/metrics.rake new/tasks/metrics.rake --- old/tasks/metrics.rake 2017-08-25 02:00:11.000000000 +0200 +++ new/tasks/metrics.rake 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + namespace :metrics do task :lines do lines, codelines, total_lines, total_codelines = 0, 0, 0, 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/rspec.rake new/tasks/rspec.rake --- old/tasks/rspec.rake 2017-08-25 02:00:11.000000000 +0200 +++ new/tasks/rspec.rake 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rspec/core/rake_task" namespace :spec do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tasks/yard.rake new/tasks/yard.rake --- old/tasks/yard.rake 2017-08-25 02:00:11.000000000 +0200 +++ new/tasks/yard.rake 2019-08-31 05:32:55.000000000 +0200 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rake" begin