Skip to content

Commit 860fede

Browse files
ACBullenbaseballlover723sporkmonger
authored
Force UTF-8 encoding only if needed (#341)
Co-authored-by: Philip Ross <[email protected]> Co-authored-by: Philip Ross <[email protected]> Co-authored-by: Bob Aman <[email protected]>
1 parent 99810af commit 860fede

File tree

2 files changed

+86
-20
lines changed

2 files changed

+86
-20
lines changed

lib/addressable/uri.rb

+20-20
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ def normalized_scheme
899899
end
900900
end
901901
# All normalized values should be UTF-8
902-
@normalized_scheme.force_encoding(Encoding::UTF_8) if @normalized_scheme
902+
force_utf8_encoding_if_needed(@normalized_scheme)
903903
@normalized_scheme
904904
end
905905

@@ -954,7 +954,7 @@ def normalized_user
954954
end
955955
end
956956
# All normalized values should be UTF-8
957-
@normalized_user.force_encoding(Encoding::UTF_8) if @normalized_user
957+
force_utf8_encoding_if_needed(@normalized_user)
958958
@normalized_user
959959
end
960960

@@ -1011,9 +1011,7 @@ def normalized_password
10111011
end
10121012
end
10131013
# All normalized values should be UTF-8
1014-
if @normalized_password
1015-
@normalized_password.force_encoding(Encoding::UTF_8)
1016-
end
1014+
force_utf8_encoding_if_needed(@normalized_password)
10171015
@normalized_password
10181016
end
10191017

@@ -1081,9 +1079,7 @@ def normalized_userinfo
10811079
end
10821080
end
10831081
# All normalized values should be UTF-8
1084-
if @normalized_userinfo
1085-
@normalized_userinfo.force_encoding(Encoding::UTF_8)
1086-
end
1082+
force_utf8_encoding_if_needed(@normalized_userinfo)
10871083
@normalized_userinfo
10881084
end
10891085

@@ -1150,9 +1146,7 @@ def normalized_host
11501146
end
11511147
end
11521148
# All normalized values should be UTF-8
1153-
if @normalized_host && !@normalized_host.empty?
1154-
@normalized_host.force_encoding(Encoding::UTF_8)
1155-
end
1149+
force_utf8_encoding_if_needed(@normalized_host)
11561150
@normalized_host
11571151
end
11581152

@@ -1270,9 +1264,7 @@ def normalized_authority
12701264
authority
12711265
end
12721266
# All normalized values should be UTF-8
1273-
if @normalized_authority
1274-
@normalized_authority.force_encoding(Encoding::UTF_8)
1275-
end
1267+
force_utf8_encoding_if_needed(@normalized_authority)
12761268
@normalized_authority
12771269
end
12781270

@@ -1506,7 +1498,7 @@ def normalized_site
15061498
site_string
15071499
end
15081500
# All normalized values should be UTF-8
1509-
@normalized_site.force_encoding(Encoding::UTF_8) if @normalized_site
1501+
force_utf8_encoding_if_needed(@normalized_site)
15101502
@normalized_site
15111503
end
15121504

@@ -1569,7 +1561,7 @@ def normalized_path
15691561
result
15701562
end
15711563
# All normalized values should be UTF-8
1572-
@normalized_path.force_encoding(Encoding::UTF_8) if @normalized_path
1564+
force_utf8_encoding_if_needed(@normalized_path)
15731565
@normalized_path
15741566
end
15751567

@@ -1645,7 +1637,7 @@ def normalized_query(*flags)
16451637
component == "" ? nil : component
16461638
end
16471639
# All normalized values should be UTF-8
1648-
@normalized_query.force_encoding(Encoding::UTF_8) if @normalized_query
1640+
force_utf8_encoding_if_needed(@normalized_query)
16491641
@normalized_query
16501642
end
16511643

@@ -1841,9 +1833,7 @@ def normalized_fragment
18411833
component == "" ? nil : component
18421834
end
18431835
# All normalized values should be UTF-8
1844-
if @normalized_fragment
1845-
@normalized_fragment.force_encoding(Encoding::UTF_8)
1846-
end
1836+
force_utf8_encoding_if_needed(@normalized_fragment)
18471837
@normalized_fragment
18481838
end
18491839

@@ -2556,5 +2546,15 @@ def remove_composite_values
25562546
remove_instance_variable(:@uri_string) if defined?(@uri_string)
25572547
remove_instance_variable(:@hash) if defined?(@hash)
25582548
end
2549+
2550+
##
2551+
# Converts the string to be UTF-8 if it is not already UTF-8
2552+
#
2553+
# @api private
2554+
def force_utf8_encoding_if_needed(str)
2555+
if str && str.encoding != Encoding::UTF_8
2556+
str.force_encoding(Encoding::UTF_8)
2557+
end
2558+
end
25592559
end
25602560
end

spec/addressable/uri_spec.rb

+66
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,72 @@ def to_s
998998
end
999999
end
10001000

1001+
describe Addressable::URI, "when normalized and then deeply frozen" do
1002+
before do
1003+
@uri = Addressable::URI.parse(
1004+
"http://user:[email protected]:8080/path?query=value#fragment"
1005+
).normalize!
1006+
1007+
@uri.instance_variables.each do |var|
1008+
@uri.instance_variable_set(var, @uri.instance_variable_get(var).freeze)
1009+
end
1010+
1011+
@uri.freeze
1012+
end
1013+
1014+
it "#normalized_scheme should not error" do
1015+
expect { @uri.normalized_scheme }.not_to raise_error
1016+
end
1017+
1018+
it "#normalized_user should not error" do
1019+
expect { @uri.normalized_user }.not_to raise_error
1020+
end
1021+
1022+
it "#normalized_password should not error" do
1023+
expect { @uri.normalized_password }.not_to raise_error
1024+
end
1025+
1026+
it "#normalized_userinfo should not error" do
1027+
expect { @uri.normalized_userinfo }.not_to raise_error
1028+
end
1029+
1030+
it "#normalized_host should not error" do
1031+
expect { @uri.normalized_host }.not_to raise_error
1032+
end
1033+
1034+
it "#normalized_authority should not error" do
1035+
expect { @uri.normalized_authority }.not_to raise_error
1036+
end
1037+
1038+
it "#normalized_port should not error" do
1039+
expect { @uri.normalized_port }.not_to raise_error
1040+
end
1041+
1042+
it "#normalized_site should not error" do
1043+
expect { @uri.normalized_site }.not_to raise_error
1044+
end
1045+
1046+
it "#normalized_path should not error" do
1047+
expect { @uri.normalized_path }.not_to raise_error
1048+
end
1049+
1050+
it "#normalized_query should not error" do
1051+
expect { @uri.normalized_query }.not_to raise_error
1052+
end
1053+
1054+
it "#normalized_fragment should not error" do
1055+
expect { @uri.normalized_fragment }.not_to raise_error
1056+
end
1057+
1058+
it "should be frozen" do
1059+
expect(@uri).to be_frozen
1060+
end
1061+
1062+
it "should not allow destructive operations" do
1063+
expect { @uri.normalize! }.to raise_error(RuntimeError)
1064+
end
1065+
end
1066+
10011067
describe Addressable::URI, "when created from string components" do
10021068
before do
10031069
@uri = Addressable::URI.new(

0 commit comments

Comments
 (0)