addressable 2.8.0 → 2.8.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|