addressable 2.8.1 → 2.8.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -53,7 +53,7 @@ module Addressable
53
53
  PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze
54
54
  SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze
55
55
  HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze
56
- AUTHORITY = (PCHAR + "\\[\\:\\]").freeze
56
+ AUTHORITY = (PCHAR + "\\[\\]").freeze
57
57
  PATH = (PCHAR + "\\/").freeze
58
58
  QUERY = (PCHAR + "\\/\\?").freeze
59
59
  FRAGMENT = (PCHAR + "\\/\\?").freeze
@@ -117,7 +117,7 @@ module Addressable
117
117
  uri = uri.to_str
118
118
  rescue TypeError, NoMethodError
119
119
  raise TypeError, "Can't convert #{uri.class} into String."
120
- end if not uri.is_a? String
120
+ end unless uri.is_a?(String)
121
121
 
122
122
  # This Regexp supplied as an example in RFC 3986, and it works great.
123
123
  scan = uri.scan(URIREGEX)
@@ -138,15 +138,15 @@ module Addressable
138
138
  user = userinfo.strip[/^([^:]*):?/, 1]
139
139
  password = userinfo.strip[/:(.*)$/, 1]
140
140
  end
141
+
141
142
  host = authority.sub(
142
143
  /^([^\[\]]*)@/, EMPTY_STR
143
144
  ).sub(
144
145
  /:([^:@\[\]]*?)$/, EMPTY_STR
145
146
  )
147
+
146
148
  port = authority[/:([^:@\[\]]*?)$/, 1]
147
- end
148
- if port == EMPTY_STR
149
- port = nil
149
+ port = nil if port == EMPTY_STR
150
150
  end
151
151
 
152
152
  return new(
@@ -189,7 +189,7 @@ module Addressable
189
189
  uri = uri.to_s
190
190
  end
191
191
 
192
- if !uri.respond_to?(:to_str)
192
+ unless uri.respond_to?(:to_str)
193
193
  raise TypeError, "Can't convert #{uri.class} into String."
194
194
  end
195
195
  # Otherwise, convert to a String
@@ -281,7 +281,7 @@ module Addressable
281
281
  return nil unless path
282
282
  # If a URI object is passed, just return itself.
283
283
  return path if path.kind_of?(self)
284
- if !path.respond_to?(:to_str)
284
+ unless path.respond_to?(:to_str)
285
285
  raise TypeError, "Can't convert #{path.class} into String."
286
286
  end
287
287
  # Otherwise, convert to a String
@@ -329,13 +329,13 @@ module Addressable
329
329
  # #=> #<Addressable::URI:0xcab390 URI:http://example.com/relative/path>
330
330
  def self.join(*uris)
331
331
  uri_objects = uris.collect do |uri|
332
- if !uri.respond_to?(:to_str)
332
+ unless uri.respond_to?(:to_str)
333
333
  raise TypeError, "Can't convert #{uri.class} into String."
334
334
  end
335
335
  uri.kind_of?(self) ? uri : self.parse(uri.to_str)
336
336
  end
337
337
  result = uri_objects.shift.dup
338
- for uri in uri_objects
338
+ uri_objects.each do |uri|
339
339
  result.join!(uri)
340
340
  end
341
341
  return result
@@ -481,7 +481,7 @@ module Addressable
481
481
  leave_encoded.include?(c) ? sequence : c
482
482
  end
483
483
 
484
- result.force_encoding("utf-8")
484
+ result.force_encoding(Encoding::UTF_8)
485
485
  if return_type == String
486
486
  return result
487
487
  elsif return_type == ::Addressable::URI
@@ -579,7 +579,7 @@ module Addressable
579
579
  unencoded = self.unencode_component(component, String, leave_encoded)
580
580
  begin
581
581
  encoded = self.encode_component(
582
- Addressable::IDNA.unicode_normalize_kc(unencoded),
582
+ unencoded.unicode_normalize(:nfc),
583
583
  character_class,
584
584
  leave_encoded
585
585
  )
@@ -687,8 +687,7 @@ module Addressable
687
687
  components.each do |key, value|
688
688
  if value != nil
689
689
  begin
690
- components[key] =
691
- Addressable::IDNA.unicode_normalize_kc(value.to_str)
690
+ components[key] = value.to_str.unicode_normalize(:nfc)
692
691
  rescue ArgumentError
693
692
  # Likely a malformed UTF-8 character, skip unicode normalization
694
693
  components[key] = value.to_str
@@ -836,7 +835,9 @@ module Addressable
836
835
  end
837
836
  end
838
837
 
839
- self.defer_validation do
838
+ reset_ivs
839
+
840
+ defer_validation do
840
841
  # Bunch of crazy logic required because of the composite components
841
842
  # like userinfo and authority.
842
843
  self.scheme = options[:scheme] if options[:scheme]
@@ -851,7 +852,8 @@ module Addressable
851
852
  self.query_values = options[:query_values] if options[:query_values]
852
853
  self.fragment = options[:fragment] if options[:fragment]
853
854
  end
854
- self.to_s
855
+
856
+ to_s # force path validation
855
857
  end
856
858
 
857
859
  ##
@@ -878,9 +880,7 @@ module Addressable
878
880
  # The scheme component for this URI.
879
881
  #
880
882
  # @return [String] The scheme component.
881
- def scheme
882
- return defined?(@scheme) ? @scheme : nil
883
- end
883
+ attr_reader :scheme
884
884
 
885
885
  ##
886
886
  # The scheme component for this URI, normalized.
@@ -888,8 +888,8 @@ module Addressable
888
888
  # @return [String] The scheme component, normalized.
889
889
  def normalized_scheme
890
890
  return nil unless self.scheme
891
- @normalized_scheme ||= begin
892
- if self.scheme =~ /^\s*ssh\+svn\s*$/i
891
+ if @normalized_scheme == NONE
892
+ @normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i
893
893
  "svn+ssh".dup
894
894
  else
895
895
  Addressable::URI.normalize_component(
@@ -920,7 +920,7 @@ module Addressable
920
920
  @scheme = nil if @scheme.to_s.strip.empty?
921
921
 
922
922
  # Reset dependent values
923
- remove_instance_variable(:@normalized_scheme) if defined?(@normalized_scheme)
923
+ @normalized_scheme = NONE
924
924
  remove_composite_values
925
925
 
926
926
  # Ensure we haven't created an invalid URI
@@ -931,9 +931,7 @@ module Addressable
931
931
  # The user component for this URI.
932
932
  #
933
933
  # @return [String] The user component.
934
- def user
935
- return defined?(@user) ? @user : nil
936
- end
934
+ attr_reader :user
937
935
 
938
936
  ##
939
937
  # The user component for this URI, normalized.
@@ -941,8 +939,8 @@ module Addressable
941
939
  # @return [String] The user component, normalized.
942
940
  def normalized_user
943
941
  return nil unless self.user
944
- return @normalized_user if defined?(@normalized_user)
945
- @normalized_user ||= begin
942
+ return @normalized_user unless @normalized_user == NONE
943
+ @normalized_user = begin
946
944
  if normalized_scheme =~ /https?/ && self.user.strip.empty? &&
947
945
  (!self.password || self.password.strip.empty?)
948
946
  nil
@@ -970,14 +968,14 @@ module Addressable
970
968
 
971
969
  # You can't have a nil user with a non-nil password
972
970
  if password != nil
973
- @user = EMPTY_STR if @user.nil?
971
+ @user = EMPTY_STR unless user
974
972
  end
975
973
 
976
974
  # Reset dependent values
977
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
978
- remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
979
- remove_instance_variable(:@authority) if defined?(@authority)
980
- remove_instance_variable(:@normalized_user) if defined?(@normalized_user)
975
+ @userinfo = nil
976
+ @normalized_userinfo = NONE
977
+ @authority = nil
978
+ @normalized_user = NONE
981
979
  remove_composite_values
982
980
 
983
981
  # Ensure we haven't created an invalid URI
@@ -988,9 +986,7 @@ module Addressable
988
986
  # The password component for this URI.
989
987
  #
990
988
  # @return [String] The password component.
991
- def password
992
- return defined?(@password) ? @password : nil
993
- end
989
+ attr_reader :password
994
990
 
995
991
  ##
996
992
  # The password component for this URI, normalized.
@@ -998,8 +994,8 @@ module Addressable
998
994
  # @return [String] The password component, normalized.
999
995
  def normalized_password
1000
996
  return nil unless self.password
1001
- return @normalized_password if defined?(@normalized_password)
1002
- @normalized_password ||= begin
997
+ return @normalized_password unless @normalized_password == NONE
998
+ @normalized_password = begin
1003
999
  if self.normalized_scheme =~ /https?/ && self.password.strip.empty? &&
1004
1000
  (!self.user || self.user.strip.empty?)
1005
1001
  nil
@@ -1026,17 +1022,15 @@ module Addressable
1026
1022
  @password = new_password ? new_password.to_str : nil
1027
1023
 
1028
1024
  # You can't have a nil user with a non-nil password
1029
- @password ||= nil
1030
- @user ||= nil
1031
1025
  if @password != nil
1032
- @user = EMPTY_STR if @user.nil?
1026
+ self.user = EMPTY_STR if user.nil?
1033
1027
  end
1034
1028
 
1035
1029
  # Reset dependent values
1036
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
1037
- remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1038
- remove_instance_variable(:@authority) if defined?(@authority)
1039
- remove_instance_variable(:@normalized_password) if defined?(@normalized_password)
1030
+ @userinfo = nil
1031
+ @normalized_userinfo = NONE
1032
+ @authority = nil
1033
+ @normalized_password = NONE
1040
1034
  remove_composite_values
1041
1035
 
1042
1036
  # Ensure we haven't created an invalid URI
@@ -1066,8 +1060,8 @@ module Addressable
1066
1060
  # @return [String] The userinfo component, normalized.
1067
1061
  def normalized_userinfo
1068
1062
  return nil unless self.userinfo
1069
- return @normalized_userinfo if defined?(@normalized_userinfo)
1070
- @normalized_userinfo ||= begin
1063
+ return @normalized_userinfo unless @normalized_userinfo == NONE
1064
+ @normalized_userinfo = begin
1071
1065
  current_user = self.normalized_user
1072
1066
  current_password = self.normalized_password
1073
1067
  if !current_user && !current_password
@@ -1105,7 +1099,7 @@ module Addressable
1105
1099
  self.user = new_user
1106
1100
 
1107
1101
  # Reset dependent values
1108
- remove_instance_variable(:@authority) if defined?(@authority)
1102
+ @authority = nil
1109
1103
  remove_composite_values
1110
1104
 
1111
1105
  # Ensure we haven't created an invalid URI
@@ -1116,9 +1110,7 @@ module Addressable
1116
1110
  # The host component for this URI.
1117
1111
  #
1118
1112
  # @return [String] The host component.
1119
- def host
1120
- return defined?(@host) ? @host : nil
1121
- end
1113
+ attr_reader :host
1122
1114
 
1123
1115
  ##
1124
1116
  # The host component for this URI, normalized.
@@ -1161,8 +1153,8 @@ module Addressable
1161
1153
  @host = new_host ? new_host.to_str : nil
1162
1154
 
1163
1155
  # Reset dependent values
1164
- remove_instance_variable(:@authority) if defined?(@authority)
1165
- remove_instance_variable(:@normalized_host) if defined?(@normalized_host)
1156
+ @authority = nil
1157
+ @normalized_host = nil
1166
1158
  remove_composite_values
1167
1159
 
1168
1160
  # Ensure we haven't created an invalid URI
@@ -1293,14 +1285,14 @@ module Addressable
1293
1285
  end
1294
1286
 
1295
1287
  # Password assigned first to ensure validity in case of nil
1296
- self.password = defined?(new_password) ? new_password : nil
1297
- self.user = defined?(new_user) ? new_user : nil
1298
- self.host = defined?(new_host) ? new_host : nil
1299
- self.port = defined?(new_port) ? new_port : nil
1288
+ self.password = new_password
1289
+ self.user = new_user
1290
+ self.host = new_host
1291
+ self.port = new_port
1300
1292
 
1301
1293
  # Reset dependent values
1302
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
1303
- remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1294
+ @userinfo = nil
1295
+ @normalized_userinfo = NONE
1304
1296
  remove_composite_values
1305
1297
 
1306
1298
  # Ensure we haven't created an invalid URI
@@ -1348,16 +1340,16 @@ module Addressable
1348
1340
  new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1]
1349
1341
  end
1350
1342
 
1351
- self.scheme = defined?(new_scheme) ? new_scheme : nil
1352
- self.host = defined?(new_host) ? new_host : nil
1353
- self.port = defined?(new_port) ? new_port : nil
1343
+ self.scheme = new_scheme
1344
+ self.host = new_host
1345
+ self.port = new_port
1354
1346
  self.userinfo = nil
1355
1347
 
1356
1348
  # Reset dependent values
1357
- remove_instance_variable(:@userinfo) if defined?(@userinfo)
1358
- remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1359
- remove_instance_variable(:@authority) if defined?(@authority)
1360
- remove_instance_variable(:@normalized_authority) if defined?(@normalized_authority)
1349
+ @userinfo = nil
1350
+ @normalized_userinfo = NONE
1351
+ @authority = nil
1352
+ @normalized_authority = nil
1361
1353
  remove_composite_values
1362
1354
 
1363
1355
  # Ensure we haven't created an invalid URI
@@ -1384,9 +1376,7 @@ module Addressable
1384
1376
  # infer port numbers from default values.
1385
1377
  #
1386
1378
  # @return [Integer] The port component.
1387
- def port
1388
- return defined?(@port) ? @port : nil
1389
- end
1379
+ attr_reader :port
1390
1380
 
1391
1381
  ##
1392
1382
  # The port component for this URI, normalized.
@@ -1394,8 +1384,8 @@ module Addressable
1394
1384
  # @return [Integer] The port component, normalized.
1395
1385
  def normalized_port
1396
1386
  return nil unless self.port
1397
- return @normalized_port if defined?(@normalized_port)
1398
- @normalized_port ||= begin
1387
+ return @normalized_port unless @normalized_port == NONE
1388
+ @normalized_port = begin
1399
1389
  if URI.port_mapping[self.normalized_scheme] == self.port
1400
1390
  nil
1401
1391
  else
@@ -1426,8 +1416,8 @@ module Addressable
1426
1416
  @port = nil if @port == 0
1427
1417
 
1428
1418
  # Reset dependent values
1429
- remove_instance_variable(:@authority) if defined?(@authority)
1430
- remove_instance_variable(:@normalized_port) if defined?(@normalized_port)
1419
+ @authority = nil
1420
+ @normalized_port = NONE
1431
1421
  remove_composite_values
1432
1422
 
1433
1423
  # Ensure we haven't created an invalid URI
@@ -1528,9 +1518,7 @@ module Addressable
1528
1518
  # The path component for this URI.
1529
1519
  #
1530
1520
  # @return [String] The path component.
1531
- def path
1532
- return defined?(@path) ? @path : EMPTY_STR
1533
- end
1521
+ attr_reader :path
1534
1522
 
1535
1523
  NORMPATH = /^(?!\/)[^\/:]*:.*$/
1536
1524
  ##
@@ -1579,7 +1567,7 @@ module Addressable
1579
1567
  end
1580
1568
 
1581
1569
  # Reset dependent values
1582
- remove_instance_variable(:@normalized_path) if defined?(@normalized_path)
1570
+ @normalized_path = nil
1583
1571
  remove_composite_values
1584
1572
 
1585
1573
  # Ensure we haven't created an invalid URI
@@ -1609,9 +1597,7 @@ module Addressable
1609
1597
  # The query component for this URI.
1610
1598
  #
1611
1599
  # @return [String] The query component.
1612
- def query
1613
- return defined?(@query) ? @query : nil
1614
- end
1600
+ attr_reader :query
1615
1601
 
1616
1602
  ##
1617
1603
  # The query component for this URI, normalized.
@@ -1619,8 +1605,8 @@ module Addressable
1619
1605
  # @return [String] The query component, normalized.
1620
1606
  def normalized_query(*flags)
1621
1607
  return nil unless self.query
1622
- return @normalized_query if defined?(@normalized_query)
1623
- @normalized_query ||= begin
1608
+ return @normalized_query unless @normalized_query == NONE
1609
+ @normalized_query = begin
1624
1610
  modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
1625
1611
  # Make sure possible key-value pair delimiters are escaped.
1626
1612
  modified_query_class.sub!("\\&", "").sub!("\\;", "")
@@ -1652,7 +1638,7 @@ module Addressable
1652
1638
  @query = new_query ? new_query.to_str : nil
1653
1639
 
1654
1640
  # Reset dependent values
1655
- remove_instance_variable(:@normalized_query) if defined?(@normalized_query)
1641
+ @normalized_query = NONE
1656
1642
  remove_composite_values
1657
1643
  end
1658
1644
 
@@ -1814,9 +1800,7 @@ module Addressable
1814
1800
  # The fragment component for this URI.
1815
1801
  #
1816
1802
  # @return [String] The fragment component.
1817
- def fragment
1818
- return defined?(@fragment) ? @fragment : nil
1819
- end
1803
+ attr_reader :fragment
1820
1804
 
1821
1805
  ##
1822
1806
  # The fragment component for this URI, normalized.
@@ -1824,8 +1808,8 @@ module Addressable
1824
1808
  # @return [String] The fragment component, normalized.
1825
1809
  def normalized_fragment
1826
1810
  return nil unless self.fragment
1827
- return @normalized_fragment if defined?(@normalized_fragment)
1828
- @normalized_fragment ||= begin
1811
+ return @normalized_fragment unless @normalized_fragment == NONE
1812
+ @normalized_fragment = begin
1829
1813
  component = Addressable::URI.normalize_component(
1830
1814
  self.fragment,
1831
1815
  Addressable::URI::NormalizeCharacterClasses::FRAGMENT
@@ -1848,7 +1832,7 @@ module Addressable
1848
1832
  @fragment = new_fragment ? new_fragment.to_str : nil
1849
1833
 
1850
1834
  # Reset dependent values
1851
- remove_instance_variable(:@normalized_fragment) if defined?(@normalized_fragment)
1835
+ @normalized_fragment = NONE
1852
1836
  remove_composite_values
1853
1837
 
1854
1838
  # Ensure we haven't created an invalid URI
@@ -2014,7 +1998,7 @@ module Addressable
2014
1998
  #
2015
1999
  # @see Hash#merge
2016
2000
  def merge(hash)
2017
- if !hash.respond_to?(:to_hash)
2001
+ unless hash.respond_to?(:to_hash)
2018
2002
  raise TypeError, "Can't convert #{hash.class} into Hash."
2019
2003
  end
2020
2004
  hash = hash.to_hash
@@ -2408,7 +2392,8 @@ module Addressable
2408
2392
  yield
2409
2393
  @validation_deferred = false
2410
2394
  validate
2411
- return nil
2395
+ ensure
2396
+ @validation_deferred = false
2412
2397
  end
2413
2398
 
2414
2399
  protected
@@ -2507,11 +2492,7 @@ module Addressable
2507
2492
  # @return [Addressable::URI] <code>self</code>.
2508
2493
  def replace_self(uri)
2509
2494
  # Reset dependent values
2510
- instance_variables.each do |var|
2511
- if instance_variable_defined?(var) && var != :@validation_deferred
2512
- remove_instance_variable(var)
2513
- end
2514
- end
2495
+ reset_ivs
2515
2496
 
2516
2497
  @scheme = uri.scheme
2517
2498
  @user = uri.user
@@ -2543,8 +2524,8 @@ module Addressable
2543
2524
  #
2544
2525
  # @api private
2545
2526
  def remove_composite_values
2546
- remove_instance_variable(:@uri_string) if defined?(@uri_string)
2547
- remove_instance_variable(:@hash) if defined?(@hash)
2527
+ @uri_string = nil
2528
+ @hash = nil
2548
2529
  end
2549
2530
 
2550
2531
  ##
@@ -2556,5 +2537,40 @@ module Addressable
2556
2537
  str.force_encoding(Encoding::UTF_8)
2557
2538
  end
2558
2539
  end
2540
+
2541
+ private
2542
+
2543
+ ##
2544
+ # Resets instance variables
2545
+ #
2546
+ # @api private
2547
+ def reset_ivs
2548
+ @scheme = nil
2549
+ @user = nil
2550
+ @normalized_scheme = NONE
2551
+ @normalized_user = NONE
2552
+ @uri_string = nil
2553
+ @hash = nil
2554
+ @userinfo = nil
2555
+ @normalized_userinfo = NONE
2556
+ @authority = nil
2557
+ @password = nil
2558
+ @normalized_authority = nil
2559
+ @port = nil
2560
+ @normalized_password = NONE
2561
+ @host = nil
2562
+ @normalized_host = nil
2563
+ @normalized_port = NONE
2564
+ @path = EMPTY_STR
2565
+ @normalized_path = nil
2566
+ @normalized_query = NONE
2567
+ @fragment = nil
2568
+ @normalized_fragment = NONE
2569
+ @query = nil
2570
+ end
2571
+
2572
+ NONE = Object.new.freeze
2573
+
2574
+ private_constant :NONE
2559
2575
  end
2560
2576
  end
@@ -23,7 +23,7 @@ if !defined?(Addressable::VERSION)
23
23
  module VERSION
24
24
  MAJOR = 2
25
25
  MINOR = 8
26
- TINY = 1
26
+ TINY = 4
27
27
 
28
28
  STRING = [MAJOR, MINOR, TINY].join('.')
29
29
  end
@@ -38,6 +38,12 @@ shared_examples_for "converting from unicode to ASCII" do
38
38
  )).to eq("www.xn--8ws00zhy3a.com")
39
39
  end
40
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
+
41
47
  it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
42
48
  "www.Iñtërnâtiônàlizætiøn.com"
43
49
  expect(Addressable::IDNA.to_ascii(
@@ -249,11 +255,6 @@ shared_examples_for "converting from ASCII to unicode" do
249
255
  "example..host"
250
256
  )).to eq("example..host")
251
257
  end
252
-
253
- it "should normalize 'string' correctly" do
254
- expect(Addressable::IDNA.unicode_normalize_kc(:'string')).to eq("string")
255
- expect(Addressable::IDNA.unicode_normalize_kc("string")).to eq("string")
256
- end
257
258
  end
258
259
 
259
260
  describe Addressable::IDNA, "when using the pure-Ruby implementation" do