From d8943269835525bd1695e2baa111a80b3d2274a1 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Thu, 27 Aug 2026 22:24:36 +0300 Subject: [PATCH 1/2] Decode form query keys consistently with values --- lib/addressable/uri.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/addressable/uri.rb b/lib/addressable/uri.rb index 07c9aeb5..8af1bfa7 100644 --- a/lib/addressable/uri.rb +++ b/lib/addressable/uri.rb @@ -1682,14 +1682,15 @@ def query_values(return_type=Hash) # I'd rather use key/value identifiers instead of array lookups, # but in this case I really want to maintain the exact pair structure, # so it's best to make all changes in-place. - pair[0] = URI.unencode_component(pair[0]) + form_encoded = ["http", "https", nil].include?(normalized_scheme) + pair[0] = URI.unencode_component(form_encoded ? pair[0].tr("+", " ") : pair[0]) if pair[1].respond_to?(:to_str) value = pair[1].to_str # I loathe the fact that I have to do this. Stupid HTML 4.01. # Treating '+' as a space was just an unbelievably bad idea. # There was nothing wrong with '%20'! # If it ain't broke, don't fix it! - value = value.tr("+", " ") if ["http", "https", nil].include?(scheme) + value = value.tr("+", " ") if form_encoded pair[1] = URI.unencode_component(value) end if return_type == Hash From 20a57c96a0664fa88c2417e806958d4be129c7ee Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Sun, 30 Aug 2026 20:47:29 +0700 Subject: [PATCH 2/2] Avoid repeated query scheme normalization --- lib/addressable/uri.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/addressable/uri.rb b/lib/addressable/uri.rb index 8af1bfa7..7d3a9ad8 100644 --- a/lib/addressable/uri.rb +++ b/lib/addressable/uri.rb @@ -1675,6 +1675,9 @@ def query_values(return_type=Hash) raise ArgumentError, "Invalid return type. Must be Hash or Array." end return nil if self.query == nil + query_scheme = normalized_scheme + form_encoded = query_scheme.nil? || + query_scheme == "http" || query_scheme == "https" split_query = self.query.split("&").map do |pair| pair.split("=", 2) if pair && !pair.empty? end.compact @@ -1682,8 +1685,9 @@ def query_values(return_type=Hash) # I'd rather use key/value identifiers instead of array lookups, # but in this case I really want to maintain the exact pair structure, # so it's best to make all changes in-place. - form_encoded = ["http", "https", nil].include?(normalized_scheme) - pair[0] = URI.unencode_component(form_encoded ? pair[0].tr("+", " ") : pair[0]) + key = pair[0] + key = key.tr("+", " ") if form_encoded + pair[0] = URI.unencode_component(key) if pair[1].respond_to?(:to_str) value = pair[1].to_str # I loathe the fact that I have to do this. Stupid HTML 4.01.