From 58adef476ef4b5e6deefaf92e7594ab29396c624 Mon Sep 17 00:00:00 2001
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
Date: Fri, 21 Feb 2025 18:16:28 +0900
Subject: [PATCH] Fix merger of URI with authority component

Reference:https://github.com/ruby/uri/commit/58adef476ef4b5e6deefaf92e7594ab29396c624
Conflict:NA

https://hackerone.com/reports/2957667

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
---
 lib/uri/generic.rb       | 19 +++++++------------
 test/uri/test_generic.rb |  7 +++++++
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb
index 6b60873..3ca5831 100644
--- a/lib/uri/generic.rb
+++ b/lib/uri/generic.rb
@@ -1123,21 +1123,16 @@ module URI
       base.fragment=(nil)
 
       # RFC2396, Section 5.2, 4)
-      if !authority
-        base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
-      else
-        # RFC2396, Section 5.2, 4)
-        base.set_path(rel.path) if rel.path
+      if authority
+        base.set_userinfo(rel.userinfo)
+        base.set_host(rel.host)
+        base.set_port(rel.port || base.default_port)
+        base.set_path(rel.path)
+      elsif base.path && rel.path
+        base.set_path(merge_path(base.path, rel.path))
       end
 
       # RFC2396, Section 5.2, 7)
-      if rel.userinfo
-        base.set_userinfo(rel.userinfo)
-      else
-        base.set_userinfo(nil)
-      end
-      base.set_host(rel.host)         if rel.host
-      base.set_port(rel.port)         if rel.port
       base.query = rel.query       if rel.query
       base.fragment=(rel.fragment) if rel.fragment
 
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index 8a611e3..a365f10 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -253,6 +253,13 @@ class URI::TestGeneric < Test::Unit::TestCase
     assert_equal(u0, u1)
   end
 
+  def test_merge_authority
+    u = URI.parse('http://user:pass@example.com:8080')
+    u0 = URI.parse('http://new.example.org/path')
+    u1 = u.merge('//new.example.org/path')
+    assert_equal(u0, u1)
+  end
+
   def test_route
     url = URI.parse('http://hoge/a.html').route_to('http://hoge/b.html')
     assert_equal('b.html', url.to_s)
-- 
2.33.0


