addressable 2.8.0 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/Gemfile +4 -2
- data/Rakefile +2 -1
- data/addressable.gemspec +9 -18
- data/lib/addressable/idna/native.rb +0 -5
- data/lib/addressable/idna/pure.rb +2 -185
- data/lib/addressable/idna.rb +0 -1
- data/lib/addressable/template.rb +10 -9
- data/lib/addressable/uri.rb +168 -148
- data/lib/addressable/version.rb +1 -2
- data/spec/addressable/idna_spec.rb +6 -6
- data/spec/addressable/net_http_compat_spec.rb +0 -1
- data/spec/addressable/security_spec.rb +0 -1
- data/spec/addressable/template_spec.rb +33 -1
- data/spec/addressable/uri_spec.rb +137 -1
- data/tasks/gem.rake +5 -2
- metadata +11 -10
data/lib/addressable/version.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# encoding:utf-8
|
|
4
3
|
#--
|
|
5
4
|
# Copyright (C) Bob Aman
|
|
6
5
|
#
|
|
@@ -24,7 +23,7 @@ if !defined?(Addressable::VERSION)
|
|
|
24
23
|
module VERSION
|
|
25
24
|
MAJOR = 2
|
|
26
25
|
MINOR = 8
|
|
27
|
-
TINY =
|
|
26
|
+
TINY = 2
|
|
28
27
|
|
|
29
28
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
|
30
29
|
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# coding: utf-8
|
|
4
3
|
# Copyright (C) Bob Aman
|
|
5
4
|
#
|
|
6
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -39,6 +38,12 @@ shared_examples_for "converting from unicode to ASCII" do
|
|
|
39
38
|
)).to eq("www.xn--8ws00zhy3a.com")
|
|
40
39
|
end
|
|
41
40
|
|
|
41
|
+
it "also accepts unicode strings encoded as ascii-8bit" do
|
|
42
|
+
expect(Addressable::IDNA.to_ascii(
|
|
43
|
+
"www.詹姆斯.com".b
|
|
44
|
+
)).to eq("www.xn--8ws00zhy3a.com")
|
|
45
|
+
end
|
|
46
|
+
|
|
42
47
|
it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
|
|
43
48
|
"www.Iñtërnâtiônàlizætiøn.com"
|
|
44
49
|
expect(Addressable::IDNA.to_ascii(
|
|
@@ -250,11 +255,6 @@ shared_examples_for "converting from ASCII to unicode" do
|
|
|
250
255
|
"example..host"
|
|
251
256
|
)).to eq("example..host")
|
|
252
257
|
end
|
|
253
|
-
|
|
254
|
-
it "should normalize 'string' correctly" do
|
|
255
|
-
expect(Addressable::IDNA.unicode_normalize_kc(:'string')).to eq("string")
|
|
256
|
-
expect(Addressable::IDNA.unicode_normalize_kc("string")).to eq("string")
|
|
257
|
-
end
|
|
258
258
|
end
|
|
259
259
|
|
|
260
260
|
describe Addressable::IDNA, "when using the pure-Ruby implementation" do
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# coding: utf-8
|
|
4
3
|
# Copyright (C) Bob Aman
|
|
5
4
|
#
|
|
6
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -78,6 +77,15 @@ describe "==" do
|
|
|
78
77
|
end
|
|
79
78
|
end
|
|
80
79
|
|
|
80
|
+
describe "#to_regexp" do
|
|
81
|
+
it "does not match the first line of multiline strings" do
|
|
82
|
+
uri = "https://www.example.com/bar"
|
|
83
|
+
template = Addressable::Template.new(uri)
|
|
84
|
+
expect(template.match(uri)).not_to be_nil
|
|
85
|
+
expect(template.match("#{uri}\ngarbage")).to be_nil
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
81
89
|
describe "Type conversion" do
|
|
82
90
|
subject {
|
|
83
91
|
{
|
|
@@ -1013,6 +1021,19 @@ describe Addressable::Template do
|
|
|
1013
1021
|
)
|
|
1014
1022
|
end
|
|
1015
1023
|
|
|
1024
|
+
it "normalizes as unicode even with wrong encoding specified" do
|
|
1025
|
+
template = subject.partial_expand("query" => "Cafe\u0301".b)
|
|
1026
|
+
expect(template.pattern).to eq(
|
|
1027
|
+
"http://example.com/{resource}/Caf%C3%A9/"
|
|
1028
|
+
)
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
it "raises on invalid unicode input" do
|
|
1032
|
+
expect {
|
|
1033
|
+
subject.partial_expand("query" => "M\xE9thode".b)
|
|
1034
|
+
}.to raise_error(ArgumentError, "invalid byte sequence in UTF-8")
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1016
1037
|
it "does not normalize unicode when byte semantics requested" do
|
|
1017
1038
|
template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
|
|
1018
1039
|
expect(template.pattern).to eq(
|
|
@@ -1073,6 +1094,17 @@ describe Addressable::Template do
|
|
|
1073
1094
|
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
|
|
1074
1095
|
end
|
|
1075
1096
|
|
|
1097
|
+
it "normalizes as unicode even with wrong encoding specified" do
|
|
1098
|
+
uri = subject.expand("query" => "Cafe\u0301".b).to_str
|
|
1099
|
+
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
|
|
1100
|
+
end
|
|
1101
|
+
|
|
1102
|
+
it "raises on invalid unicode input" do
|
|
1103
|
+
expect {
|
|
1104
|
+
subject.expand("query" => "M\xE9thode".b).to_str
|
|
1105
|
+
}.to raise_error(ArgumentError, "invalid byte sequence in UTF-8")
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1076
1108
|
it "does not normalize unicode when byte semantics requested" do
|
|
1077
1109
|
uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
|
|
1078
1110
|
expect(uri).to eq("http://example.com/search/Cafe%CC%81/")
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# coding: utf-8
|
|
4
3
|
# Copyright (C) Bob Aman
|
|
5
4
|
#
|
|
6
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -999,6 +998,72 @@ describe Addressable::URI, "when frozen" do
|
|
|
999
998
|
end
|
|
1000
999
|
end
|
|
1001
1000
|
|
|
1001
|
+
describe Addressable::URI, "when normalized and then deeply frozen" do
|
|
1002
|
+
before do
|
|
1003
|
+
@uri = Addressable::URI.parse(
|
|
1004
|
+
"http://user:password@example.com:8080/path?query=value#fragment"
|
|
1005
|
+
).normalize!
|
|
1006
|
+
|
|
1007
|
+
@uri.instance_variables.each do |var|
|
|
1008
|
+
@uri.instance_variable_set(var, @uri.instance_variable_get(var).freeze)
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
@uri.freeze
|
|
1012
|
+
end
|
|
1013
|
+
|
|
1014
|
+
it "#normalized_scheme should not error" do
|
|
1015
|
+
expect { @uri.normalized_scheme }.not_to raise_error
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
it "#normalized_user should not error" do
|
|
1019
|
+
expect { @uri.normalized_user }.not_to raise_error
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
it "#normalized_password should not error" do
|
|
1023
|
+
expect { @uri.normalized_password }.not_to raise_error
|
|
1024
|
+
end
|
|
1025
|
+
|
|
1026
|
+
it "#normalized_userinfo should not error" do
|
|
1027
|
+
expect { @uri.normalized_userinfo }.not_to raise_error
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1030
|
+
it "#normalized_host should not error" do
|
|
1031
|
+
expect { @uri.normalized_host }.not_to raise_error
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
it "#normalized_authority should not error" do
|
|
1035
|
+
expect { @uri.normalized_authority }.not_to raise_error
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
it "#normalized_port should not error" do
|
|
1039
|
+
expect { @uri.normalized_port }.not_to raise_error
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
it "#normalized_site should not error" do
|
|
1043
|
+
expect { @uri.normalized_site }.not_to raise_error
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
it "#normalized_path should not error" do
|
|
1047
|
+
expect { @uri.normalized_path }.not_to raise_error
|
|
1048
|
+
end
|
|
1049
|
+
|
|
1050
|
+
it "#normalized_query should not error" do
|
|
1051
|
+
expect { @uri.normalized_query }.not_to raise_error
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
it "#normalized_fragment should not error" do
|
|
1055
|
+
expect { @uri.normalized_fragment }.not_to raise_error
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
it "should be frozen" do
|
|
1059
|
+
expect(@uri).to be_frozen
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
it "should not allow destructive operations" do
|
|
1063
|
+
expect { @uri.normalize! }.to raise_error(RuntimeError)
|
|
1064
|
+
end
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1002
1067
|
describe Addressable::URI, "when created from string components" do
|
|
1003
1068
|
before do
|
|
1004
1069
|
@uri = Addressable::URI.new(
|
|
@@ -2956,6 +3021,20 @@ describe Addressable::URI, "when parsed from " +
|
|
|
2956
3021
|
end
|
|
2957
3022
|
end
|
|
2958
3023
|
|
|
3024
|
+
describe Addressable::URI, "when parsed with empty port" do
|
|
3025
|
+
subject(:uri) do
|
|
3026
|
+
Addressable::URI.parse("//example.com:")
|
|
3027
|
+
end
|
|
3028
|
+
|
|
3029
|
+
it "should not infer a port" do
|
|
3030
|
+
expect(uri.port).to be(nil)
|
|
3031
|
+
end
|
|
3032
|
+
|
|
3033
|
+
it "should have a site value of '//example.com'" do
|
|
3034
|
+
expect(uri.site).to eq("//example.com")
|
|
3035
|
+
end
|
|
3036
|
+
end
|
|
3037
|
+
|
|
2959
3038
|
describe Addressable::URI, "when parsed from " +
|
|
2960
3039
|
"'http://example.com/%2E/'" do
|
|
2961
3040
|
before do
|
|
@@ -5874,6 +5953,26 @@ describe Addressable::URI, "when normalizing a path with an encoded slash" do
|
|
|
5874
5953
|
end
|
|
5875
5954
|
end
|
|
5876
5955
|
|
|
5956
|
+
describe Addressable::URI, "when normalizing a path with special unicode" do
|
|
5957
|
+
it "does not stop at or ignore null bytes" do
|
|
5958
|
+
expect(Addressable::URI.parse("/path%00segment/").normalize.path).to eq(
|
|
5959
|
+
"/path%00segment/"
|
|
5960
|
+
)
|
|
5961
|
+
end
|
|
5962
|
+
|
|
5963
|
+
it "does apply NFC unicode normalization" do
|
|
5964
|
+
expect(Addressable::URI.parse("/%E2%84%A6").normalize.path).to eq(
|
|
5965
|
+
"/%CE%A9"
|
|
5966
|
+
)
|
|
5967
|
+
end
|
|
5968
|
+
|
|
5969
|
+
it "does not apply NFKC unicode normalization" do
|
|
5970
|
+
expect(Addressable::URI.parse("/%C2%AF%C2%A0").normalize.path).to eq(
|
|
5971
|
+
"/%C2%AF%C2%A0"
|
|
5972
|
+
)
|
|
5973
|
+
end
|
|
5974
|
+
end
|
|
5975
|
+
|
|
5877
5976
|
describe Addressable::URI, "when normalizing a partially encoded string" do
|
|
5878
5977
|
it "should result in correct percent encoded sequence" do
|
|
5879
5978
|
expect(Addressable::URI.normalize_component(
|
|
@@ -5993,6 +6092,11 @@ describe Addressable::URI, "when unencoding a multibyte string" do
|
|
|
5993
6092
|
expect(Addressable::URI.unencode_component("ski=%BA%DAɫ")).to eq("ski=\xBA\xDAɫ")
|
|
5994
6093
|
end
|
|
5995
6094
|
|
|
6095
|
+
it "should not fail with UTF-8 incompatible string" do
|
|
6096
|
+
url = "/M%E9/\xE9?p=\xFC".b
|
|
6097
|
+
expect(Addressable::URI.unencode_component(url)).to eq("/M\xE9/\xE9?p=\xFC")
|
|
6098
|
+
end
|
|
6099
|
+
|
|
5996
6100
|
it "should result in correct percent encoded sequence as a URI" do
|
|
5997
6101
|
expect(Addressable::URI.unencode(
|
|
5998
6102
|
"/path?g%C3%BCnther", ::Addressable::URI
|
|
@@ -6663,3 +6767,35 @@ describe Addressable::URI, "when initializing a subclass of Addressable::URI" do
|
|
|
6663
6767
|
expect(@uri.class).to eq(@uri.join('path').class)
|
|
6664
6768
|
end
|
|
6665
6769
|
end
|
|
6770
|
+
|
|
6771
|
+
describe Addressable::URI, "when initialized in a non-main `Ractor`" do
|
|
6772
|
+
it "should have the same value as if used in the main `Ractor`" do
|
|
6773
|
+
pending("Ruby 3.0+ for `Ractor` support") unless defined?(Ractor)
|
|
6774
|
+
main = Addressable::URI.parse("http://example.com")
|
|
6775
|
+
expect(
|
|
6776
|
+
Ractor.new { Addressable::URI.parse("http://example.com") }.take
|
|
6777
|
+
).to eq(main)
|
|
6778
|
+
end
|
|
6779
|
+
end
|
|
6780
|
+
|
|
6781
|
+
describe Addressable::URI, "when deferring validation" do
|
|
6782
|
+
subject(:deferred) { uri.instance_variable_get(:@validation_deferred) }
|
|
6783
|
+
|
|
6784
|
+
let(:uri) { Addressable::URI.parse("http://example.com") }
|
|
6785
|
+
|
|
6786
|
+
it "defers validation within the block" do
|
|
6787
|
+
uri.defer_validation do
|
|
6788
|
+
expect(deferred).to be true
|
|
6789
|
+
end
|
|
6790
|
+
end
|
|
6791
|
+
|
|
6792
|
+
it "always resets deferral afterward" do
|
|
6793
|
+
expect { uri.defer_validation { raise "boom" } }.to raise_error("boom")
|
|
6794
|
+
expect(deferred).to be false
|
|
6795
|
+
end
|
|
6796
|
+
|
|
6797
|
+
it "returns nil" do
|
|
6798
|
+
res = uri.defer_validation {}
|
|
6799
|
+
expect(res).to be nil
|
|
6800
|
+
end
|
|
6801
|
+
end
|
data/tasks/gem.rake
CHANGED
|
@@ -19,9 +19,9 @@ namespace :gem do
|
|
|
19
19
|
exit(1)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
s.required_ruby_version = ">= 2.
|
|
22
|
+
s.required_ruby_version = ">= 2.2"
|
|
23
23
|
|
|
24
|
-
s.add_runtime_dependency "public_suffix", ">= 2.0.2", "<
|
|
24
|
+
s.add_runtime_dependency "public_suffix", ">= 2.0.2", "< 6.0"
|
|
25
25
|
s.add_development_dependency "bundler", ">= 1.0", "< 3.0"
|
|
26
26
|
|
|
27
27
|
s.require_path = "lib"
|
|
@@ -30,6 +30,9 @@ namespace :gem do
|
|
|
30
30
|
s.email = "bob@sporkmonger.com"
|
|
31
31
|
s.homepage = "https://github.com/sporkmonger/addressable"
|
|
32
32
|
s.license = "Apache-2.0"
|
|
33
|
+
s.metadata = {
|
|
34
|
+
"changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md"
|
|
35
|
+
}
|
|
33
36
|
end
|
|
34
37
|
|
|
35
38
|
Gem::PackageTask.new(GEM_SPEC) do |p|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: addressable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.8.
|
|
4
|
+
version: 2.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bob Aman
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-04-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: public_suffix
|
|
@@ -19,7 +19,7 @@ dependencies:
|
|
|
19
19
|
version: 2.0.2
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '
|
|
22
|
+
version: '6.0'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +29,7 @@ dependencies:
|
|
|
29
29
|
version: 2.0.2
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '6.0'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: bundler
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -90,8 +90,9 @@ files:
|
|
|
90
90
|
homepage: https://github.com/sporkmonger/addressable
|
|
91
91
|
licenses:
|
|
92
92
|
- Apache-2.0
|
|
93
|
-
metadata:
|
|
94
|
-
|
|
93
|
+
metadata:
|
|
94
|
+
changelog_uri: https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md
|
|
95
|
+
post_install_message:
|
|
95
96
|
rdoc_options:
|
|
96
97
|
- "--main"
|
|
97
98
|
- README.md
|
|
@@ -101,15 +102,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
101
102
|
requirements:
|
|
102
103
|
- - ">="
|
|
103
104
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: '2.
|
|
105
|
+
version: '2.2'
|
|
105
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
107
|
requirements:
|
|
107
108
|
- - ">="
|
|
108
109
|
- !ruby/object:Gem::Version
|
|
109
110
|
version: '0'
|
|
110
111
|
requirements: []
|
|
111
|
-
rubygems_version: 3.
|
|
112
|
-
signing_key:
|
|
112
|
+
rubygems_version: 3.4.8
|
|
113
|
+
signing_key:
|
|
113
114
|
specification_version: 4
|
|
114
115
|
summary: URI Implementation
|
|
115
116
|
test_files: []
|