addressable 2.6.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: afa411655b3715e655e0cdca551d20df31b83491
4
- data.tar.gz: 0cd2871c45abb19f6b6238ad202856e7afb8619d
2
+ SHA256:
3
+ metadata.gz: 03a21b1eab156a16e90bd7963af85980edfbddc8f3dbe052766303dba76cc000
4
+ data.tar.gz: 03eca5d86f4c70f9320000f36e3cff4fd8023342a4e0ac855d0ef1ec89ee6183
5
5
  SHA512:
6
- metadata.gz: 16274bd51d38c58b3712dbbdad1368417051937dbe33d74fa73951a39b71d824092c0ecd50005d467db9c914cc074fd0344282df2e23e1182c764b1a1da9750a
7
- data.tar.gz: c53ff1d0e09a5e3d997a13a464d50c45fd7d548326f94d3ad40dc97753ce3a47aad4804a62faea48b89775394538982e70ac22d7488fab8ee6594b6816d8ff28
6
+ metadata.gz: d504f9475ad823f5bb077b9c039a2c91c83e52c20896247a7289b61725c61b1ddefe8ae06155fb018fc67087cf04276081b42105a18394b45e2374ad0b2fadb0
7
+ data.tar.gz: b81766fbcb9335d5ca94403b62d3b2a6fae31b66cd3c05f48e1885eaf07883bfa1321b6930271fe1415135aec687af51312a26ce27bd4b83b2ac6424dec597c9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ # Addressable 2.8.0
2
+ - fixes ReDoS vulnerability in Addressable::Template#match
3
+ - no longer replaces `+` with spaces in queries for non-http(s) schemes
4
+ - fixed encoding ipv6 literals
5
+ - the `:compacted` flag for `normalized_query` now dedupes parameters
6
+ - fix broken `escape_component` alias
7
+ - dropping support for Ruby 2.0 and 2.1
8
+ - adding Ruby 3.0 compatibility for development tasks
9
+ - drop support for `rack-mount` and remove Addressable::Template#generate
10
+ - performance improvements
11
+ - switch CI/CD to GitHub Actions
12
+
13
+ # Addressable 2.7.0
14
+ - added `:compacted` flag to `normalized_query`
15
+ - `heuristic_parse` handles `mailto:` more intuitively
16
+ - dropped explicit support for JRuby 9.0.5.0
17
+ - compatibility w/ public_suffix 4.x
18
+ - performance improvements
19
+
1
20
  # Addressable 2.6.0
2
21
  - added `tld=` method to allow assignment to the public suffix
3
22
  - most `heuristic_parse` patterns are now case-insensitive
data/Gemfile CHANGED
@@ -1,10 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
- gemspec
5
+ gemspec(path: __FILE__ == "(eval)" ? ".." : ".")
4
6
 
5
7
  group :test do
6
- gem 'rspec', '~> 3.5'
7
- gem 'rspec-its', '~> 1.1'
8
+ gem 'rspec', '~> 3.8'
9
+ gem 'rspec-its', '~> 1.3'
10
+ end
11
+
12
+ group :coverage do
13
+ gem "coveralls", "> 0.7", require: false, platforms: :mri
14
+ gem "simplecov", require: false
8
15
  end
9
16
 
10
17
  group :development do
@@ -14,19 +21,8 @@ group :development do
14
21
  end
15
22
 
16
23
  group :test, :development do
17
- gem 'rake', '> 10.0', '< 12'
18
- gem 'simplecov', :require => false
19
- gem 'coveralls', :require => false, :platforms => [
20
- :ruby_20, :ruby_21, :ruby_22, :ruby_23
21
- ]
22
- # Used to test compatibility.
23
- gem 'rack-mount', git: 'https://github.com/sporkmonger/rack-mount.git', require: 'rack/mount'
24
-
25
- if RUBY_VERSION.start_with?('2.0', '2.1')
26
- gem 'rack', '< 2', :require => false
27
- else
28
- gem 'rack', :require => false
29
- end
24
+ gem 'memory_profiler'
25
+ gem "rake", ">= 12.3.3"
30
26
  end
31
27
 
32
- gem 'idn-ruby', :platform => [:mri_20, :mri_21, :mri_22, :mri_23, :mri_24]
28
+ gem "idn-ruby", platform: :mri
data/README.md CHANGED
@@ -7,21 +7,23 @@
7
7
  <dt>License</dt><dd>Apache 2.0</dd>
8
8
  </dl>
9
9
 
10
- [![Gem Version](http://img.shields.io/gem/dt/addressable.svg)][gem]
11
- [![Build Status](https://secure.travis-ci.org/sporkmonger/addressable.svg?branch=master)][travis]
10
+ [![Gem Version](https://img.shields.io/gem/dt/addressable.svg)][gem]
11
+ [![Build Status](https://github.com/sporkmonger/addressable/workflows/CI/badge.svg)][actions]
12
12
  [![Test Coverage Status](https://img.shields.io/coveralls/sporkmonger/addressable.svg)][coveralls]
13
- [![Documentation Coverage Status](http://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch]
13
+ [![Documentation Coverage Status](https://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch]
14
14
 
15
15
  [gem]: https://rubygems.org/gems/addressable
16
- [travis]: http://travis-ci.org/sporkmonger/addressable
16
+ [actions]: https://github.com/sporkmonger/addressable/actions
17
17
  [coveralls]: https://coveralls.io/r/sporkmonger/addressable
18
- [inch]: http://inch-ci.org/github/sporkmonger/addressable
18
+ [inch]: https://inch-ci.org/github/sporkmonger/addressable
19
19
 
20
20
  # Description
21
21
 
22
- Addressable is a replacement for the URI implementation that is part of
23
- Ruby's standard library. It more closely conforms to RFC 3986, RFC 3987, and
24
- RFC 6570 (level 4), providing support for IRIs and URI templates.
22
+ Addressable is an alternative implementation to the URI implementation
23
+ that is part of Ruby's standard library. It is flexible, offers heuristic
24
+ parsing, and additionally provides extensive support for IRIs and URI templates.
25
+
26
+ Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4).
25
27
 
26
28
  # Reference
27
29
 
@@ -96,7 +98,7 @@ You may optionally turn on native IDN support by installing libidn and the
96
98
  idn gem:
97
99
 
98
100
  ```console
99
- $ sudo apt-get install idn # Debian/Ubuntu
101
+ $ sudo apt-get install libidn11-dev # Debian/Ubuntu
100
102
  $ brew install libidn # OS X
101
103
  $ gem install idn-ruby
102
104
  ```
@@ -108,7 +110,7 @@ dependency using a pessimistic version constraint covering the major and minor
108
110
  values:
109
111
 
110
112
  ```ruby
111
- spec.add_dependency 'addressable', '~> 2.5'
113
+ spec.add_dependency 'addressable', '~> 2.7'
112
114
  ```
113
115
 
114
116
  If you need a specific bug fix, you can also specify minimum tiny versions
data/Rakefile CHANGED
@@ -14,9 +14,9 @@ RELEASE_NAME = "REL #{PKG_VERSION}"
14
14
 
15
15
  PKG_SUMMARY = "URI Implementation"
16
16
  PKG_DESCRIPTION = <<-TEXT
17
- Addressable is a replacement for the URI implementation that is part of
18
- Ruby's standard library. It more closely conforms to the relevant RFCs and
19
- adds support for IRIs and URI templates.
17
+ Addressable is an alternative implementation to the URI implementation that is
18
+ part of Ruby's standard library. It is flexible, offers heuristic parsing, and
19
+ additionally provides extensive support for IRIs and URI templates.
20
20
  TEXT
21
21
 
22
22
  PKG_FILES = FileList[
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # stub: addressable 2.8.0 ruby lib
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "addressable".freeze
6
+ s.version = "2.8.0"
7
+
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
+ s.require_paths = ["lib".freeze]
10
+ s.authors = ["Bob Aman".freeze]
11
+ s.date = "2021-07-03"
12
+ 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
13
+ s.email = "bob@sporkmonger.com".freeze
14
+ s.extra_rdoc_files = ["README.md".freeze]
15
+ 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]
16
+ s.homepage = "https://github.com/sporkmonger/addressable".freeze
17
+ s.licenses = ["Apache-2.0".freeze]
18
+ s.rdoc_options = ["--main".freeze, "README.md".freeze]
19
+ s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
20
+ s.rubygems_version = "3.0.3".freeze
21
+ s.summary = "URI Implementation".freeze
22
+
23
+ if s.respond_to? :specification_version then
24
+ s.specification_version = 4
25
+
26
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 5.0"])
28
+ s.add_development_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
29
+ else
30
+ s.add_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 5.0"])
31
+ s.add_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 5.0"])
35
+ s.add_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
36
+ end
37
+ end
@@ -135,7 +135,7 @@ module Addressable
135
135
  unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) }
136
136
  return unpacked.pack("U*")
137
137
  end
138
- (class <<self; private :unicode_downcase; end)
138
+ private_class_method :unicode_downcase
139
139
 
140
140
  def self.unicode_compose(unpacked)
141
141
  unpacked_result = []
@@ -160,7 +160,7 @@ module Addressable
160
160
  unpacked_result << starter
161
161
  return unpacked_result
162
162
  end
163
- (class <<self; private :unicode_compose; end)
163
+ private_class_method :unicode_compose
164
164
 
165
165
  def self.unicode_compose_pair(ch_one, ch_two)
166
166
  if ch_one >= HANGUL_LBASE && ch_one < HANGUL_LBASE + HANGUL_LCOUNT &&
@@ -178,43 +178,45 @@ module Addressable
178
178
  end
179
179
 
180
180
  p = []
181
- ucs4_to_utf8 = lambda do |ch|
182
- if ch < 128
183
- p << ch
184
- elsif ch < 2048
185
- p << (ch >> 6 | 192)
186
- p << (ch & 63 | 128)
187
- elsif ch < 0x10000
188
- p << (ch >> 12 | 224)
189
- p << (ch >> 6 & 63 | 128)
190
- p << (ch & 63 | 128)
191
- elsif ch < 0x200000
192
- p << (ch >> 18 | 240)
193
- p << (ch >> 12 & 63 | 128)
194
- p << (ch >> 6 & 63 | 128)
195
- p << (ch & 63 | 128)
196
- elsif ch < 0x4000000
197
- p << (ch >> 24 | 248)
198
- p << (ch >> 18 & 63 | 128)
199
- p << (ch >> 12 & 63 | 128)
200
- p << (ch >> 6 & 63 | 128)
201
- p << (ch & 63 | 128)
202
- elsif ch < 0x80000000
203
- p << (ch >> 30 | 252)
204
- p << (ch >> 24 & 63 | 128)
205
- p << (ch >> 18 & 63 | 128)
206
- p << (ch >> 12 & 63 | 128)
207
- p << (ch >> 6 & 63 | 128)
208
- p << (ch & 63 | 128)
209
- end
210
- end
211
181
 
212
- ucs4_to_utf8.call(ch_one)
213
- ucs4_to_utf8.call(ch_two)
182
+ ucs4_to_utf8(ch_one, p)
183
+ ucs4_to_utf8(ch_two, p)
214
184
 
215
185
  return lookup_unicode_composition(p)
216
186
  end
217
- (class <<self; private :unicode_compose_pair; end)
187
+ private_class_method :unicode_compose_pair
188
+
189
+ def self.ucs4_to_utf8(char, buffer)
190
+ if char < 128
191
+ buffer << char
192
+ elsif char < 2048
193
+ buffer << (char >> 6 | 192)
194
+ buffer << (char & 63 | 128)
195
+ elsif char < 0x10000
196
+ buffer << (char >> 12 | 224)
197
+ buffer << (char >> 6 & 63 | 128)
198
+ buffer << (char & 63 | 128)
199
+ elsif char < 0x200000
200
+ buffer << (char >> 18 | 240)
201
+ buffer << (char >> 12 & 63 | 128)
202
+ buffer << (char >> 6 & 63 | 128)
203
+ buffer << (char & 63 | 128)
204
+ elsif char < 0x4000000
205
+ buffer << (char >> 24 | 248)
206
+ buffer << (char >> 18 & 63 | 128)
207
+ buffer << (char >> 12 & 63 | 128)
208
+ buffer << (char >> 6 & 63 | 128)
209
+ buffer << (char & 63 | 128)
210
+ elsif char < 0x80000000
211
+ buffer << (char >> 30 | 252)
212
+ buffer << (char >> 24 & 63 | 128)
213
+ buffer << (char >> 18 & 63 | 128)
214
+ buffer << (char >> 12 & 63 | 128)
215
+ buffer << (char >> 6 & 63 | 128)
216
+ buffer << (char & 63 | 128)
217
+ end
218
+ end
219
+ private_class_method :ucs4_to_utf8
218
220
 
219
221
  def self.unicode_sort_canonical(unpacked)
220
222
  unpacked = unpacked.dup
@@ -238,7 +240,7 @@ module Addressable
238
240
  end
239
241
  return unpacked
240
242
  end
241
- (class <<self; private :unicode_sort_canonical; end)
243
+ private_class_method :unicode_sort_canonical
242
244
 
243
245
  def self.unicode_decompose(unpacked)
244
246
  unpacked_result = []
@@ -259,7 +261,7 @@ module Addressable
259
261
  end
260
262
  return unpacked_result
261
263
  end
262
- (class <<self; private :unicode_decompose; end)
264
+ private_class_method :unicode_decompose
263
265
 
264
266
  def self.unicode_decompose_hangul(codepoint)
265
267
  sindex = codepoint - HANGUL_SBASE;
@@ -276,7 +278,7 @@ module Addressable
276
278
  end
277
279
  return l, v, t
278
280
  end
279
- (class <<self; private :unicode_decompose_hangul; end)
281
+ private_class_method :unicode_decompose_hangul
280
282
 
281
283
  def self.lookup_unicode_combining_class(codepoint)
282
284
  codepoint_data = UNICODE_DATA[codepoint]
@@ -284,14 +286,14 @@ module Addressable
284
286
  (codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) :
285
287
  0)
286
288
  end
287
- (class <<self; private :lookup_unicode_combining_class; end)
289
+ private_class_method :lookup_unicode_combining_class
288
290
 
289
291
  def self.lookup_unicode_compatibility(codepoint)
290
292
  codepoint_data = UNICODE_DATA[codepoint]
291
293
  (codepoint_data ?
292
294
  codepoint_data[UNICODE_DATA_COMPATIBILITY] : nil)
293
295
  end
294
- (class <<self; private :lookup_unicode_compatibility; end)
296
+ private_class_method :lookup_unicode_compatibility
295
297
 
296
298
  def self.lookup_unicode_lowercase(codepoint)
297
299
  codepoint_data = UNICODE_DATA[codepoint]
@@ -299,12 +301,12 @@ module Addressable
299
301
  (codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) :
300
302
  codepoint)
301
303
  end
302
- (class <<self; private :lookup_unicode_lowercase; end)
304
+ private_class_method :lookup_unicode_lowercase
303
305
 
304
306
  def self.lookup_unicode_composition(unpacked)
305
307
  return COMPOSITION_TABLE[unpacked]
306
308
  end
307
- (class <<self; private :lookup_unicode_composition; end)
309
+ private_class_method :lookup_unicode_composition
308
310
 
309
311
  HANGUL_SBASE = 0xac00
310
312
  HANGUL_LBASE = 0x1100
@@ -341,7 +343,7 @@ module Addressable
341
343
  end
342
344
 
343
345
  COMPOSITION_TABLE = {}
344
- for codepoint, data in UNICODE_DATA
346
+ UNICODE_DATA.each do |codepoint, data|
345
347
  canonical = data[UNICODE_DATA_CANONICAL]
346
348
  exclusion = data[UNICODE_DATA_EXCLUSION]
347
349
 
@@ -500,7 +502,7 @@ module Addressable
500
502
 
501
503
  output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "")
502
504
  end
503
- (class <<self; private :punycode_encode; end)
505
+ private_class_method :punycode_encode
504
506
 
505
507
  def self.punycode_decode(punycode)
506
508
  input = []
@@ -622,22 +624,22 @@ module Addressable
622
624
 
623
625
  output.pack("U*")
624
626
  end
625
- (class <<self; private :punycode_decode; end)
627
+ private_class_method :punycode_decode
626
628
 
627
629
  def self.punycode_basic?(codepoint)
628
630
  codepoint < 0x80
629
631
  end
630
- (class <<self; private :punycode_basic?; end)
632
+ private_class_method :punycode_basic?
631
633
 
632
634
  def self.punycode_delimiter?(codepoint)
633
635
  codepoint == PUNYCODE_DELIMITER
634
636
  end
635
- (class <<self; private :punycode_delimiter?; end)
637
+ private_class_method :punycode_delimiter?
636
638
 
637
639
  def self.punycode_encode_digit(d)
638
640
  d + 22 + 75 * ((d < 26) ? 1 : 0)
639
641
  end
640
- (class <<self; private :punycode_encode_digit; end)
642
+ private_class_method :punycode_encode_digit
641
643
 
642
644
  # Returns the numeric value of a basic codepoint
643
645
  # (for use in representing integers) in the range 0 to
@@ -653,7 +655,7 @@ module Addressable
653
655
  PUNYCODE_BASE
654
656
  end
655
657
  end
656
- (class <<self; private :punycode_decode_digit; end)
658
+ private_class_method :punycode_decode_digit
657
659
 
658
660
  # Bias adaptation method
659
661
  def self.punycode_adapt(delta, numpoints, firsttime)
@@ -670,7 +672,7 @@ module Addressable
670
672
 
671
673
  k + (difference + 1) * delta / (delta + PUNYCODE_SKEW)
672
674
  end
673
- (class <<self; private :punycode_adapt; end)
675
+ private_class_method :punycode_adapt
674
676
  end
675
677
  # :startdoc:
676
678
  end
@@ -37,7 +37,7 @@ module Addressable
37
37
  Addressable::URI::CharacterClasses::DIGIT + '_'
38
38
 
39
39
  var_char =
40
- "(?:(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
40
+ "(?>(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
41
41
  RESERVED =
42
42
  "(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])"
43
43
  UNRESERVED =
@@ -412,7 +412,7 @@ module Addressable
412
412
  # match.captures
413
413
  # #=> ["a", ["b", "c"]]
414
414
  def match(uri, processor=nil)
415
- uri = Addressable::URI.parse(uri)
415
+ uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
416
416
  mapping = {}
417
417
 
418
418
  # First, we need to process the pattern, and extract the values.
@@ -653,40 +653,6 @@ module Addressable
653
653
  self.to_regexp.named_captures
654
654
  end
655
655
 
656
- ##
657
- # Generates a route result for a given set of parameters.
658
- # Should only be used by rack-mount.
659
- #
660
- # @param params [Hash] The set of parameters used to expand the template.
661
- # @param recall [Hash] Default parameters used to expand the template.
662
- # @param options [Hash] Either a `:processor` or a `:parameterize` block.
663
- #
664
- # @api private
665
- def generate(params={}, recall={}, options={})
666
- merged = recall.merge(params)
667
- if options[:processor]
668
- processor = options[:processor]
669
- elsif options[:parameterize]
670
- # TODO: This is sending me into fits trying to shoe-horn this into
671
- # the existing API. I think I've got this backwards and processors
672
- # should be a set of 4 optional blocks named :validate, :transform,
673
- # :match, and :restore. Having to use a singleton here is a huge
674
- # code smell.
675
- processor = Object.new
676
- class <<processor
677
- attr_accessor :block
678
- def transform(name, value)
679
- block.call(name, value)
680
- end
681
- end
682
- processor.block = options[:parameterize]
683
- else
684
- processor = nil
685
- end
686
- result = self.expand(merged, processor)
687
- result.to_s if result
688
- end
689
-
690
656
  private
691
657
  def ordered_variable_defaults
692
658
  @ordered_variable_defaults ||= begin
@@ -973,15 +939,35 @@ module Addressable
973
939
  end
974
940
  end
975
941
 
942
+ ##
943
+ # Generates the <tt>Regexp</tt> that parses a template pattern. Memoizes the
944
+ # value if template processor not set (processors may not be deterministic)
945
+ #
946
+ # @param [String] pattern The URI template pattern.
947
+ # @param [#match] processor The template processor to use.
948
+ #
949
+ # @return [Array, Regexp]
950
+ # An array of expansion variables nad a regular expression which may be
951
+ # used to parse a template pattern
952
+ def parse_template_pattern(pattern, processor = nil)
953
+ if processor.nil? && pattern == @pattern
954
+ @cached_template_parse ||=
955
+ parse_new_template_pattern(pattern, processor)
956
+ else
957
+ parse_new_template_pattern(pattern, processor)
958
+ end
959
+ end
960
+
976
961
  ##
977
962
  # Generates the <tt>Regexp</tt> that parses a template pattern.
978
963
  #
979
964
  # @param [String] pattern The URI template pattern.
980
965
  # @param [#match] processor The template processor to use.
981
966
  #
982
- # @return [Regexp]
983
- # A regular expression which may be used to parse a template pattern.
984
- def parse_template_pattern(pattern, processor=nil)
967
+ # @return [Array, Regexp]
968
+ # An array of expansion variables nad a regular expression which may be
969
+ # used to parse a template pattern
970
+ def parse_new_template_pattern(pattern, processor = nil)
985
971
  # Escape the pattern. The two gsubs restore the escaped curly braces
986
972
  # back to their original form. Basically, escape everything that isn't
987
973
  # within an expansion.