addressable 2.8.1 → 2.8.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/addressable/uri.rb
CHANGED
@@ -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 + "\\[
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
338
|
+
uri_objects.each do |uri|
|
339
339
|
result.join!(uri)
|
340
340
|
end
|
341
341
|
return result
|
@@ -344,17 +344,13 @@ module Addressable
|
|
344
344
|
##
|
345
345
|
# Tables used to optimize encoding operations in `self.encode_component`
|
346
346
|
# and `self.normalize_component`
|
347
|
-
SEQUENCE_ENCODING_TABLE =
|
348
|
-
|
349
|
-
|
350
|
-
end.join
|
351
|
-
end
|
347
|
+
SEQUENCE_ENCODING_TABLE = (0..255).map do |byte|
|
348
|
+
format("%02x", byte).freeze
|
349
|
+
end.freeze
|
352
350
|
|
353
|
-
SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE =
|
354
|
-
|
355
|
-
|
356
|
-
end.join
|
357
|
-
end
|
351
|
+
SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = (0..255).map do |byte|
|
352
|
+
format("%%%02X", byte).freeze
|
353
|
+
end.freeze
|
358
354
|
|
359
355
|
##
|
360
356
|
# Percent encodes a URI component.
|
@@ -421,16 +417,17 @@ module Addressable
|
|
421
417
|
component = component.dup
|
422
418
|
component.force_encoding(Encoding::ASCII_8BIT)
|
423
419
|
# Avoiding gsub! because there are edge cases with frozen strings
|
424
|
-
component = component.gsub(character_class) do |
|
425
|
-
SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[
|
420
|
+
component = component.gsub(character_class) do |char|
|
421
|
+
SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[char.ord]
|
426
422
|
end
|
427
423
|
if upcase_encoded.length > 0
|
428
|
-
upcase_encoded_chars = upcase_encoded.
|
429
|
-
SEQUENCE_ENCODING_TABLE[
|
424
|
+
upcase_encoded_chars = upcase_encoded.bytes.map do |byte|
|
425
|
+
SEQUENCE_ENCODING_TABLE[byte]
|
430
426
|
end
|
431
427
|
component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/,
|
432
428
|
&:upcase)
|
433
429
|
end
|
430
|
+
|
434
431
|
return component
|
435
432
|
end
|
436
433
|
|
@@ -481,7 +478,7 @@ module Addressable
|
|
481
478
|
leave_encoded.include?(c) ? sequence : c
|
482
479
|
end
|
483
480
|
|
484
|
-
result.force_encoding(
|
481
|
+
result.force_encoding(Encoding::UTF_8)
|
485
482
|
if return_type == String
|
486
483
|
return result
|
487
484
|
elsif return_type == ::Addressable::URI
|
@@ -560,10 +557,9 @@ module Addressable
|
|
560
557
|
leave_re = if leave_encoded.length > 0
|
561
558
|
character_class = "#{character_class}%" unless character_class.include?('%')
|
562
559
|
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
end.join('|')})"
|
560
|
+
bytes = leave_encoded.bytes
|
561
|
+
leave_encoded_pattern = bytes.map { |b| SEQUENCE_ENCODING_TABLE[b] }.join('|')
|
562
|
+
"|%(?!#{leave_encoded_pattern}|#{leave_encoded_pattern.upcase})"
|
567
563
|
end
|
568
564
|
|
569
565
|
character_class = if leave_re
|
@@ -579,7 +575,7 @@ module Addressable
|
|
579
575
|
unencoded = self.unencode_component(component, String, leave_encoded)
|
580
576
|
begin
|
581
577
|
encoded = self.encode_component(
|
582
|
-
|
578
|
+
unencoded.unicode_normalize(:nfc),
|
583
579
|
character_class,
|
584
580
|
leave_encoded
|
585
581
|
)
|
@@ -687,8 +683,7 @@ module Addressable
|
|
687
683
|
components.each do |key, value|
|
688
684
|
if value != nil
|
689
685
|
begin
|
690
|
-
components[key] =
|
691
|
-
Addressable::IDNA.unicode_normalize_kc(value.to_str)
|
686
|
+
components[key] = value.to_str.unicode_normalize(:nfc)
|
692
687
|
rescue ArgumentError
|
693
688
|
# Likely a malformed UTF-8 character, skip unicode normalization
|
694
689
|
components[key] = value.to_str
|
@@ -836,7 +831,9 @@ module Addressable
|
|
836
831
|
end
|
837
832
|
end
|
838
833
|
|
839
|
-
|
834
|
+
reset_ivs
|
835
|
+
|
836
|
+
defer_validation do
|
840
837
|
# Bunch of crazy logic required because of the composite components
|
841
838
|
# like userinfo and authority.
|
842
839
|
self.scheme = options[:scheme] if options[:scheme]
|
@@ -851,7 +848,8 @@ module Addressable
|
|
851
848
|
self.query_values = options[:query_values] if options[:query_values]
|
852
849
|
self.fragment = options[:fragment] if options[:fragment]
|
853
850
|
end
|
854
|
-
|
851
|
+
|
852
|
+
to_s # force path validation
|
855
853
|
end
|
856
854
|
|
857
855
|
##
|
@@ -878,9 +876,7 @@ module Addressable
|
|
878
876
|
# The scheme component for this URI.
|
879
877
|
#
|
880
878
|
# @return [String] The scheme component.
|
881
|
-
|
882
|
-
return defined?(@scheme) ? @scheme : nil
|
883
|
-
end
|
879
|
+
attr_reader :scheme
|
884
880
|
|
885
881
|
##
|
886
882
|
# The scheme component for this URI, normalized.
|
@@ -888,8 +884,8 @@ module Addressable
|
|
888
884
|
# @return [String] The scheme component, normalized.
|
889
885
|
def normalized_scheme
|
890
886
|
return nil unless self.scheme
|
891
|
-
@normalized_scheme
|
892
|
-
if self.scheme =~ /^\s*ssh\+svn\s*$/i
|
887
|
+
if @normalized_scheme == NONE
|
888
|
+
@normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i
|
893
889
|
"svn+ssh".dup
|
894
890
|
else
|
895
891
|
Addressable::URI.normalize_component(
|
@@ -920,7 +916,7 @@ module Addressable
|
|
920
916
|
@scheme = nil if @scheme.to_s.strip.empty?
|
921
917
|
|
922
918
|
# Reset dependent values
|
923
|
-
|
919
|
+
@normalized_scheme = NONE
|
924
920
|
remove_composite_values
|
925
921
|
|
926
922
|
# Ensure we haven't created an invalid URI
|
@@ -931,9 +927,7 @@ module Addressable
|
|
931
927
|
# The user component for this URI.
|
932
928
|
#
|
933
929
|
# @return [String] The user component.
|
934
|
-
|
935
|
-
return defined?(@user) ? @user : nil
|
936
|
-
end
|
930
|
+
attr_reader :user
|
937
931
|
|
938
932
|
##
|
939
933
|
# The user component for this URI, normalized.
|
@@ -941,8 +935,8 @@ module Addressable
|
|
941
935
|
# @return [String] The user component, normalized.
|
942
936
|
def normalized_user
|
943
937
|
return nil unless self.user
|
944
|
-
return @normalized_user
|
945
|
-
@normalized_user
|
938
|
+
return @normalized_user unless @normalized_user == NONE
|
939
|
+
@normalized_user = begin
|
946
940
|
if normalized_scheme =~ /https?/ && self.user.strip.empty? &&
|
947
941
|
(!self.password || self.password.strip.empty?)
|
948
942
|
nil
|
@@ -970,14 +964,14 @@ module Addressable
|
|
970
964
|
|
971
965
|
# You can't have a nil user with a non-nil password
|
972
966
|
if password != nil
|
973
|
-
@user = EMPTY_STR
|
967
|
+
@user = EMPTY_STR unless user
|
974
968
|
end
|
975
969
|
|
976
970
|
# Reset dependent values
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
971
|
+
@userinfo = nil
|
972
|
+
@normalized_userinfo = NONE
|
973
|
+
@authority = nil
|
974
|
+
@normalized_user = NONE
|
981
975
|
remove_composite_values
|
982
976
|
|
983
977
|
# Ensure we haven't created an invalid URI
|
@@ -988,9 +982,7 @@ module Addressable
|
|
988
982
|
# The password component for this URI.
|
989
983
|
#
|
990
984
|
# @return [String] The password component.
|
991
|
-
|
992
|
-
return defined?(@password) ? @password : nil
|
993
|
-
end
|
985
|
+
attr_reader :password
|
994
986
|
|
995
987
|
##
|
996
988
|
# The password component for this URI, normalized.
|
@@ -998,8 +990,8 @@ module Addressable
|
|
998
990
|
# @return [String] The password component, normalized.
|
999
991
|
def normalized_password
|
1000
992
|
return nil unless self.password
|
1001
|
-
return @normalized_password
|
1002
|
-
@normalized_password
|
993
|
+
return @normalized_password unless @normalized_password == NONE
|
994
|
+
@normalized_password = begin
|
1003
995
|
if self.normalized_scheme =~ /https?/ && self.password.strip.empty? &&
|
1004
996
|
(!self.user || self.user.strip.empty?)
|
1005
997
|
nil
|
@@ -1026,17 +1018,15 @@ module Addressable
|
|
1026
1018
|
@password = new_password ? new_password.to_str : nil
|
1027
1019
|
|
1028
1020
|
# You can't have a nil user with a non-nil password
|
1029
|
-
@password ||= nil
|
1030
|
-
@user ||= nil
|
1031
1021
|
if @password != nil
|
1032
|
-
|
1022
|
+
self.user = EMPTY_STR if user.nil?
|
1033
1023
|
end
|
1034
1024
|
|
1035
1025
|
# Reset dependent values
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1026
|
+
@userinfo = nil
|
1027
|
+
@normalized_userinfo = NONE
|
1028
|
+
@authority = nil
|
1029
|
+
@normalized_password = NONE
|
1040
1030
|
remove_composite_values
|
1041
1031
|
|
1042
1032
|
# Ensure we haven't created an invalid URI
|
@@ -1066,8 +1056,8 @@ module Addressable
|
|
1066
1056
|
# @return [String] The userinfo component, normalized.
|
1067
1057
|
def normalized_userinfo
|
1068
1058
|
return nil unless self.userinfo
|
1069
|
-
return @normalized_userinfo
|
1070
|
-
@normalized_userinfo
|
1059
|
+
return @normalized_userinfo unless @normalized_userinfo == NONE
|
1060
|
+
@normalized_userinfo = begin
|
1071
1061
|
current_user = self.normalized_user
|
1072
1062
|
current_password = self.normalized_password
|
1073
1063
|
if !current_user && !current_password
|
@@ -1105,7 +1095,7 @@ module Addressable
|
|
1105
1095
|
self.user = new_user
|
1106
1096
|
|
1107
1097
|
# Reset dependent values
|
1108
|
-
|
1098
|
+
@authority = nil
|
1109
1099
|
remove_composite_values
|
1110
1100
|
|
1111
1101
|
# Ensure we haven't created an invalid URI
|
@@ -1116,9 +1106,7 @@ module Addressable
|
|
1116
1106
|
# The host component for this URI.
|
1117
1107
|
#
|
1118
1108
|
# @return [String] The host component.
|
1119
|
-
|
1120
|
-
return defined?(@host) ? @host : nil
|
1121
|
-
end
|
1109
|
+
attr_reader :host
|
1122
1110
|
|
1123
1111
|
##
|
1124
1112
|
# The host component for this URI, normalized.
|
@@ -1161,8 +1149,8 @@ module Addressable
|
|
1161
1149
|
@host = new_host ? new_host.to_str : nil
|
1162
1150
|
|
1163
1151
|
# Reset dependent values
|
1164
|
-
|
1165
|
-
|
1152
|
+
@authority = nil
|
1153
|
+
@normalized_host = nil
|
1166
1154
|
remove_composite_values
|
1167
1155
|
|
1168
1156
|
# Ensure we haven't created an invalid URI
|
@@ -1293,14 +1281,14 @@ module Addressable
|
|
1293
1281
|
end
|
1294
1282
|
|
1295
1283
|
# Password assigned first to ensure validity in case of nil
|
1296
|
-
self.password =
|
1297
|
-
self.user =
|
1298
|
-
self.host =
|
1299
|
-
self.port =
|
1284
|
+
self.password = new_password
|
1285
|
+
self.user = new_user
|
1286
|
+
self.host = new_host
|
1287
|
+
self.port = new_port
|
1300
1288
|
|
1301
1289
|
# Reset dependent values
|
1302
|
-
|
1303
|
-
|
1290
|
+
@userinfo = nil
|
1291
|
+
@normalized_userinfo = NONE
|
1304
1292
|
remove_composite_values
|
1305
1293
|
|
1306
1294
|
# Ensure we haven't created an invalid URI
|
@@ -1348,16 +1336,16 @@ module Addressable
|
|
1348
1336
|
new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1]
|
1349
1337
|
end
|
1350
1338
|
|
1351
|
-
self.scheme =
|
1352
|
-
self.host =
|
1353
|
-
self.port =
|
1339
|
+
self.scheme = new_scheme
|
1340
|
+
self.host = new_host
|
1341
|
+
self.port = new_port
|
1354
1342
|
self.userinfo = nil
|
1355
1343
|
|
1356
1344
|
# Reset dependent values
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1345
|
+
@userinfo = nil
|
1346
|
+
@normalized_userinfo = NONE
|
1347
|
+
@authority = nil
|
1348
|
+
@normalized_authority = nil
|
1361
1349
|
remove_composite_values
|
1362
1350
|
|
1363
1351
|
# Ensure we haven't created an invalid URI
|
@@ -1384,9 +1372,7 @@ module Addressable
|
|
1384
1372
|
# infer port numbers from default values.
|
1385
1373
|
#
|
1386
1374
|
# @return [Integer] The port component.
|
1387
|
-
|
1388
|
-
return defined?(@port) ? @port : nil
|
1389
|
-
end
|
1375
|
+
attr_reader :port
|
1390
1376
|
|
1391
1377
|
##
|
1392
1378
|
# The port component for this URI, normalized.
|
@@ -1394,8 +1380,8 @@ module Addressable
|
|
1394
1380
|
# @return [Integer] The port component, normalized.
|
1395
1381
|
def normalized_port
|
1396
1382
|
return nil unless self.port
|
1397
|
-
return @normalized_port
|
1398
|
-
@normalized_port
|
1383
|
+
return @normalized_port unless @normalized_port == NONE
|
1384
|
+
@normalized_port = begin
|
1399
1385
|
if URI.port_mapping[self.normalized_scheme] == self.port
|
1400
1386
|
nil
|
1401
1387
|
else
|
@@ -1426,8 +1412,8 @@ module Addressable
|
|
1426
1412
|
@port = nil if @port == 0
|
1427
1413
|
|
1428
1414
|
# Reset dependent values
|
1429
|
-
|
1430
|
-
|
1415
|
+
@authority = nil
|
1416
|
+
@normalized_port = NONE
|
1431
1417
|
remove_composite_values
|
1432
1418
|
|
1433
1419
|
# Ensure we haven't created an invalid URI
|
@@ -1528,9 +1514,7 @@ module Addressable
|
|
1528
1514
|
# The path component for this URI.
|
1529
1515
|
#
|
1530
1516
|
# @return [String] The path component.
|
1531
|
-
|
1532
|
-
return defined?(@path) ? @path : EMPTY_STR
|
1533
|
-
end
|
1517
|
+
attr_reader :path
|
1534
1518
|
|
1535
1519
|
NORMPATH = /^(?!\/)[^\/:]*:.*$/
|
1536
1520
|
##
|
@@ -1579,7 +1563,7 @@ module Addressable
|
|
1579
1563
|
end
|
1580
1564
|
|
1581
1565
|
# Reset dependent values
|
1582
|
-
|
1566
|
+
@normalized_path = nil
|
1583
1567
|
remove_composite_values
|
1584
1568
|
|
1585
1569
|
# Ensure we haven't created an invalid URI
|
@@ -1609,9 +1593,7 @@ module Addressable
|
|
1609
1593
|
# The query component for this URI.
|
1610
1594
|
#
|
1611
1595
|
# @return [String] The query component.
|
1612
|
-
|
1613
|
-
return defined?(@query) ? @query : nil
|
1614
|
-
end
|
1596
|
+
attr_reader :query
|
1615
1597
|
|
1616
1598
|
##
|
1617
1599
|
# The query component for this URI, normalized.
|
@@ -1619,8 +1601,8 @@ module Addressable
|
|
1619
1601
|
# @return [String] The query component, normalized.
|
1620
1602
|
def normalized_query(*flags)
|
1621
1603
|
return nil unless self.query
|
1622
|
-
return @normalized_query
|
1623
|
-
@normalized_query
|
1604
|
+
return @normalized_query unless @normalized_query == NONE
|
1605
|
+
@normalized_query = begin
|
1624
1606
|
modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
|
1625
1607
|
# Make sure possible key-value pair delimiters are escaped.
|
1626
1608
|
modified_query_class.sub!("\\&", "").sub!("\\;", "")
|
@@ -1652,7 +1634,7 @@ module Addressable
|
|
1652
1634
|
@query = new_query ? new_query.to_str : nil
|
1653
1635
|
|
1654
1636
|
# Reset dependent values
|
1655
|
-
|
1637
|
+
@normalized_query = NONE
|
1656
1638
|
remove_composite_values
|
1657
1639
|
end
|
1658
1640
|
|
@@ -1814,9 +1796,7 @@ module Addressable
|
|
1814
1796
|
# The fragment component for this URI.
|
1815
1797
|
#
|
1816
1798
|
# @return [String] The fragment component.
|
1817
|
-
|
1818
|
-
return defined?(@fragment) ? @fragment : nil
|
1819
|
-
end
|
1799
|
+
attr_reader :fragment
|
1820
1800
|
|
1821
1801
|
##
|
1822
1802
|
# The fragment component for this URI, normalized.
|
@@ -1824,8 +1804,8 @@ module Addressable
|
|
1824
1804
|
# @return [String] The fragment component, normalized.
|
1825
1805
|
def normalized_fragment
|
1826
1806
|
return nil unless self.fragment
|
1827
|
-
return @normalized_fragment
|
1828
|
-
@normalized_fragment
|
1807
|
+
return @normalized_fragment unless @normalized_fragment == NONE
|
1808
|
+
@normalized_fragment = begin
|
1829
1809
|
component = Addressable::URI.normalize_component(
|
1830
1810
|
self.fragment,
|
1831
1811
|
Addressable::URI::NormalizeCharacterClasses::FRAGMENT
|
@@ -1848,7 +1828,7 @@ module Addressable
|
|
1848
1828
|
@fragment = new_fragment ? new_fragment.to_str : nil
|
1849
1829
|
|
1850
1830
|
# Reset dependent values
|
1851
|
-
|
1831
|
+
@normalized_fragment = NONE
|
1852
1832
|
remove_composite_values
|
1853
1833
|
|
1854
1834
|
# Ensure we haven't created an invalid URI
|
@@ -2014,7 +1994,7 @@ module Addressable
|
|
2014
1994
|
#
|
2015
1995
|
# @see Hash#merge
|
2016
1996
|
def merge(hash)
|
2017
|
-
|
1997
|
+
unless hash.respond_to?(:to_hash)
|
2018
1998
|
raise TypeError, "Can't convert #{hash.class} into Hash."
|
2019
1999
|
end
|
2020
2000
|
hash = hash.to_hash
|
@@ -2408,7 +2388,27 @@ module Addressable
|
|
2408
2388
|
yield
|
2409
2389
|
@validation_deferred = false
|
2410
2390
|
validate
|
2411
|
-
|
2391
|
+
ensure
|
2392
|
+
@validation_deferred = false
|
2393
|
+
end
|
2394
|
+
|
2395
|
+
def encode_with(coder)
|
2396
|
+
instance_variables.each do |ivar|
|
2397
|
+
value = instance_variable_get(ivar)
|
2398
|
+
if value != NONE
|
2399
|
+
key = ivar.to_s.slice(1..-1)
|
2400
|
+
coder[key] = value
|
2401
|
+
end
|
2402
|
+
end
|
2403
|
+
nil
|
2404
|
+
end
|
2405
|
+
|
2406
|
+
def init_with(coder)
|
2407
|
+
reset_ivs
|
2408
|
+
coder.map.each do |key, value|
|
2409
|
+
instance_variable_set("@#{key}", value)
|
2410
|
+
end
|
2411
|
+
nil
|
2412
2412
|
end
|
2413
2413
|
|
2414
2414
|
protected
|
@@ -2507,11 +2507,7 @@ module Addressable
|
|
2507
2507
|
# @return [Addressable::URI] <code>self</code>.
|
2508
2508
|
def replace_self(uri)
|
2509
2509
|
# Reset dependent values
|
2510
|
-
|
2511
|
-
if instance_variable_defined?(var) && var != :@validation_deferred
|
2512
|
-
remove_instance_variable(var)
|
2513
|
-
end
|
2514
|
-
end
|
2510
|
+
reset_ivs
|
2515
2511
|
|
2516
2512
|
@scheme = uri.scheme
|
2517
2513
|
@user = uri.user
|
@@ -2543,8 +2539,8 @@ module Addressable
|
|
2543
2539
|
#
|
2544
2540
|
# @api private
|
2545
2541
|
def remove_composite_values
|
2546
|
-
|
2547
|
-
|
2542
|
+
@uri_string = nil
|
2543
|
+
@hash = nil
|
2548
2544
|
end
|
2549
2545
|
|
2550
2546
|
##
|
@@ -2556,5 +2552,40 @@ module Addressable
|
|
2556
2552
|
str.force_encoding(Encoding::UTF_8)
|
2557
2553
|
end
|
2558
2554
|
end
|
2555
|
+
|
2556
|
+
private
|
2557
|
+
|
2558
|
+
##
|
2559
|
+
# Resets instance variables
|
2560
|
+
#
|
2561
|
+
# @api private
|
2562
|
+
def reset_ivs
|
2563
|
+
@scheme = nil
|
2564
|
+
@user = nil
|
2565
|
+
@normalized_scheme = NONE
|
2566
|
+
@normalized_user = NONE
|
2567
|
+
@uri_string = nil
|
2568
|
+
@hash = nil
|
2569
|
+
@userinfo = nil
|
2570
|
+
@normalized_userinfo = NONE
|
2571
|
+
@authority = nil
|
2572
|
+
@password = nil
|
2573
|
+
@normalized_authority = nil
|
2574
|
+
@port = nil
|
2575
|
+
@normalized_password = NONE
|
2576
|
+
@host = nil
|
2577
|
+
@normalized_host = nil
|
2578
|
+
@normalized_port = NONE
|
2579
|
+
@path = EMPTY_STR
|
2580
|
+
@normalized_path = nil
|
2581
|
+
@normalized_query = NONE
|
2582
|
+
@fragment = nil
|
2583
|
+
@normalized_fragment = NONE
|
2584
|
+
@query = nil
|
2585
|
+
end
|
2586
|
+
|
2587
|
+
NONE = Module.new.freeze
|
2588
|
+
|
2589
|
+
private_constant :NONE
|
2559
2590
|
end
|
2560
2591
|
end
|
data/lib/addressable/version.rb
CHANGED
@@ -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
|