addressable 2.6.0 → 2.8.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  #
@@ -37,7 +36,7 @@ module Addressable
37
36
  Addressable::URI::CharacterClasses::DIGIT + '_'
38
37
 
39
38
  var_char =
40
- "(?:(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
39
+ "(?>(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
41
40
  RESERVED =
42
41
  "(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])"
43
42
  UNRESERVED =
@@ -412,7 +411,7 @@ module Addressable
412
411
  # match.captures
413
412
  # #=> ["a", ["b", "c"]]
414
413
  def match(uri, processor=nil)
415
- uri = Addressable::URI.parse(uri)
414
+ uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
416
415
  mapping = {}
417
416
 
418
417
  # First, we need to process the pattern, and extract the values.
@@ -653,50 +652,16 @@ module Addressable
653
652
  self.to_regexp.named_captures
654
653
  end
655
654
 
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
655
  private
691
656
  def ordered_variable_defaults
692
657
  @ordered_variable_defaults ||= begin
693
658
  expansions, _ = parse_template_pattern(pattern)
694
- expansions.map do |capture|
659
+ expansions.flat_map do |capture|
695
660
  _, _, varlist = *capture.match(EXPRESSION)
696
661
  varlist.split(',').map do |varspec|
697
662
  varspec[VARSPEC, 1]
698
663
  end
699
- end.flatten
664
+ end
700
665
  end
701
666
  end
702
667
 
@@ -927,25 +892,24 @@ module Addressable
927
892
  # operator.
928
893
  #
929
894
  # @param [Hash, Array, String] value
930
- # Normalizes keys and values with IDNA#unicode_normalize_kc
895
+ # Normalizes unicode keys and values with String#unicode_normalize (NFC)
931
896
  #
932
897
  # @return [Hash, Array, String] The normalized values
933
898
  def normalize_value(value)
934
- unless value.is_a?(Hash)
935
- value = value.respond_to?(:to_ary) ? value.to_ary : value.to_str
936
- end
937
-
938
899
  # Handle unicode normalization
939
- if value.kind_of?(Array)
940
- value.map! { |val| Addressable::IDNA.unicode_normalize_kc(val) }
900
+ if value.respond_to?(:to_ary)
901
+ value.to_ary.map! { |val| normalize_value(val) }
941
902
  elsif value.kind_of?(Hash)
942
903
  value = value.inject({}) { |acc, (k, v)|
943
- acc[Addressable::IDNA.unicode_normalize_kc(k)] =
944
- Addressable::IDNA.unicode_normalize_kc(v)
904
+ acc[normalize_value(k)] = normalize_value(v)
945
905
  acc
946
906
  }
947
907
  else
948
- value = Addressable::IDNA.unicode_normalize_kc(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)
949
913
  end
950
914
  value
951
915
  end
@@ -973,15 +937,35 @@ module Addressable
973
937
  end
974
938
  end
975
939
 
940
+ ##
941
+ # Generates the <tt>Regexp</tt> that parses a template pattern. Memoizes the
942
+ # value if template processor not set (processors may not be deterministic)
943
+ #
944
+ # @param [String] pattern The URI template pattern.
945
+ # @param [#match] processor The template processor to use.
946
+ #
947
+ # @return [Array, Regexp]
948
+ # An array of expansion variables nad a regular expression which may be
949
+ # used to parse a template pattern
950
+ def parse_template_pattern(pattern, processor = nil)
951
+ if processor.nil? && pattern == @pattern
952
+ @cached_template_parse ||=
953
+ parse_new_template_pattern(pattern, processor)
954
+ else
955
+ parse_new_template_pattern(pattern, processor)
956
+ end
957
+ end
958
+
976
959
  ##
977
960
  # Generates the <tt>Regexp</tt> that parses a template pattern.
978
961
  #
979
962
  # @param [String] pattern The URI template pattern.
980
963
  # @param [#match] processor The template processor to use.
981
964
  #
982
- # @return [Regexp]
983
- # A regular expression which may be used to parse a template pattern.
984
- def parse_template_pattern(pattern, processor=nil)
965
+ # @return [Array, Regexp]
966
+ # An array of expansion variables nad a regular expression which may be
967
+ # used to parse a template pattern
968
+ def parse_new_template_pattern(pattern, processor = nil)
985
969
  # Escape the pattern. The two gsubs restore the escaped curly braces
986
970
  # back to their original form. Basically, escape everything that isn't
987
971
  # within an expansion.
@@ -1037,7 +1021,7 @@ module Addressable
1037
1021
  end
1038
1022
 
1039
1023
  # Ensure that the regular expression matches the whole URI.
1040
- regexp_string = "^#{regexp_string}$"
1024
+ regexp_string = "\\A#{regexp_string}\\z"
1041
1025
  return expansions, Regexp.new(regexp_string)
1042
1026
  end
1043
1027