From 686dbbbfc7a9ec67e40826c8bde8661e8e6a7471 Mon Sep 17 00:00:00 2001
From: Alex Bullen <alexb@tinfoilsecurity.com>
Date: Wed, 17 Apr 2019 16:19:32 -0700
Subject: [PATCH] Check to see if @normalized_* variables are already UTF-8
 before calling force_encoding on them

This prevents unnecessary mutation of these variables when already set
and appropriately encoded. Necessary for our use case as we freeze our
Addressable::URI objects to ensure they don't get changed when passed around
---
 lib/addressable/uri.rb | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/lib/addressable/uri.rb b/lib/addressable/uri.rb
index 9109256c..97fc0b37 100644
--- a/lib/addressable/uri.rb
+++ b/lib/addressable/uri.rb
@@ -865,7 +865,9 @@ def normalized_scheme
         end
       end
       # All normalized values should be UTF-8
-      @normalized_scheme.force_encoding(Encoding::UTF_8) if @normalized_scheme
+      if @normalized_scheme && @normalized_scheme.encoding != Encoding::UTF_8
+        @normalized_scheme.force_encoding(Encoding::UTF_8)
+      end
       @normalized_scheme
     end
 
@@ -920,7 +922,9 @@ def normalized_user
         end
       end
       # All normalized values should be UTF-8
-      @normalized_user.force_encoding(Encoding::UTF_8) if @normalized_user
+      if @normalized_user && @normalized_user.encoding != Encoding::UTF_8
+        @normalized_user.force_encoding(Encoding::UTF_8)
+      end
       @normalized_user
     end
 
@@ -977,7 +981,7 @@ def normalized_password
         end
       end
       # All normalized values should be UTF-8
-      if @normalized_password
+      if @normalized_password && @normalized_password.encoding != Encoding::UTF_8
         @normalized_password.force_encoding(Encoding::UTF_8)
       end
       @normalized_password
@@ -1047,7 +1051,7 @@ def normalized_userinfo
         end
       end
       # All normalized values should be UTF-8
-      if @normalized_userinfo
+      if @normalized_userinfo && @normalized_userinfo.encoding != Encoding::UTF_8
         @normalized_userinfo.force_encoding(Encoding::UTF_8)
       end
       @normalized_userinfo
@@ -1114,7 +1118,9 @@ def normalized_host
         end
       end
       # All normalized values should be UTF-8
-      @normalized_host.force_encoding(Encoding::UTF_8) if @normalized_host
+      if @normalized_host && @normalized_host.encoding != Encoding::UTF_8
+        @normalized_host.force_encoding(Encoding::UTF_8)
+      end
       @normalized_host
     end
 
@@ -1232,7 +1238,7 @@ def normalized_authority
         authority
       end
       # All normalized values should be UTF-8
-      if @normalized_authority
+      if @normalized_authority && @normalized_authority.encoding != Encoding::UTF_8
         @normalized_authority.force_encoding(Encoding::UTF_8)
       end
       @normalized_authority
@@ -1468,7 +1474,9 @@ def normalized_site
         site_string
       end
       # All normalized values should be UTF-8
-      @normalized_site.force_encoding(Encoding::UTF_8) if @normalized_site
+      if @normalized_site && @normalized_site.encoding != Encoding::UTF_8
+        @normalized_site.force_encoding(Encoding::UTF_8)
+      end
       @normalized_site
     end
 
@@ -1531,7 +1539,9 @@ def normalized_path
         result
       end
       # All normalized values should be UTF-8
-      @normalized_path.force_encoding(Encoding::UTF_8) if @normalized_path
+      if @normalized_path && @normalized_path.encoding != Encoding::UTF_8
+         @normalized_path.force_encoding(Encoding::UTF_8)
+      end
       @normalized_path
     end
 
@@ -1602,7 +1612,9 @@ def normalized_query(*flags)
         component == "" ? nil : component
       end
       # All normalized values should be UTF-8
-      @normalized_query.force_encoding(Encoding::UTF_8) if @normalized_query
+      if @normalized_query && @normalized_query.encoding != Encoding::UTF_8
+        @normalized_query.force_encoding(Encoding::UTF_8)
+      end
       @normalized_query
     end
 
@@ -1796,7 +1808,7 @@ def normalized_fragment
         component == "" ? nil : component
       end
       # All normalized values should be UTF-8
-      if @normalized_fragment
+      if @normalized_fragment && @normalized_fragment.encoding != Encoding::UTF_8
         @normalized_fragment.force_encoding(Encoding::UTF_8)
       end
       @normalized_fragment