addressable 2.8.1 → 2.8.5
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 +31 -2
- data/Rakefile +11 -5
- data/addressable.gemspec +28 -0
- data/lib/addressable/idna/native.rb +8 -2
- data/lib/addressable/idna/pure.rb +10 -182
- data/lib/addressable/template.rb +9 -10
- data/lib/addressable/uri.rb +145 -114
- data/lib/addressable/version.rb +1 -1
- data/spec/addressable/idna_spec.rb +6 -5
- data/spec/addressable/template_spec.rb +60 -264
- data/spec/addressable/uri_spec.rb +95 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b7d4ea3b683b3b7c719ae54919505e8e98823b39e54cd68d3579319b61d9824
|
4
|
+
data.tar.gz: d09b61eba34544826aec64909b848b53549ae64059e09cc5f462991a59fd2465
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37927e878581e256a98ac619723a90f7b7a2d5b655ef613872a4f963ffdccabc6f0b761b65673fc6929509b0f783b48460b2643ac33c2d076bc5234e4126573b
|
7
|
+
data.tar.gz: 3afd1d272e41f97959bc8b34188b8d9fc419fcc01af9ea8a955d3ee2e6f57e3417d5ec6c58378e6b29fedb15e948ace7c080cd2c3739d6e24a4dd04eb3fa3f70
|
data/CHANGELOG.md
CHANGED
@@ -1,13 +1,42 @@
|
|
1
|
+
# Addressable 2.8.5
|
2
|
+
- Fix thread safety issue with encoding tables ([#515])
|
3
|
+
- Define URI::NONE as a module to avoid serialization issues ([#509])
|
4
|
+
- Fix YAML serialization ([#508])
|
5
|
+
|
6
|
+
[#508]: https://github.com/sporkmonger/addressable/pull/508
|
7
|
+
[#509]: https://github.com/sporkmonger/addressable/pull/509
|
8
|
+
[#515]: https://github.com/sporkmonger/addressable/pull/515
|
9
|
+
|
10
|
+
# Addressable 2.8.4
|
11
|
+
- Restore `Addressable::IDNA.unicode_normalize_kc` as a deprecated method ([#504])
|
12
|
+
|
13
|
+
[#504]: https://github.com/sporkmonger/addressable/pull/504
|
14
|
+
|
15
|
+
# Addressable 2.8.3
|
16
|
+
- Fix template expand level 2 hash support for non-string objects ([#499], [#498])
|
17
|
+
|
18
|
+
[#499]: https://github.com/sporkmonger/addressable/pull/499
|
19
|
+
[#498]: https://github.com/sporkmonger/addressable/pull/498
|
20
|
+
|
21
|
+
# Addressable 2.8.2
|
22
|
+
- Improve cache hits and JIT friendliness ([#486](https://github.com/sporkmonger/addressable/pull/486))
|
23
|
+
- Improve code style and test coverage ([#482](https://github.com/sporkmonger/addressable/pull/482))
|
24
|
+
- Ensure reset of deferred validation ([#481](https://github.com/sporkmonger/addressable/pull/481))
|
25
|
+
- Resolve normalization differences between `IDNA::Native` and `IDNA::Pure` ([#408](https://github.com/sporkmonger/addressable/issues/408), [#492])
|
26
|
+
- 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])
|
27
|
+
|
28
|
+
[#492]: https://github.com/sporkmonger/addressable/pull/492
|
29
|
+
|
1
30
|
# Addressable 2.8.1
|
2
31
|
- refactor `Addressable::URI.normalize_path` to address linter offenses ([#430](https://github.com/sporkmonger/addressable/pull/430))
|
3
|
-
- remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY` regex ([#438](https://github.com/sporkmonger/addressable/pull/438))
|
4
32
|
- update gemspec to reflect supported Ruby versions ([#466], [#464], [#463])
|
5
33
|
- compatibility w/ public_suffix 5.x ([#466], [#465], [#460])
|
6
34
|
- fixes "invalid byte sequence in UTF-8" exception when unencoding URLs containing non UTF-8 characters ([#459](https://github.com/sporkmonger/addressable/pull/459))
|
7
|
-
- `Ractor` compatibility ([#449]
|
35
|
+
- `Ractor` compatibility ([#449])
|
8
36
|
- use the whole string instead of a single line for template match ([#431](https://github.com/sporkmonger/addressable/pull/431))
|
9
37
|
- force UTF-8 encoding only if needed ([#341](https://github.com/sporkmonger/addressable/pull/341))
|
10
38
|
|
39
|
+
[#449]: https://github.com/sporkmonger/addressable/pull/449
|
11
40
|
[#460]: https://github.com/sporkmonger/addressable/pull/460
|
12
41
|
[#463]: https://github.com/sporkmonger/addressable/pull/463
|
13
42
|
[#464]: https://github.com/sporkmonger/addressable/pull/464
|
data/Rakefile
CHANGED
@@ -20,11 +20,17 @@ additionally provides extensive support for IRIs and URI templates.
|
|
20
20
|
TEXT
|
21
21
|
|
22
22
|
PKG_FILES = FileList[
|
23
|
-
"
|
24
|
-
"
|
25
|
-
"
|
26
|
-
|
27
|
-
|
23
|
+
"data/**/*",
|
24
|
+
"lib/**/*.rb",
|
25
|
+
"spec/**/*.rb",
|
26
|
+
"tasks/**/*.rake",
|
27
|
+
"addressable.gemspec",
|
28
|
+
"CHANGELOG.md",
|
29
|
+
"Gemfile",
|
30
|
+
"LICENSE.txt",
|
31
|
+
"README.md",
|
32
|
+
"Rakefile",
|
33
|
+
]
|
28
34
|
|
29
35
|
task :default => "spec"
|
30
36
|
|
data/addressable.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: addressable 2.8.5 ruby lib
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "addressable".freeze
|
6
|
+
s.version = "2.8.5"
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
|
+
s.metadata = { "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md" } if s.respond_to? :metadata=
|
10
|
+
s.require_paths = ["lib".freeze]
|
11
|
+
s.authors = ["Bob Aman".freeze]
|
12
|
+
s.date = "2023-08-03"
|
13
|
+
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
|
14
|
+
s.email = "bob@sporkmonger.com".freeze
|
15
|
+
s.extra_rdoc_files = ["README.md".freeze]
|
16
|
+
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]
|
17
|
+
s.homepage = "https://github.com/sporkmonger/addressable".freeze
|
18
|
+
s.licenses = ["Apache-2.0".freeze]
|
19
|
+
s.rdoc_options = ["--main".freeze, "README.md".freeze]
|
20
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze)
|
21
|
+
s.rubygems_version = "3.4.18".freeze
|
22
|
+
s.summary = "URI Implementation".freeze
|
23
|
+
|
24
|
+
s.specification_version = 4
|
25
|
+
|
26
|
+
s.add_runtime_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 6.0"])
|
27
|
+
s.add_development_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
|
28
|
+
end
|
@@ -29,8 +29,14 @@ module Addressable
|
|
29
29
|
IDN::Punycode.decode(value.to_s)
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
class << self
|
33
|
+
# @deprecated Use {String#unicode_normalize(:nfkc)} instead
|
34
|
+
def unicode_normalize_kc(value)
|
35
|
+
value.to_s.unicode_normalize(:nfkc)
|
36
|
+
end
|
37
|
+
|
38
|
+
extend Gem::Deprecate
|
39
|
+
deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4
|
34
40
|
end
|
35
41
|
|
36
42
|
def self.to_ascii(value)
|
@@ -66,7 +66,7 @@ module Addressable
|
|
66
66
|
# domain name as described in RFC 3490.
|
67
67
|
def self.to_ascii(input)
|
68
68
|
input = input.to_s unless input.is_a?(String)
|
69
|
-
input = input.dup
|
69
|
+
input = input.dup.force_encoding(Encoding::UTF_8).unicode_normalize(:nfkc)
|
70
70
|
if input.respond_to?(:force_encoding)
|
71
71
|
input.force_encoding(Encoding::ASCII_8BIT)
|
72
72
|
end
|
@@ -77,7 +77,7 @@ module Addressable
|
|
77
77
|
part.force_encoding(Encoding::ASCII_8BIT)
|
78
78
|
end
|
79
79
|
if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE
|
80
|
-
ACE_PREFIX + punycode_encode(
|
80
|
+
ACE_PREFIX + punycode_encode(part)
|
81
81
|
else
|
82
82
|
part
|
83
83
|
end
|
@@ -112,13 +112,14 @@ module Addressable
|
|
112
112
|
output
|
113
113
|
end
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
115
|
+
class << self
|
116
|
+
# @deprecated Use {String#unicode_normalize(:nfkc)} instead
|
117
|
+
def unicode_normalize_kc(value)
|
118
|
+
value.to_s.unicode_normalize(:nfkc)
|
119
|
+
end
|
120
|
+
|
121
|
+
extend Gem::Deprecate
|
122
|
+
deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4
|
122
123
|
end
|
123
124
|
|
124
125
|
##
|
@@ -136,164 +137,6 @@ module Addressable
|
|
136
137
|
end
|
137
138
|
private_class_method :unicode_downcase
|
138
139
|
|
139
|
-
def self.unicode_compose(unpacked)
|
140
|
-
unpacked_result = []
|
141
|
-
length = unpacked.length
|
142
|
-
|
143
|
-
return unpacked if length == 0
|
144
|
-
|
145
|
-
starter = unpacked[0]
|
146
|
-
starter_cc = lookup_unicode_combining_class(starter)
|
147
|
-
starter_cc = 256 if starter_cc != 0
|
148
|
-
for i in 1...length
|
149
|
-
ch = unpacked[i]
|
150
|
-
|
151
|
-
if (starter_cc == 0 &&
|
152
|
-
(composite = unicode_compose_pair(starter, ch)) != nil)
|
153
|
-
starter = composite
|
154
|
-
else
|
155
|
-
unpacked_result << starter
|
156
|
-
starter = ch
|
157
|
-
end
|
158
|
-
end
|
159
|
-
unpacked_result << starter
|
160
|
-
return unpacked_result
|
161
|
-
end
|
162
|
-
private_class_method :unicode_compose
|
163
|
-
|
164
|
-
def self.unicode_compose_pair(ch_one, ch_two)
|
165
|
-
if ch_one >= HANGUL_LBASE && ch_one < HANGUL_LBASE + HANGUL_LCOUNT &&
|
166
|
-
ch_two >= HANGUL_VBASE && ch_two < HANGUL_VBASE + HANGUL_VCOUNT
|
167
|
-
# Hangul L + V
|
168
|
-
return HANGUL_SBASE + (
|
169
|
-
(ch_one - HANGUL_LBASE) * HANGUL_VCOUNT + (ch_two - HANGUL_VBASE)
|
170
|
-
) * HANGUL_TCOUNT
|
171
|
-
elsif ch_one >= HANGUL_SBASE &&
|
172
|
-
ch_one < HANGUL_SBASE + HANGUL_SCOUNT &&
|
173
|
-
(ch_one - HANGUL_SBASE) % HANGUL_TCOUNT == 0 &&
|
174
|
-
ch_two >= HANGUL_TBASE && ch_two < HANGUL_TBASE + HANGUL_TCOUNT
|
175
|
-
# Hangul LV + T
|
176
|
-
return ch_one + (ch_two - HANGUL_TBASE)
|
177
|
-
end
|
178
|
-
|
179
|
-
p = []
|
180
|
-
|
181
|
-
ucs4_to_utf8(ch_one, p)
|
182
|
-
ucs4_to_utf8(ch_two, p)
|
183
|
-
|
184
|
-
return lookup_unicode_composition(p)
|
185
|
-
end
|
186
|
-
private_class_method :unicode_compose_pair
|
187
|
-
|
188
|
-
def self.ucs4_to_utf8(char, buffer)
|
189
|
-
if char < 128
|
190
|
-
buffer << char
|
191
|
-
elsif char < 2048
|
192
|
-
buffer << (char >> 6 | 192)
|
193
|
-
buffer << (char & 63 | 128)
|
194
|
-
elsif char < 0x10000
|
195
|
-
buffer << (char >> 12 | 224)
|
196
|
-
buffer << (char >> 6 & 63 | 128)
|
197
|
-
buffer << (char & 63 | 128)
|
198
|
-
elsif char < 0x200000
|
199
|
-
buffer << (char >> 18 | 240)
|
200
|
-
buffer << (char >> 12 & 63 | 128)
|
201
|
-
buffer << (char >> 6 & 63 | 128)
|
202
|
-
buffer << (char & 63 | 128)
|
203
|
-
elsif char < 0x4000000
|
204
|
-
buffer << (char >> 24 | 248)
|
205
|
-
buffer << (char >> 18 & 63 | 128)
|
206
|
-
buffer << (char >> 12 & 63 | 128)
|
207
|
-
buffer << (char >> 6 & 63 | 128)
|
208
|
-
buffer << (char & 63 | 128)
|
209
|
-
elsif char < 0x80000000
|
210
|
-
buffer << (char >> 30 | 252)
|
211
|
-
buffer << (char >> 24 & 63 | 128)
|
212
|
-
buffer << (char >> 18 & 63 | 128)
|
213
|
-
buffer << (char >> 12 & 63 | 128)
|
214
|
-
buffer << (char >> 6 & 63 | 128)
|
215
|
-
buffer << (char & 63 | 128)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
private_class_method :ucs4_to_utf8
|
219
|
-
|
220
|
-
def self.unicode_sort_canonical(unpacked)
|
221
|
-
unpacked = unpacked.dup
|
222
|
-
i = 1
|
223
|
-
length = unpacked.length
|
224
|
-
|
225
|
-
return unpacked if length < 2
|
226
|
-
|
227
|
-
while i < length
|
228
|
-
last = unpacked[i-1]
|
229
|
-
ch = unpacked[i]
|
230
|
-
last_cc = lookup_unicode_combining_class(last)
|
231
|
-
cc = lookup_unicode_combining_class(ch)
|
232
|
-
if cc != 0 && last_cc != 0 && last_cc > cc
|
233
|
-
unpacked[i] = last
|
234
|
-
unpacked[i-1] = ch
|
235
|
-
i -= 1 if i > 1
|
236
|
-
else
|
237
|
-
i += 1
|
238
|
-
end
|
239
|
-
end
|
240
|
-
return unpacked
|
241
|
-
end
|
242
|
-
private_class_method :unicode_sort_canonical
|
243
|
-
|
244
|
-
def self.unicode_decompose(unpacked)
|
245
|
-
unpacked_result = []
|
246
|
-
for cp in unpacked
|
247
|
-
if cp >= HANGUL_SBASE && cp < HANGUL_SBASE + HANGUL_SCOUNT
|
248
|
-
l, v, t = unicode_decompose_hangul(cp)
|
249
|
-
unpacked_result << l
|
250
|
-
unpacked_result << v if v
|
251
|
-
unpacked_result << t if t
|
252
|
-
else
|
253
|
-
dc = lookup_unicode_compatibility(cp)
|
254
|
-
unless dc
|
255
|
-
unpacked_result << cp
|
256
|
-
else
|
257
|
-
unpacked_result.concat(unicode_decompose(dc.unpack("U*")))
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
return unpacked_result
|
262
|
-
end
|
263
|
-
private_class_method :unicode_decompose
|
264
|
-
|
265
|
-
def self.unicode_decompose_hangul(codepoint)
|
266
|
-
sindex = codepoint - HANGUL_SBASE;
|
267
|
-
if sindex < 0 || sindex >= HANGUL_SCOUNT
|
268
|
-
l = codepoint
|
269
|
-
v = t = nil
|
270
|
-
return l, v, t
|
271
|
-
end
|
272
|
-
l = HANGUL_LBASE + sindex / HANGUL_NCOUNT
|
273
|
-
v = HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
|
274
|
-
t = HANGUL_TBASE + sindex % HANGUL_TCOUNT
|
275
|
-
if t == HANGUL_TBASE
|
276
|
-
t = nil
|
277
|
-
end
|
278
|
-
return l, v, t
|
279
|
-
end
|
280
|
-
private_class_method :unicode_decompose_hangul
|
281
|
-
|
282
|
-
def self.lookup_unicode_combining_class(codepoint)
|
283
|
-
codepoint_data = UNICODE_DATA[codepoint]
|
284
|
-
(codepoint_data ?
|
285
|
-
(codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) :
|
286
|
-
0)
|
287
|
-
end
|
288
|
-
private_class_method :lookup_unicode_combining_class
|
289
|
-
|
290
|
-
def self.lookup_unicode_compatibility(codepoint)
|
291
|
-
codepoint_data = UNICODE_DATA[codepoint]
|
292
|
-
(codepoint_data ?
|
293
|
-
codepoint_data[UNICODE_DATA_COMPATIBILITY] : nil)
|
294
|
-
end
|
295
|
-
private_class_method :lookup_unicode_compatibility
|
296
|
-
|
297
140
|
def self.lookup_unicode_lowercase(codepoint)
|
298
141
|
codepoint_data = UNICODE_DATA[codepoint]
|
299
142
|
(codepoint_data ?
|
@@ -302,21 +145,6 @@ module Addressable
|
|
302
145
|
end
|
303
146
|
private_class_method :lookup_unicode_lowercase
|
304
147
|
|
305
|
-
def self.lookup_unicode_composition(unpacked)
|
306
|
-
return COMPOSITION_TABLE[unpacked]
|
307
|
-
end
|
308
|
-
private_class_method :lookup_unicode_composition
|
309
|
-
|
310
|
-
HANGUL_SBASE = 0xac00
|
311
|
-
HANGUL_LBASE = 0x1100
|
312
|
-
HANGUL_LCOUNT = 19
|
313
|
-
HANGUL_VBASE = 0x1161
|
314
|
-
HANGUL_VCOUNT = 21
|
315
|
-
HANGUL_TBASE = 0x11a7
|
316
|
-
HANGUL_TCOUNT = 28
|
317
|
-
HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT # 588
|
318
|
-
HANGUL_SCOUNT = HANGUL_LCOUNT * HANGUL_NCOUNT # 11172
|
319
|
-
|
320
148
|
UNICODE_DATA_COMBINING_CLASS = 0
|
321
149
|
UNICODE_DATA_EXCLUSION = 1
|
322
150
|
UNICODE_DATA_CANONICAL = 2
|
data/lib/addressable/template.rb
CHANGED
@@ -892,25 +892,24 @@ module Addressable
|
|
892
892
|
# operator.
|
893
893
|
#
|
894
894
|
# @param [Hash, Array, String] value
|
895
|
-
# Normalizes keys and values with
|
895
|
+
# Normalizes unicode keys and values with String#unicode_normalize (NFC)
|
896
896
|
#
|
897
897
|
# @return [Hash, Array, String] The normalized values
|
898
898
|
def normalize_value(value)
|
899
|
-
unless value.is_a?(Hash)
|
900
|
-
value = value.respond_to?(:to_ary) ? value.to_ary : value.to_str
|
901
|
-
end
|
902
|
-
|
903
899
|
# Handle unicode normalization
|
904
|
-
if value.
|
905
|
-
value.map! { |val|
|
900
|
+
if value.respond_to?(:to_ary)
|
901
|
+
value.to_ary.map! { |val| normalize_value(val) }
|
906
902
|
elsif value.kind_of?(Hash)
|
907
903
|
value = value.inject({}) { |acc, (k, v)|
|
908
|
-
acc[
|
909
|
-
Addressable::IDNA.unicode_normalize_kc(v)
|
904
|
+
acc[normalize_value(k)] = normalize_value(v)
|
910
905
|
acc
|
911
906
|
}
|
912
907
|
else
|
913
|
-
value =
|
908
|
+
value = value.to_s if !value.kind_of?(String)
|
909
|
+
if value.encoding != Encoding::UTF_8
|
910
|
+
value = value.dup.force_encoding(Encoding::UTF_8)
|
911
|
+
end
|
912
|
+
value = value.unicode_normalize(:nfc)
|
914
913
|
end
|
915
914
|
value
|
916
915
|
end
|