Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package rubygem-addressable for
openSUSE:Factory checked in at 2023-06-14 16:28:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-addressable (Old)
and /work/SRC/openSUSE:Factory/.rubygem-addressable.new.15902 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-addressable"
Wed Jun 14 16:28:55 2023 rev:23 rq:1092614 version:2.8.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-addressable/rubygem-addressable.changes
2022-08-28 13:12:10.864523052 +0200
+++
/work/SRC/openSUSE:Factory/.rubygem-addressable.new.15902/rubygem-addressable.changes
2023-06-14 16:29:17.038447786 +0200
@@ -1,0 +2,16 @@
+Sat Jun 10 14:08:24 UTC 2023 - Andrea Manzini <[email protected]>
+
+- updated to version 2.8.4
+ * Restore Addressable::IDNA.unicode_normalize_kc as a deprecated method
+
+- updated to version 2.8.3
+ * Fix template expand level 2 hash support for non-string objects
+
+- updated to version 2.8.2
+ * Improve cache hits and JIT friendliness
+ * Improve code style and test coverage
+ * Ensure reset of deferred validation
+ * Resolve normalization differences between IDNA::Native and IDNA::Pure
+ * Remove redundant colon in Addressable::URI::CharacterClasses::AUTHORITY
+
+-------------------------------------------------------------------
Old:
----
addressable-2.8.1.gem
New:
----
addressable-2.8.4.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-addressable.spec ++++++
--- /var/tmp/diff_new_pack.0mSdrJ/_old 2023-06-14 16:29:17.838452704 +0200
+++ /var/tmp/diff_new_pack.0mSdrJ/_new 2023-06-14 16:29:17.846452753 +0200
@@ -1,7 +1,7 @@
#
# spec file for package rubygem-addressable
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
#
Name: rubygem-addressable
-Version: 2.8.1
+Version: 2.8.4
Release: 0
%define mod_name addressable
%define mod_full_name %{mod_name}-%{version}
++++++ addressable-2.8.1.gem -> addressable-2.8.4.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md 2022-08-19 12:48:27.000000000 +0200
+++ new/CHANGELOG.md 2023-04-09 17:02:36.000000000 +0200
@@ -1,13 +1,33 @@
+# Addressable 2.8.4
+- Restore `Addressable::IDNA.unicode_normalize_kc` as a deprecated method
([#504])
+
+[#504]: https://github.com/sporkmonger/addressable/pull/504
+
+# Addressable 2.8.3
+- Fix template expand level 2 hash support for non-string objects ([#499],
[#498])
+
+[#499]: https://github.com/sporkmonger/addressable/pull/499
+[#498]: https://github.com/sporkmonger/addressable/pull/498
+
+# Addressable 2.8.2
+- Improve cache hits and JIT friendliness
([#486](https://github.com/sporkmonger/addressable/pull/486))
+- Improve code style and test coverage
([#482](https://github.com/sporkmonger/addressable/pull/482))
+- Ensure reset of deferred validation
([#481](https://github.com/sporkmonger/addressable/pull/481))
+- Resolve normalization differences between `IDNA::Native` and `IDNA::Pure`
([#408](https://github.com/sporkmonger/addressable/issues/408), [#492])
+- Remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY`
regex ([#438](https://github.com/sporkmonger/addressable/pull/438))
(accidentally reverted by [#449] merge but [added
back](https://github.com/sporkmonger/addressable/pull/492#discussion_r1105125280)
in [#492])
+
+[#492]: https://github.com/sporkmonger/addressable/pull/492
+
# Addressable 2.8.1
- refactor `Addressable::URI.normalize_path` to address linter offenses
([#430](https://github.com/sporkmonger/addressable/pull/430))
-- remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY`
regex ([#438](https://github.com/sporkmonger/addressable/pull/438))
- update gemspec to reflect supported Ruby versions ([#466], [#464], [#463])
- compatibility w/ public_suffix 5.x ([#466], [#465], [#460])
- fixes "invalid byte sequence in UTF-8" exception when unencoding URLs
containing non UTF-8 characters
([#459](https://github.com/sporkmonger/addressable/pull/459))
-- `Ractor` compatibility
([#449](https://github.com/sporkmonger/addressable/pull/449))
+- `Ractor` compatibility ([#449])
- use the whole string instead of a single line for template match
([#431](https://github.com/sporkmonger/addressable/pull/431))
- force UTF-8 encoding only if needed
([#341](https://github.com/sporkmonger/addressable/pull/341))
+[#449]: https://github.com/sporkmonger/addressable/pull/449
[#460]: https://github.com/sporkmonger/addressable/pull/460
[#463]: https://github.com/sporkmonger/addressable/pull/463
[#464]: https://github.com/sporkmonger/addressable/pull/464
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile 2022-08-19 12:48:27.000000000 +0200
+++ new/Rakefile 2023-04-09 17:02:36.000000000 +0200
@@ -24,7 +24,8 @@
"tasks/**/*",
"[A-Z]*", "Rakefile"
].exclude(/pkg/).exclude(/database\.yml/).
- exclude(/Gemfile\.lock/).exclude(/[_\.]git$/)
+ exclude(/Gemfile\.lock/).exclude(/[_\.]git$/).
+ exclude(/coverage/)
task :default => "spec"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/addressable.gemspec new/addressable.gemspec
--- old/addressable.gemspec 1970-01-01 01:00:00.000000000 +0100
+++ new/addressable.gemspec 2023-04-09 17:02:36.000000000 +0200
@@ -0,0 +1,28 @@
+# -*- encoding: utf-8 -*-
+# stub: addressable 2.8.4 ruby lib
+
+Gem::Specification.new do |s|
+ s.name = "addressable".freeze
+ s.version = "2.8.4"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if
s.respond_to? :required_rubygems_version=
+ s.metadata = { "changelog_uri" =>
"https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md" } if
s.respond_to? :metadata=
+ s.require_paths = ["lib".freeze]
+ s.authors = ["Bob Aman".freeze]
+ s.date = "2023-04-09"
+ s.description = "Addressable is an alternative implementation to the URI
implementation that is\npart of Ruby's standard library. It is flexible, offers
heuristic parsing, and\nadditionally provides extensive support for IRIs and
URI templates.\n".freeze
+ s.email = "[email protected]".freeze
+ s.extra_rdoc_files = ["README.md".freeze]
+ s.files = ["CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE.txt".freeze,
"README.md".freeze, "Rakefile".freeze, "addressable.gemspec".freeze,
"data/unicode.data".freeze, "lib/addressable.rb".freeze,
"lib/addressable/idna.rb".freeze, "lib/addressable/idna/native.rb".freeze,
"lib/addressable/idna/pure.rb".freeze, "lib/addressable/template.rb".freeze,
"lib/addressable/uri.rb".freeze, "lib/addressable/version.rb".freeze,
"spec/addressable/idna_spec.rb".freeze,
"spec/addressable/net_http_compat_spec.rb".freeze,
"spec/addressable/security_spec.rb".freeze,
"spec/addressable/template_spec.rb".freeze,
"spec/addressable/uri_spec.rb".freeze, "spec/spec_helper.rb".freeze,
"tasks/clobber.rake".freeze, "tasks/gem.rake".freeze, "tasks/git.rake".freeze,
"tasks/metrics.rake".freeze, "tasks/profile.rake".freeze,
"tasks/rspec.rake".freeze, "tasks/yard.rake".freeze]
+ s.homepage = "https://github.com/sporkmonger/addressable".freeze
+ s.licenses = ["Apache-2.0".freeze]
+ s.rdoc_options = ["--main".freeze, "README.md".freeze]
+ s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze)
+ s.rubygems_version = "3.4.10".freeze
+ s.summary = "URI Implementation".freeze
+
+ s.specification_version = 4
+
+ s.add_runtime_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 6.0"])
+ s.add_development_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
+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 2022-08-19 12:48:27.000000000 +0200
+++ new/lib/addressable/idna/native.rb 2023-04-09 17:02:36.000000000 +0200
@@ -29,8 +29,14 @@
IDN::Punycode.decode(value.to_s)
end
- def self.unicode_normalize_kc(value)
- IDN::Stringprep.nfkc_normalize(value.to_s)
+ class << self
+ # @deprecated Use {String#unicode_normalize(:nfkc)} instead
+ def unicode_normalize_kc(value)
+ value.to_s.unicode_normalize(:nfkc)
+ end
+
+ extend Gem::Deprecate
+ deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)",
2023, 4
end
def self.to_ascii(value)
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 2022-08-19 12:48:27.000000000 +0200
+++ new/lib/addressable/idna/pure.rb 2023-04-09 17:02:36.000000000 +0200
@@ -66,7 +66,7 @@
# domain name as described in RFC 3490.
def self.to_ascii(input)
input = input.to_s unless input.is_a?(String)
- input = input.dup
+ input =
input.dup.force_encoding(Encoding::UTF_8).unicode_normalize(:nfkc)
if input.respond_to?(:force_encoding)
input.force_encoding(Encoding::ASCII_8BIT)
end
@@ -77,7 +77,7 @@
part.force_encoding(Encoding::ASCII_8BIT)
end
if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE
- ACE_PREFIX + punycode_encode(unicode_normalize_kc(part))
+ ACE_PREFIX + punycode_encode(part)
else
part
end
@@ -112,13 +112,14 @@
output
end
- # Unicode normalization form KC.
- def self.unicode_normalize_kc(input)
- input = input.to_s unless input.is_a?(String)
- unpacked = input.unpack("U*")
- unpacked =
- unicode_compose(unicode_sort_canonical(unicode_decompose(unpacked)))
- return unpacked.pack("U*")
+ class << self
+ # @deprecated Use {String#unicode_normalize(:nfkc)} instead
+ def unicode_normalize_kc(value)
+ value.to_s.unicode_normalize(:nfkc)
+ end
+
+ extend Gem::Deprecate
+ deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)",
2023, 4
end
##
@@ -136,164 +137,6 @@
end
private_class_method :unicode_downcase
- def self.unicode_compose(unpacked)
- unpacked_result = []
- length = unpacked.length
-
- return unpacked if length == 0
-
- starter = unpacked[0]
- starter_cc = lookup_unicode_combining_class(starter)
- starter_cc = 256 if starter_cc != 0
- for i in 1...length
- ch = unpacked[i]
-
- if (starter_cc == 0 &&
- (composite = unicode_compose_pair(starter, ch)) != nil)
- starter = composite
- else
- unpacked_result << starter
- starter = ch
- end
- end
- unpacked_result << starter
- return unpacked_result
- 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 &&
- ch_two >= HANGUL_VBASE && ch_two < HANGUL_VBASE + HANGUL_VCOUNT
- # Hangul L + V
- return HANGUL_SBASE + (
- (ch_one - HANGUL_LBASE) * HANGUL_VCOUNT + (ch_two - HANGUL_VBASE)
- ) * HANGUL_TCOUNT
- elsif ch_one >= HANGUL_SBASE &&
- ch_one < HANGUL_SBASE + HANGUL_SCOUNT &&
- (ch_one - HANGUL_SBASE) % HANGUL_TCOUNT == 0 &&
- ch_two >= HANGUL_TBASE && ch_two < HANGUL_TBASE + HANGUL_TCOUNT
- # Hangul LV + T
- return ch_one + (ch_two - HANGUL_TBASE)
- end
-
- p = []
-
- ucs4_to_utf8(ch_one, p)
- ucs4_to_utf8(ch_two, p)
-
- return lookup_unicode_composition(p)
- end
- private_class_method :unicode_compose_pair
-
- def self.ucs4_to_utf8(char, buffer)
- if char < 128
- buffer << char
- elsif char < 2048
- buffer << (char >> 6 | 192)
- buffer << (char & 63 | 128)
- elsif char < 0x10000
- buffer << (char >> 12 | 224)
- buffer << (char >> 6 & 63 | 128)
- buffer << (char & 63 | 128)
- elsif char < 0x200000
- buffer << (char >> 18 | 240)
- buffer << (char >> 12 & 63 | 128)
- buffer << (char >> 6 & 63 | 128)
- buffer << (char & 63 | 128)
- elsif char < 0x4000000
- buffer << (char >> 24 | 248)
- buffer << (char >> 18 & 63 | 128)
- buffer << (char >> 12 & 63 | 128)
- buffer << (char >> 6 & 63 | 128)
- buffer << (char & 63 | 128)
- elsif char < 0x80000000
- buffer << (char >> 30 | 252)
- buffer << (char >> 24 & 63 | 128)
- buffer << (char >> 18 & 63 | 128)
- buffer << (char >> 12 & 63 | 128)
- buffer << (char >> 6 & 63 | 128)
- buffer << (char & 63 | 128)
- end
- end
- private_class_method :ucs4_to_utf8
-
- def self.unicode_sort_canonical(unpacked)
- unpacked = unpacked.dup
- i = 1
- length = unpacked.length
-
- return unpacked if length < 2
-
- while i < length
- last = unpacked[i-1]
- ch = unpacked[i]
- last_cc = lookup_unicode_combining_class(last)
- cc = lookup_unicode_combining_class(ch)
- if cc != 0 && last_cc != 0 && last_cc > cc
- unpacked[i] = last
- unpacked[i-1] = ch
- i -= 1 if i > 1
- else
- i += 1
- end
- end
- return unpacked
- end
- private_class_method :unicode_sort_canonical
-
- def self.unicode_decompose(unpacked)
- unpacked_result = []
- for cp in unpacked
- if cp >= HANGUL_SBASE && cp < HANGUL_SBASE + HANGUL_SCOUNT
- l, v, t = unicode_decompose_hangul(cp)
- unpacked_result << l
- unpacked_result << v if v
- unpacked_result << t if t
- else
- dc = lookup_unicode_compatibility(cp)
- unless dc
- unpacked_result << cp
- else
- unpacked_result.concat(unicode_decompose(dc.unpack("U*")))
- end
- end
- end
- return unpacked_result
- end
- private_class_method :unicode_decompose
-
- def self.unicode_decompose_hangul(codepoint)
- sindex = codepoint - HANGUL_SBASE;
- if sindex < 0 || sindex >= HANGUL_SCOUNT
- l = codepoint
- v = t = nil
- return l, v, t
- end
- l = HANGUL_LBASE + sindex / HANGUL_NCOUNT
- v = HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
- t = HANGUL_TBASE + sindex % HANGUL_TCOUNT
- if t == HANGUL_TBASE
- t = nil
- end
- return l, v, t
- end
- private_class_method :unicode_decompose_hangul
-
- def self.lookup_unicode_combining_class(codepoint)
- codepoint_data = UNICODE_DATA[codepoint]
- (codepoint_data ?
- (codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) :
- 0)
- 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
- private_class_method :lookup_unicode_compatibility
-
def self.lookup_unicode_lowercase(codepoint)
codepoint_data = UNICODE_DATA[codepoint]
(codepoint_data ?
@@ -302,21 +145,6 @@
end
private_class_method :lookup_unicode_lowercase
- def self.lookup_unicode_composition(unpacked)
- return COMPOSITION_TABLE[unpacked]
- end
- private_class_method :lookup_unicode_composition
-
- HANGUL_SBASE = 0xac00
- HANGUL_LBASE = 0x1100
- HANGUL_LCOUNT = 19
- HANGUL_VBASE = 0x1161
- HANGUL_VCOUNT = 21
- HANGUL_TBASE = 0x11a7
- HANGUL_TCOUNT = 28
- HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT # 588
- HANGUL_SCOUNT = HANGUL_LCOUNT * HANGUL_NCOUNT # 11172
-
UNICODE_DATA_COMBINING_CLASS = 0
UNICODE_DATA_EXCLUSION = 1
UNICODE_DATA_CANONICAL = 2
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 2022-08-19 12:48:27.000000000 +0200
+++ new/lib/addressable/template.rb 2023-04-09 17:02:36.000000000 +0200
@@ -892,25 +892,24 @@
# operator.
#
# @param [Hash, Array, String] value
- # Normalizes keys and values with IDNA#unicode_normalize_kc
+ # Normalizes unicode keys and values with String#unicode_normalize (NFC)
#
# @return [Hash, Array, String] The normalized values
def normalize_value(value)
- unless value.is_a?(Hash)
- value = value.respond_to?(:to_ary) ? value.to_ary : value.to_str
- end
-
# Handle unicode normalization
- if value.kind_of?(Array)
- value.map! { |val| Addressable::IDNA.unicode_normalize_kc(val) }
+ if value.respond_to?(:to_ary)
+ value.to_ary.map! { |val| normalize_value(val) }
elsif value.kind_of?(Hash)
value = value.inject({}) { |acc, (k, v)|
- acc[Addressable::IDNA.unicode_normalize_kc(k)] =
- Addressable::IDNA.unicode_normalize_kc(v)
+ acc[normalize_value(k)] = normalize_value(v)
acc
}
else
- value = Addressable::IDNA.unicode_normalize_kc(value)
+ value = value.to_s if !value.kind_of?(String)
+ if value.encoding != Encoding::UTF_8
+ value = value.dup.force_encoding(Encoding::UTF_8)
+ end
+ value = value.unicode_normalize(:nfc)
end
value
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 2022-08-19 12:48:27.000000000 +0200
+++ new/lib/addressable/uri.rb 2023-04-09 17:02:36.000000000 +0200
@@ -53,7 +53,7 @@
PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze
SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze
HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze
- AUTHORITY = (PCHAR + "\\[\\:\\]").freeze
+ AUTHORITY = (PCHAR + "\\[\\]").freeze
PATH = (PCHAR + "\\/").freeze
QUERY = (PCHAR + "\\/\\?").freeze
FRAGMENT = (PCHAR + "\\/\\?").freeze
@@ -117,7 +117,7 @@
uri = uri.to_str
rescue TypeError, NoMethodError
raise TypeError, "Can't convert #{uri.class} into String."
- end if not uri.is_a? String
+ end unless uri.is_a?(String)
# This Regexp supplied as an example in RFC 3986, and it works great.
scan = uri.scan(URIREGEX)
@@ -138,15 +138,15 @@
user = userinfo.strip[/^([^:]*):?/, 1]
password = userinfo.strip[/:(.*)$/, 1]
end
+
host = authority.sub(
/^([^\[\]]*)@/, EMPTY_STR
).sub(
/:([^:@\[\]]*?)$/, EMPTY_STR
)
+
port = authority[/:([^:@\[\]]*?)$/, 1]
- end
- if port == EMPTY_STR
- port = nil
+ port = nil if port == EMPTY_STR
end
return new(
@@ -189,7 +189,7 @@
uri = uri.to_s
end
- if !uri.respond_to?(:to_str)
+ unless uri.respond_to?(:to_str)
raise TypeError, "Can't convert #{uri.class} into String."
end
# Otherwise, convert to a String
@@ -281,7 +281,7 @@
return nil unless path
# If a URI object is passed, just return itself.
return path if path.kind_of?(self)
- if !path.respond_to?(:to_str)
+ unless path.respond_to?(:to_str)
raise TypeError, "Can't convert #{path.class} into String."
end
# Otherwise, convert to a String
@@ -329,13 +329,13 @@
# #=> #<Addressable::URI:0xcab390 URI:http://example.com/relative/path>
def self.join(*uris)
uri_objects = uris.collect do |uri|
- if !uri.respond_to?(:to_str)
+ unless uri.respond_to?(:to_str)
raise TypeError, "Can't convert #{uri.class} into String."
end
uri.kind_of?(self) ? uri : self.parse(uri.to_str)
end
result = uri_objects.shift.dup
- for uri in uri_objects
+ uri_objects.each do |uri|
result.join!(uri)
end
return result
@@ -481,7 +481,7 @@
leave_encoded.include?(c) ? sequence : c
end
- result.force_encoding("utf-8")
+ result.force_encoding(Encoding::UTF_8)
if return_type == String
return result
elsif return_type == ::Addressable::URI
@@ -579,7 +579,7 @@
unencoded = self.unencode_component(component, String, leave_encoded)
begin
encoded = self.encode_component(
- Addressable::IDNA.unicode_normalize_kc(unencoded),
+ unencoded.unicode_normalize(:nfc),
character_class,
leave_encoded
)
@@ -687,8 +687,7 @@
components.each do |key, value|
if value != nil
begin
- components[key] =
- Addressable::IDNA.unicode_normalize_kc(value.to_str)
+ components[key] = value.to_str.unicode_normalize(:nfc)
rescue ArgumentError
# Likely a malformed UTF-8 character, skip unicode normalization
components[key] = value.to_str
@@ -836,7 +835,9 @@
end
end
- self.defer_validation do
+ reset_ivs
+
+ defer_validation do
# Bunch of crazy logic required because of the composite components
# like userinfo and authority.
self.scheme = options[:scheme] if options[:scheme]
@@ -851,7 +852,8 @@
self.query_values = options[:query_values] if options[:query_values]
self.fragment = options[:fragment] if options[:fragment]
end
- self.to_s
+
+ to_s # force path validation
end
##
@@ -878,9 +880,7 @@
# The scheme component for this URI.
#
# @return [String] The scheme component.
- def scheme
- return defined?(@scheme) ? @scheme : nil
- end
+ attr_reader :scheme
##
# The scheme component for this URI, normalized.
@@ -888,8 +888,8 @@
# @return [String] The scheme component, normalized.
def normalized_scheme
return nil unless self.scheme
- @normalized_scheme ||= begin
- if self.scheme =~ /^\s*ssh\+svn\s*$/i
+ if @normalized_scheme == NONE
+ @normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i
"svn+ssh".dup
else
Addressable::URI.normalize_component(
@@ -920,7 +920,7 @@
@scheme = nil if @scheme.to_s.strip.empty?
# Reset dependent values
- remove_instance_variable(:@normalized_scheme) if
defined?(@normalized_scheme)
+ @normalized_scheme = NONE
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -931,9 +931,7 @@
# The user component for this URI.
#
# @return [String] The user component.
- def user
- return defined?(@user) ? @user : nil
- end
+ attr_reader :user
##
# The user component for this URI, normalized.
@@ -941,8 +939,8 @@
# @return [String] The user component, normalized.
def normalized_user
return nil unless self.user
- return @normalized_user if defined?(@normalized_user)
- @normalized_user ||= begin
+ return @normalized_user unless @normalized_user == NONE
+ @normalized_user = begin
if normalized_scheme =~ /https?/ && self.user.strip.empty? &&
(!self.password || self.password.strip.empty?)
nil
@@ -970,14 +968,14 @@
# You can't have a nil user with a non-nil password
if password != nil
- @user = EMPTY_STR if @user.nil?
+ @user = EMPTY_STR unless user
end
# Reset dependent values
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
- remove_instance_variable(:@normalized_userinfo) if
defined?(@normalized_userinfo)
- remove_instance_variable(:@authority) if defined?(@authority)
- remove_instance_variable(:@normalized_user) if defined?(@normalized_user)
+ @userinfo = nil
+ @normalized_userinfo = NONE
+ @authority = nil
+ @normalized_user = NONE
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -988,9 +986,7 @@
# The password component for this URI.
#
# @return [String] The password component.
- def password
- return defined?(@password) ? @password : nil
- end
+ attr_reader :password
##
# The password component for this URI, normalized.
@@ -998,8 +994,8 @@
# @return [String] The password component, normalized.
def normalized_password
return nil unless self.password
- return @normalized_password if defined?(@normalized_password)
- @normalized_password ||= begin
+ return @normalized_password unless @normalized_password == NONE
+ @normalized_password = begin
if self.normalized_scheme =~ /https?/ && self.password.strip.empty? &&
(!self.user || self.user.strip.empty?)
nil
@@ -1026,17 +1022,15 @@
@password = new_password ? new_password.to_str : nil
# You can't have a nil user with a non-nil password
- @password ||= nil
- @user ||= nil
if @password != nil
- @user = EMPTY_STR if @user.nil?
+ self.user = EMPTY_STR if user.nil?
end
# Reset dependent values
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
- remove_instance_variable(:@normalized_userinfo) if
defined?(@normalized_userinfo)
- remove_instance_variable(:@authority) if defined?(@authority)
- remove_instance_variable(:@normalized_password) if
defined?(@normalized_password)
+ @userinfo = nil
+ @normalized_userinfo = NONE
+ @authority = nil
+ @normalized_password = NONE
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1066,8 +1060,8 @@
# @return [String] The userinfo component, normalized.
def normalized_userinfo
return nil unless self.userinfo
- return @normalized_userinfo if defined?(@normalized_userinfo)
- @normalized_userinfo ||= begin
+ return @normalized_userinfo unless @normalized_userinfo == NONE
+ @normalized_userinfo = begin
current_user = self.normalized_user
current_password = self.normalized_password
if !current_user && !current_password
@@ -1105,7 +1099,7 @@
self.user = new_user
# Reset dependent values
- remove_instance_variable(:@authority) if defined?(@authority)
+ @authority = nil
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1116,9 +1110,7 @@
# The host component for this URI.
#
# @return [String] The host component.
- def host
- return defined?(@host) ? @host : nil
- end
+ attr_reader :host
##
# The host component for this URI, normalized.
@@ -1161,8 +1153,8 @@
@host = new_host ? new_host.to_str : nil
# Reset dependent values
- remove_instance_variable(:@authority) if defined?(@authority)
- remove_instance_variable(:@normalized_host) if defined?(@normalized_host)
+ @authority = nil
+ @normalized_host = nil
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1293,14 +1285,14 @@
end
# Password assigned first to ensure validity in case of nil
- self.password = defined?(new_password) ? new_password : nil
- self.user = defined?(new_user) ? new_user : nil
- self.host = defined?(new_host) ? new_host : nil
- self.port = defined?(new_port) ? new_port : nil
+ self.password = new_password
+ self.user = new_user
+ self.host = new_host
+ self.port = new_port
# Reset dependent values
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
- remove_instance_variable(:@normalized_userinfo) if
defined?(@normalized_userinfo)
+ @userinfo = nil
+ @normalized_userinfo = NONE
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1348,16 +1340,16 @@
new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1]
end
- self.scheme = defined?(new_scheme) ? new_scheme : nil
- self.host = defined?(new_host) ? new_host : nil
- self.port = defined?(new_port) ? new_port : nil
+ self.scheme = new_scheme
+ self.host = new_host
+ self.port = new_port
self.userinfo = nil
# Reset dependent values
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
- remove_instance_variable(:@normalized_userinfo) if
defined?(@normalized_userinfo)
- remove_instance_variable(:@authority) if defined?(@authority)
- remove_instance_variable(:@normalized_authority) if
defined?(@normalized_authority)
+ @userinfo = nil
+ @normalized_userinfo = NONE
+ @authority = nil
+ @normalized_authority = nil
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1384,9 +1376,7 @@
# infer port numbers from default values.
#
# @return [Integer] The port component.
- def port
- return defined?(@port) ? @port : nil
- end
+ attr_reader :port
##
# The port component for this URI, normalized.
@@ -1394,8 +1384,8 @@
# @return [Integer] The port component, normalized.
def normalized_port
return nil unless self.port
- return @normalized_port if defined?(@normalized_port)
- @normalized_port ||= begin
+ return @normalized_port unless @normalized_port == NONE
+ @normalized_port = begin
if URI.port_mapping[self.normalized_scheme] == self.port
nil
else
@@ -1426,8 +1416,8 @@
@port = nil if @port == 0
# Reset dependent values
- remove_instance_variable(:@authority) if defined?(@authority)
- remove_instance_variable(:@normalized_port) if defined?(@normalized_port)
+ @authority = nil
+ @normalized_port = NONE
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1528,9 +1518,7 @@
# The path component for this URI.
#
# @return [String] The path component.
- def path
- return defined?(@path) ? @path : EMPTY_STR
- end
+ attr_reader :path
NORMPATH = /^(?!\/)[^\/:]*:.*$/
##
@@ -1579,7 +1567,7 @@
end
# Reset dependent values
- remove_instance_variable(:@normalized_path) if defined?(@normalized_path)
+ @normalized_path = nil
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -1609,9 +1597,7 @@
# The query component for this URI.
#
# @return [String] The query component.
- def query
- return defined?(@query) ? @query : nil
- end
+ attr_reader :query
##
# The query component for this URI, normalized.
@@ -1619,8 +1605,8 @@
# @return [String] The query component, normalized.
def normalized_query(*flags)
return nil unless self.query
- return @normalized_query if defined?(@normalized_query)
- @normalized_query ||= begin
+ return @normalized_query unless @normalized_query == NONE
+ @normalized_query = begin
modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
# Make sure possible key-value pair delimiters are escaped.
modified_query_class.sub!("\\&", "").sub!("\\;", "")
@@ -1652,7 +1638,7 @@
@query = new_query ? new_query.to_str : nil
# Reset dependent values
- remove_instance_variable(:@normalized_query) if
defined?(@normalized_query)
+ @normalized_query = NONE
remove_composite_values
end
@@ -1814,9 +1800,7 @@
# The fragment component for this URI.
#
# @return [String] The fragment component.
- def fragment
- return defined?(@fragment) ? @fragment : nil
- end
+ attr_reader :fragment
##
# The fragment component for this URI, normalized.
@@ -1824,8 +1808,8 @@
# @return [String] The fragment component, normalized.
def normalized_fragment
return nil unless self.fragment
- return @normalized_fragment if defined?(@normalized_fragment)
- @normalized_fragment ||= begin
+ return @normalized_fragment unless @normalized_fragment == NONE
+ @normalized_fragment = begin
component = Addressable::URI.normalize_component(
self.fragment,
Addressable::URI::NormalizeCharacterClasses::FRAGMENT
@@ -1848,7 +1832,7 @@
@fragment = new_fragment ? new_fragment.to_str : nil
# Reset dependent values
- remove_instance_variable(:@normalized_fragment) if
defined?(@normalized_fragment)
+ @normalized_fragment = NONE
remove_composite_values
# Ensure we haven't created an invalid URI
@@ -2014,7 +1998,7 @@
#
# @see Hash#merge
def merge(hash)
- if !hash.respond_to?(:to_hash)
+ unless hash.respond_to?(:to_hash)
raise TypeError, "Can't convert #{hash.class} into Hash."
end
hash = hash.to_hash
@@ -2408,7 +2392,8 @@
yield
@validation_deferred = false
validate
- return nil
+ ensure
+ @validation_deferred = false
end
protected
@@ -2507,11 +2492,7 @@
# @return [Addressable::URI] <code>self</code>.
def replace_self(uri)
# Reset dependent values
- instance_variables.each do |var|
- if instance_variable_defined?(var) && var != :@validation_deferred
- remove_instance_variable(var)
- end
- end
+ reset_ivs
@scheme = uri.scheme
@user = uri.user
@@ -2543,8 +2524,8 @@
#
# @api private
def remove_composite_values
- remove_instance_variable(:@uri_string) if defined?(@uri_string)
- remove_instance_variable(:@hash) if defined?(@hash)
+ @uri_string = nil
+ @hash = nil
end
##
@@ -2556,5 +2537,40 @@
str.force_encoding(Encoding::UTF_8)
end
end
+
+ private
+
+ ##
+ # Resets instance variables
+ #
+ # @api private
+ def reset_ivs
+ @scheme = nil
+ @user = nil
+ @normalized_scheme = NONE
+ @normalized_user = NONE
+ @uri_string = nil
+ @hash = nil
+ @userinfo = nil
+ @normalized_userinfo = NONE
+ @authority = nil
+ @password = nil
+ @normalized_authority = nil
+ @port = nil
+ @normalized_password = NONE
+ @host = nil
+ @normalized_host = nil
+ @normalized_port = NONE
+ @path = EMPTY_STR
+ @normalized_path = nil
+ @normalized_query = NONE
+ @fragment = nil
+ @normalized_fragment = NONE
+ @query = nil
+ end
+
+ NONE = Object.new.freeze
+
+ private_constant :NONE
end
end
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 2022-08-19 12:48:27.000000000 +0200
+++ new/lib/addressable/version.rb 2023-04-09 17:02:36.000000000 +0200
@@ -23,7 +23,7 @@
module VERSION
MAJOR = 2
MINOR = 8
- TINY = 1
+ TINY = 4
STRING = [MAJOR, MINOR, TINY].join('.')
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata 2022-08-19 12:48:27.000000000 +0200
+++ new/metadata 2023-04-09 17:02:36.000000000 +0200
@@ -1,14 +1,14 @@
--- !ruby/object:Gem::Specification
name: addressable
version: !ruby/object:Gem::Version
- version: 2.8.1
+ version: 2.8.4
platform: ruby
authors:
- Bob Aman
autorequire:
bindir: bin
cert_chain: []
-date: 2022-08-19 00:00:00.000000000 Z
+date: 2023-04-09 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: public_suffix
@@ -65,6 +65,7 @@
- LICENSE.txt
- README.md
- Rakefile
+- addressable.gemspec
- data/unicode.data
- lib/addressable.rb
- lib/addressable/idna.rb
@@ -108,7 +109,7 @@
- !ruby/object:Gem::Version
version: '0'
requirements: []
-rubygems_version: 3.3.7
+rubygems_version: 3.4.10
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 2022-08-19 12:48:27.000000000 +0200
+++ new/spec/addressable/idna_spec.rb 2023-04-09 17:02:36.000000000 +0200
@@ -38,6 +38,12 @@
)).to eq("www.xn--8ws00zhy3a.com")
end
+ it "also accepts unicode strings encoded as ascii-8bit" do
+ expect(Addressable::IDNA.to_ascii(
+ "www.è©¹å§æ¯.com".b
+ )).to eq("www.xn--8ws00zhy3a.com")
+ end
+
it "should convert 'www.Iñtërnâtiônà lizætiøn.com' correctly" do
"www.Iñtërnâtiônà lizætiøn.com"
expect(Addressable::IDNA.to_ascii(
@@ -249,11 +255,6 @@
"example..host"
)).to eq("example..host")
end
-
- it "should normalize 'string' correctly" do
- expect(Addressable::IDNA.unicode_normalize_kc(:'string')).to eq("string")
- expect(Addressable::IDNA.unicode_normalize_kc("string")).to eq("string")
- end
end
describe Addressable::IDNA, "when using the pure-Ruby implementation" do
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 2022-08-19 12:48:27.000000000
+0200
+++ new/spec/addressable/template_spec.rb 2023-04-09 17:02:36.000000000
+0200
@@ -26,11 +26,7 @@
exp = expansion.is_a?(Array) ? expansion.first : expansion
it "#{template} to #{exp}" do
tmpl = Addressable::Template.new(template).expand(subject)
- if expansion.is_a?(Array)
- expect(expansion.any?{|i| i == tmpl.to_str}).to be true
- else
- expect(tmpl.to_str).to eq(expansion)
- end
+ expect(tmpl.to_str).to eq(expansion)
end
end
end
@@ -209,7 +205,7 @@
:path => "/foo/bar",
:semi => ";",
:list => %w(red green blue),
- :keys => {"semi" => ';', "dot" => '.', "comma" => ','}
+ :keys => {"semi" => ';', "dot" => '.', :comma => ','}
}
}
context "Expansion with value modifiers" do
@@ -218,22 +214,8 @@
'{var:30}' => 'value',
'{list}' => 'red,green,blue',
'{list*}' => 'red,green,blue',
- '{keys}' => [
- 'semi,%3B,dot,.,comma,%2C',
- 'dot,.,semi,%3B,comma,%2C',
- 'comma,%2C,semi,%3B,dot,.',
- 'semi,%3B,comma,%2C,dot,.',
- 'dot,.,comma,%2C,semi,%3B',
- 'comma,%2C,dot,.,semi,%3B'
- ],
- '{keys*}' => [
- 'semi=%3B,dot=.,comma=%2C',
- 'dot=.,semi=%3B,comma=%2C',
- 'comma=%2C,semi=%3B,dot=.',
- 'semi=%3B,comma=%2C,dot=.',
- 'dot=.,comma=%2C,semi=%3B',
- 'comma=%2C,dot=.,semi=%3B'
- ]
+ '{keys}' => 'semi,%3B,dot,.,comma,%2C',
+ '{keys*}' => 'semi=%3B,dot=.,comma=%2C',
}
end
context "Operator + with value modifiers" do
@@ -241,22 +223,8 @@
'{+path:6}/here' => '/foo/b/here',
'{+list}' => 'red,green,blue',
'{+list*}' => 'red,green,blue',
- '{+keys}' => [
- 'semi,;,dot,.,comma,,',
- 'dot,.,semi,;,comma,,',
- 'comma,,,semi,;,dot,.',
- 'semi,;,comma,,,dot,.',
- 'dot,.,comma,,,semi,;',
- 'comma,,,dot,.,semi,;'
- ],
- '{+keys*}' => [
- 'semi=;,dot=.,comma=,',
- 'dot=.,semi=;,comma=,',
- 'comma=,,semi=;,dot=.',
- 'semi=;,comma=,,dot=.',
- 'dot=.,comma=,,semi=;',
- 'comma=,,dot=.,semi=;'
- ]
+ '{+keys}' => 'semi,;,dot,.,comma,,',
+ '{+keys*}' => 'semi=;,dot=.,comma=,',
}
end
context "Operator # with value modifiers" do
@@ -264,22 +232,8 @@
'{#path:6}/here' => '#/foo/b/here',
'{#list}' => '#red,green,blue',
'{#list*}' => '#red,green,blue',
- '{#keys}' => [
- '#semi,;,dot,.,comma,,',
- '#dot,.,semi,;,comma,,',
- '#comma,,,semi,;,dot,.',
- '#semi,;,comma,,,dot,.',
- '#dot,.,comma,,,semi,;',
- '#comma,,,dot,.,semi,;'
- ],
- '{#keys*}' => [
- '#semi=;,dot=.,comma=,',
- '#dot=.,semi=;,comma=,',
- '#comma=,,semi=;,dot=.',
- '#semi=;,comma=,,dot=.',
- '#dot=.,comma=,,semi=;',
- '#comma=,,dot=.,semi=;'
- ]
+ '{#keys}' => '#semi,;,dot,.,comma,,',
+ '{#keys*}' => '#semi=;,dot=.,comma=,',
}
end
context "Operator . with value modifiers" do
@@ -287,22 +241,8 @@
'X{.var:3}' => 'X.val',
'X{.list}' => 'X.red,green,blue',
'X{.list*}' => 'X.red.green.blue',
- 'X{.keys}' => [
- 'X.semi,%3B,dot,.,comma,%2C',
- 'X.dot,.,semi,%3B,comma,%2C',
- 'X.comma,%2C,semi,%3B,dot,.',
- 'X.semi,%3B,comma,%2C,dot,.',
- 'X.dot,.,comma,%2C,semi,%3B',
- 'X.comma,%2C,dot,.,semi,%3B'
- ],
- 'X{.keys*}' => [
- 'X.semi=%3B.dot=..comma=%2C',
- 'X.dot=..semi=%3B.comma=%2C',
- 'X.comma=%2C.semi=%3B.dot=.',
- 'X.semi=%3B.comma=%2C.dot=.',
- 'X.dot=..comma=%2C.semi=%3B',
- 'X.comma=%2C.dot=..semi=%3B'
- ]
+ 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
+ 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
}
end
context "Operator / with value modifiers" do
@@ -311,22 +251,8 @@
'{/list}' => '/red,green,blue',
'{/list*}' => '/red/green/blue',
'{/list*,path:4}' => '/red/green/blue/%2Ffoo',
- '{/keys}' => [
- '/semi,%3B,dot,.,comma,%2C',
- '/dot,.,semi,%3B,comma,%2C',
- '/comma,%2C,semi,%3B,dot,.',
- '/semi,%3B,comma,%2C,dot,.',
- '/dot,.,comma,%2C,semi,%3B',
- '/comma,%2C,dot,.,semi,%3B'
- ],
- '{/keys*}' => [
- '/semi=%3B/dot=./comma=%2C',
- '/dot=./semi=%3B/comma=%2C',
- '/comma=%2C/semi=%3B/dot=.',
- '/semi=%3B/comma=%2C/dot=.',
- '/dot=./comma=%2C/semi=%3B',
- '/comma=%2C/dot=./semi=%3B'
- ]
+ '{/keys}' => '/semi,%3B,dot,.,comma,%2C',
+ '{/keys*}' => '/semi=%3B/dot=./comma=%2C',
}
end
context "Operator ; with value modifiers" do
@@ -334,22 +260,8 @@
'{;hello:5}' => ';hello=Hello',
'{;list}' => ';list=red,green,blue',
'{;list*}' => ';list=red;list=green;list=blue',
- '{;keys}' => [
- ';keys=semi,%3B,dot,.,comma,%2C',
- ';keys=dot,.,semi,%3B,comma,%2C',
- ';keys=comma,%2C,semi,%3B,dot,.',
- ';keys=semi,%3B,comma,%2C,dot,.',
- ';keys=dot,.,comma,%2C,semi,%3B',
- ';keys=comma,%2C,dot,.,semi,%3B'
- ],
- '{;keys*}' => [
- ';semi=%3B;dot=.;comma=%2C',
- ';dot=.;semi=%3B;comma=%2C',
- ';comma=%2C;semi=%3B;dot=.',
- ';semi=%3B;comma=%2C;dot=.',
- ';dot=.;comma=%2C;semi=%3B',
- ';comma=%2C;dot=.;semi=%3B'
- ]
+ '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
+ '{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
}
end
context "Operator ? with value modifiers" do
@@ -357,22 +269,8 @@
'{?var:3}' => '?var=val',
'{?list}' => '?list=red,green,blue',
'{?list*}' => '?list=red&list=green&list=blue',
- '{?keys}' => [
- '?keys=semi,%3B,dot,.,comma,%2C',
- '?keys=dot,.,semi,%3B,comma,%2C',
- '?keys=comma,%2C,semi,%3B,dot,.',
- '?keys=semi,%3B,comma,%2C,dot,.',
- '?keys=dot,.,comma,%2C,semi,%3B',
- '?keys=comma,%2C,dot,.,semi,%3B'
- ],
- '{?keys*}' => [
- '?semi=%3B&dot=.&comma=%2C',
- '?dot=.&semi=%3B&comma=%2C',
- '?comma=%2C&semi=%3B&dot=.',
- '?semi=%3B&comma=%2C&dot=.',
- '?dot=.&comma=%2C&semi=%3B',
- '?comma=%2C&dot=.&semi=%3B'
- ]
+ '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
+ '{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
}
end
context "Operator & with value modifiers" do
@@ -380,22 +278,8 @@
'{&var:3}' => '&var=val',
'{&list}' => '&list=red,green,blue',
'{&list*}' => '&list=red&list=green&list=blue',
- '{&keys}' => [
- '&keys=semi,%3B,dot,.,comma,%2C',
- '&keys=dot,.,semi,%3B,comma,%2C',
- '&keys=comma,%2C,semi,%3B,dot,.',
- '&keys=semi,%3B,comma,%2C,dot,.',
- '&keys=dot,.,comma,%2C,semi,%3B',
- '&keys=comma,%2C,dot,.,semi,%3B'
- ],
- '{&keys*}' => [
- '&semi=%3B&dot=.&comma=%2C',
- '&dot=.&semi=%3B&comma=%2C',
- '&comma=%2C&semi=%3B&dot=.',
- '&semi=%3B&comma=%2C&dot=.',
- '&dot=.&comma=%2C&semi=%3B',
- '&comma=%2C&dot=.&semi=%3B'
- ]
+ '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
+ '{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
}
end
end
@@ -404,7 +288,7 @@
{
:var => "value",
:semi => ";",
- :year => %w(1965 2000 2012),
+ :year => [1965, 2000, 2012],
:dom => %w(example com)
}
}
@@ -437,7 +321,7 @@
:base => "http://example.com/home/",
:path => "/foo/bar",
:list => ["red", "green", "blue"],
- :keys => {"semi" => ";","dot" => ".","comma" => ","},
+ :keys => {"semi" => ";","dot" => ".",:comma => ","},
:v => "6",
:x => "1024",
:y => "768",
@@ -475,22 +359,8 @@
'{var:30}' => 'value',
'{list}' => 'red,green,blue',
'{list*}' => 'red,green,blue',
- '{keys}' => [
- 'semi,%3B,dot,.,comma,%2C',
- 'dot,.,semi,%3B,comma,%2C',
- 'comma,%2C,semi,%3B,dot,.',
- 'semi,%3B,comma,%2C,dot,.',
- 'dot,.,comma,%2C,semi,%3B',
- 'comma,%2C,dot,.,semi,%3B'
- ],
- '{keys*}' => [
- 'semi=%3B,dot=.,comma=%2C',
- 'dot=.,semi=%3B,comma=%2C',
- 'comma=%2C,semi=%3B,dot=.',
- 'semi=%3B,comma=%2C,dot=.',
- 'dot=.,comma=%2C,semi=%3B',
- 'comma=%2C,dot=.,semi=%3B'
- ]
+ '{keys}' => 'semi,%3B,dot,.,comma,%2C',
+ '{keys*}' => 'semi=%3B,dot=.,comma=%2C',
}
end
context "reserved expansion (+)" do
@@ -510,22 +380,8 @@
'{+path:6}/here' => '/foo/b/here',
'{+list}' => 'red,green,blue',
'{+list*}' => 'red,green,blue',
- '{+keys}' => [
- 'semi,;,dot,.,comma,,',
- 'dot,.,semi,;,comma,,',
- 'comma,,,semi,;,dot,.',
- 'semi,;,comma,,,dot,.',
- 'dot,.,comma,,,semi,;',
- 'comma,,,dot,.,semi,;'
- ],
- '{+keys*}' => [
- 'semi=;,dot=.,comma=,',
- 'dot=.,semi=;,comma=,',
- 'comma=,,semi=;,dot=.',
- 'semi=;,comma=,,dot=.',
- 'dot=.,comma=,,semi=;',
- 'comma=,,dot=.,semi=;'
- ]
+ '{+keys}' => 'semi,;,dot,.,comma,,',
+ '{+keys*}' => 'semi=;,dot=.,comma=,',
}
end
context "fragment expansion (#)" do
@@ -540,22 +396,8 @@
'{#path:6}/here' => '#/foo/b/here',
'{#list}' => '#red,green,blue',
'{#list*}' => '#red,green,blue',
- '{#keys}' => [
- '#semi,;,dot,.,comma,,',
- '#dot,.,semi,;,comma,,',
- '#comma,,,semi,;,dot,.',
- '#semi,;,comma,,,dot,.',
- '#dot,.,comma,,,semi,;',
- '#comma,,,dot,.,semi,;'
- ],
- '{#keys*}' => [
- '#semi=;,dot=.,comma=,',
- '#dot=.,semi=;,comma=,',
- '#comma=,,semi=;,dot=.',
- '#semi=;,comma=,,dot=.',
- '#dot=.,comma=,,semi=;',
- '#comma=,,dot=.,semi=;'
- ]
+ '{#keys}' => '#semi,;,dot,.,comma,,',
+ '{#keys*}' => '#semi=;,dot=.,comma=,',
}
end
context "label expansion (.)" do
@@ -570,22 +412,8 @@
'X{.var:3}' => 'X.val',
'X{.list}' => 'X.red,green,blue',
'X{.list*}' => 'X.red.green.blue',
- 'X{.keys}' => [
- 'X.semi,%3B,dot,.,comma,%2C',
- 'X.dot,.,semi,%3B,comma,%2C',
- 'X.comma,%2C,semi,%3B,dot,.',
- 'X.semi,%3B,comma,%2C,dot,.',
- 'X.dot,.,comma,%2C,semi,%3B',
- 'X.comma,%2C,dot,.,semi,%3B'
- ],
- 'X{.keys*}' => [
- 'X.semi=%3B.dot=..comma=%2C',
- 'X.dot=..semi=%3B.comma=%2C',
- 'X.comma=%2C.semi=%3B.dot=.',
- 'X.semi=%3B.comma=%2C.dot=.',
- 'X.dot=..comma=%2C.semi=%3B',
- 'X.comma=%2C.dot=..semi=%3B'
- ],
+ 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
+ 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
'X{.empty_keys}' => 'X',
'X{.empty_keys*}' => 'X'
}
@@ -604,22 +432,8 @@
'{/list}' => '/red,green,blue',
'{/list*}' => '/red/green/blue',
'{/list*,path:4}' => '/red/green/blue/%2Ffoo',
- '{/keys}' => [
- '/semi,%3B,dot,.,comma,%2C',
- '/dot,.,semi,%3B,comma,%2C',
- '/comma,%2C,semi,%3B,dot,.',
- '/semi,%3B,comma,%2C,dot,.',
- '/dot,.,comma,%2C,semi,%3B',
- '/comma,%2C,dot,.,semi,%3B'
- ],
- '{/keys*}' => [
- '/semi=%3B/dot=./comma=%2C',
- '/dot=./semi=%3B/comma=%2C',
- '/comma=%2C/semi=%3B/dot=.',
- '/semi=%3B/comma=%2C/dot=.',
- '/dot=./comma=%2C/semi=%3B',
- '/comma=%2C/dot=./semi=%3B'
- ]
+ '{/keys}' => '/semi,%3B,dot,.,comma,%2C',
+ '{/keys*}' => '/semi=%3B/dot=./comma=%2C',
}
end
context "path-style expansion (;)" do
@@ -635,22 +449,8 @@
'{;hello:5}' => ';hello=Hello',
'{;list}' => ';list=red,green,blue',
'{;list*}' => ';list=red;list=green;list=blue',
- '{;keys}' => [
- ';keys=semi,%3B,dot,.,comma,%2C',
- ';keys=dot,.,semi,%3B,comma,%2C',
- ';keys=comma,%2C,semi,%3B,dot,.',
- ';keys=semi,%3B,comma,%2C,dot,.',
- ';keys=dot,.,comma,%2C,semi,%3B',
- ';keys=comma,%2C,dot,.,semi,%3B'
- ],
- '{;keys*}' => [
- ';semi=%3B;dot=.;comma=%2C',
- ';dot=.;semi=%3B;comma=%2C',
- ';comma=%2C;semi=%3B;dot=.',
- ';semi=%3B;comma=%2C;dot=.',
- ';dot=.;comma=%2C;semi=%3B',
- ';comma=%2C;dot=.;semi=%3B'
- ]
+ '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
+ '{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
}
end
context "form query expansion (?)" do
@@ -663,22 +463,8 @@
'{?var:3}' => '?var=val',
'{?list}' => '?list=red,green,blue',
'{?list*}' => '?list=red&list=green&list=blue',
- '{?keys}' => [
- '?keys=semi,%3B,dot,.,comma,%2C',
- '?keys=dot,.,semi,%3B,comma,%2C',
- '?keys=comma,%2C,semi,%3B,dot,.',
- '?keys=semi,%3B,comma,%2C,dot,.',
- '?keys=dot,.,comma,%2C,semi,%3B',
- '?keys=comma,%2C,dot,.,semi,%3B'
- ],
- '{?keys*}' => [
- '?semi=%3B&dot=.&comma=%2C',
- '?dot=.&semi=%3B&comma=%2C',
- '?comma=%2C&semi=%3B&dot=.',
- '?semi=%3B&comma=%2C&dot=.',
- '?dot=.&comma=%2C&semi=%3B',
- '?comma=%2C&dot=.&semi=%3B'
- ]
+ '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
+ '{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
}
end
context "form query expansion (&)" do
@@ -691,22 +477,8 @@
'{&var:3}' => '&var=val',
'{&list}' => '&list=red,green,blue',
'{&list*}' => '&list=red&list=green&list=blue',
- '{&keys}' => [
- '&keys=semi,%3B,dot,.,comma,%2C',
- '&keys=dot,.,semi,%3B,comma,%2C',
- '&keys=comma,%2C,semi,%3B,dot,.',
- '&keys=semi,%3B,comma,%2C,dot,.',
- '&keys=dot,.,comma,%2C,semi,%3B',
- '&keys=comma,%2C,dot,.,semi,%3B'
- ],
- '{&keys*}' => [
- '&semi=%3B&dot=.&comma=%2C',
- '&dot=.&semi=%3B&comma=%2C',
- '&comma=%2C&semi=%3B&dot=.',
- '&semi=%3B&comma=%2C&dot=.',
- '&dot=.&comma=%2C&semi=%3B',
- '&comma=%2C&dot=.&semi=%3B'
- ]
+ '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
+ '{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
}
end
context "non-string key in match data" do
@@ -1021,6 +793,19 @@
)
end
+ it "normalizes as unicode even with wrong encoding specified" do
+ template = subject.partial_expand("query" => "Cafe\u0301".b)
+ expect(template.pattern).to eq(
+ "http://example.com/{resource}/Caf%C3%A9/"
+ )
+ end
+
+ it "raises on invalid unicode input" do
+ expect {
+ subject.partial_expand("query" => "M\xE9thode".b)
+ }.to raise_error(ArgumentError, "invalid byte sequence in UTF-8")
+ 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(
@@ -1081,6 +866,17 @@
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
end
+ it "normalizes as unicode even with wrong encoding specified" do
+ uri = subject.expand("query" => "Cafe\u0301".b).to_str
+ expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
+ end
+
+ it "raises on invalid unicode input" do
+ expect {
+ subject.expand("query" => "M\xE9thode".b).to_str
+ }.to raise_error(ArgumentError, "invalid byte sequence in UTF-8")
+ 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/")
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 2022-08-19 12:48:27.000000000 +0200
+++ new/spec/addressable/uri_spec.rb 2023-04-09 17:02:36.000000000 +0200
@@ -3021,6 +3021,20 @@
end
end
+describe Addressable::URI, "when parsed with empty port" do
+ subject(:uri) do
+ Addressable::URI.parse("//example.com:")
+ end
+
+ it "should not infer a port" do
+ expect(uri.port).to be(nil)
+ end
+
+ it "should have a site value of '//example.com'" do
+ expect(uri.site).to eq("//example.com")
+ end
+end
+
describe Addressable::URI, "when parsed from " +
"'http://example.com/%2E/'" do
before do
@@ -5939,6 +5953,26 @@
end
end
+describe Addressable::URI, "when normalizing a path with special unicode" do
+ it "does not stop at or ignore null bytes" do
+ expect(Addressable::URI.parse("/path%00segment/").normalize.path).to eq(
+ "/path%00segment/"
+ )
+ end
+
+ it "does apply NFC unicode normalization" do
+ expect(Addressable::URI.parse("/%E2%84%A6").normalize.path).to eq(
+ "/%CE%A9"
+ )
+ end
+
+ it "does not apply NFKC unicode normalization" do
+ expect(Addressable::URI.parse("/%C2%AF%C2%A0").normalize.path).to eq(
+ "/%C2%AF%C2%A0"
+ )
+ end
+end
+
describe Addressable::URI, "when normalizing a partially encoded string" do
it "should result in correct percent encoded sequence" do
expect(Addressable::URI.normalize_component(
@@ -6743,3 +6777,25 @@
).to eq(main)
end
end
+
+describe Addressable::URI, "when deferring validation" do
+ subject(:deferred) { uri.instance_variable_get(:@validation_deferred) }
+
+ let(:uri) { Addressable::URI.parse("http://example.com") }
+
+ it "defers validation within the block" do
+ uri.defer_validation do
+ expect(deferred).to be true
+ end
+ end
+
+ it "always resets deferral afterward" do
+ expect { uri.defer_validation { raise "boom" } }.to raise_error("boom")
+ expect(deferred).to be false
+ end
+
+ it "returns nil" do
+ res = uri.defer_validation {}
+ expect(res).to be nil
+ end
+end