From 365ee4d2200d45962d3f919f61fa2dda54db2c34 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Thu, 27 Aug 2026 23:35:58 +0300 Subject: [PATCH 1/2] Avoid mutating caller components in FTP.build --- lib/uri/ftp.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/uri/ftp.rb b/lib/uri/ftp.rb index 1c75e24..bb1b945 100644 --- a/lib/uri/ftp.rb +++ b/lib/uri/ftp.rb @@ -100,13 +100,8 @@ def self.build(args) # foo/bar /foo/bar # /foo/bar /%2Ffoo/bar # - if args.kind_of?(Array) - args[3] = '/' + args[3].sub(/^\//, '%2F') - else - args[:path] = '/' + args[:path].sub(/^\//, '%2F') - end - tmp = Util::make_components_hash(self, args) + tmp[:path] = '/' + tmp[:path].sub(/^\//, '%2F') if tmp[:typecode] if tmp[:typecode].size == 1 From c3fc0b8aea733f1704b0325496851105a73c6a79 Mon Sep 17 00:00:00 2001 From: Oskar Eichler <62393985+OskarEichler@users.noreply.github.com> Date: Fri, 28 Aug 2026 15:03:57 +0300 Subject: [PATCH 2/2] test: cover URI regression --- test/uri/test_ftp.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/uri/test_ftp.rb b/test/uri/test_ftp.rb index 3ad7864..3a1d7a9 100644 --- a/test/uri/test_ftp.rb +++ b/test/uri/test_ftp.rb @@ -6,6 +6,19 @@ class URI::TestFTP < Test::Unit::TestCase def setup end + + def test_build_does_not_mutate_components + components = {host: "example.test", path: "/folder"} + original = components.dup + + first = URI::FTP.build(components) + second = URI::FTP.build(components) + + assert_equal(original, components) + assert_equal(first, second) + assert_nothing_raised { URI::FTP.build(components.freeze) } + end + def test_parse url = URI.parse('ftp://user:pass@host.com/abc/def') assert_kind_of(URI::FTP, url)