]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1875: username parsing bug in netrw plugin v9.1.1875
authorVáclav Kobera <vasekobera@gmail.com>
Sun, 26 Oct 2025 18:21:04 +0000 (18:21 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 26 Oct 2025 18:21:04 +0000 (18:21 +0000)
Problem:  username parsing bug in netrw plugin when using remote adding
          feature
Solution: Allow any characters except for "@" (Václav Kobera), add a
          test for the netrw plugin

closes: #18611

Signed-off-by: Václav Kobera <vasekobera@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/pack/dist/opt/netrw/autoload/netrw.vim
src/testdir/Make_all.mak
src/testdir/test_plugin_netrw.vim [new file with mode: 0644]
src/version.c

index 6206be79ae0c448e4ca040690f24469c8f45dbe4..f1ce7f393eafe82d52035ccf7a88c9ffdb7a8cdf 100644 (file)
@@ -10,6 +10,7 @@
 " 2025 Sep 17 by Vim Project tighten the regex to handle remote compressed archives #18318
 " 2025 Sep 18 by Vim Project 'equalalways' not always respected #18358
 " 2025 Oct 01 by Vim Project fix navigate to parent folder #18464
+" 2025 Oct 26 by Vim Project fix parsing of remote user names #18611
 " Copyright:  Copyright (C) 2016 Charles E. Campbell {{{1
 "             Permission is hereby granted to use and distribute this code,
 "             with or without modifications, provided that this copyright
@@ -9312,7 +9313,7 @@ endfunction
 function s:RemotePathAnalysis(dirname)
 
     "                method   ://    user  @      machine      :port            /path
-    let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
+    let dirpat  = '^\(\w\{-}\)://\(\([^@]\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
     let s:method  = substitute(a:dirname,dirpat,'\1','')
     let s:user    = substitute(a:dirname,dirpat,'\3','')
     let s:machine = substitute(a:dirname,dirpat,'\4','')
@@ -9656,5 +9657,4 @@ let &cpo= s:keepcpo
 unlet s:keepcpo
 
 " }}}
-
 " vim:ts=8 sts=4 sw=4 et fdm=marker
index 0d4aeb0432fb506008c5f9366e9ed5b1d275683c..a587034c81150a6acbbb17de7044f2bebb443e14 100644 (file)
@@ -247,6 +247,7 @@ NEW_TESTS = \
        test_plugin_helptoc \
        test_plugin_man \
        test_plugin_matchparen \
+       test_plugin_netrw \
        test_plugin_tar \
        test_plugin_termdebug \
        test_plugin_tohtml \
@@ -520,6 +521,7 @@ NEW_TESTS_RES = \
        test_plugin_helptoc.res \
        test_plugin_man.res \
        test_plugin_matchparen.res \
+       test_plugin_netrw.res \
        test_plugin_tar.res \
        test_plugin_termdebug.res \
        test_plugin_tohtml.res \
diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim
new file mode 100644 (file)
index 0000000..750a7d1
--- /dev/null
@@ -0,0 +1,116 @@
+let s:netrw_path =        $VIMRUNTIME . '/pack/dist/opt/netrw/autoload/netrw.vim'
+let s:netrw_test_dir  =   'samples'
+let s:netrw_test_path =   s:netrw_test_dir . '/netrw.vim'
+
+"make copy of netrw script and add function to print local variables"
+func s:appendDebugToNetrw(netrw_path, netrw_test_path)
+  let netrwScript = readfile(a:netrw_path)
+
+  let netrwScript += [
+       \ '\n',
+       \ '"-- test helpers ---"',
+       \ 'function! TestNetrwCaptureRemotePath(dirname)',
+       \ '  call s:RemotePathAnalysis(a:dirname)',
+       \ '  return {"method": s:method, "user": s:user, "machine": s:machine, "port": s:port, "path": s:path, "fname": s:fname}',
+       \ 'endfunction'
+       \ ]
+
+  call writefile(netrwScript, a:netrw_test_path)
+  execute 'source' a:netrw_test_path
+endfunction
+
+func s:setup()
+  call s:appendDebugToNetrw(s:netrw_path, s:netrw_test_path)
+endfunction
+
+func s:cleanup()
+  call delete(s:netrw_test_path)
+endfunction
+
+func s:combine
+  \( usernames
+  \, methods
+  \, hosts
+  \, ports
+  \, dirs
+  \, files)
+  for username in a:usernames
+    for method in a:methods
+      for host in a:hosts
+        for port in a:ports
+          for dir in a:dirs
+            for file in a:files
+               " --- Build a full remote path ---
+
+              let port_str = empty(port) ? "" : ':' . port
+              let remote = printf('%s://%s@%s%s/%s%s', method, username, host, port_str, dir, file)
+
+              let result = TestNetrwCaptureRemotePath(remote)
+
+              call assert_equal(result.method, method)
+              call assert_equal(result.user, username)
+              call assert_equal(result.machine, host)
+              call assert_equal(result.port, port)
+              call assert_equal(result.path, dir . file)
+            endfor
+          endfor
+        endfor
+      endfor
+    endfor
+  endfor
+endfunction
+
+
+func Test_netrw_parse_remote_simple()
+  call s:setup()
+  let result = TestNetrwCaptureRemotePath('scp://user@localhost:2222/test.txt')
+  call assert_equal(result.method, 'scp')
+  call assert_equal(result.user, 'user')
+  call assert_equal(result.machine, 'localhost')
+  call assert_equal(result.port, '2222')
+  call assert_equal(result.path, 'test.txt')
+  call s:cleanup()
+endfunction
+
+"testing different combinations"
+func Test_netrw_parse_regular_usernames()
+  call s:setup()
+
+  " --- sample data for combinations ---"
+  let usernames = ["root", "toor", "user01", "skillIssue"]
+  let methods = ["scp", "ssh", "ftp", "sftp"]
+  let hosts = ["localhost", "server.com", "fit-workspaces.ksi.fit.cvut.cz", "192.168.1.42"]
+  let ports = ["", "22","420", "443", "2222", "1234"]
+  let dirs = ["", "somefolder/", "path/to/the/bottom/of/the/world/please/send/help/"]
+  let files = ["test.txt", "tttt.vim", "Makefile"]
+
+  call s:combine(usernames, methods, hosts, ports, dirs, files)
+
+  call s:cleanup()
+endfunc
+
+"Host myserver
+"    HostName 192.168.1.42
+"    User alice
+func Test_netrw_parse_ssh_config_entries()
+  call s:setup()
+  let result = TestNetrwCaptureRemotePath('scp://myserver//etc/nginx/nginx.conf')
+  call assert_equal(result.method, 'scp')
+  call assert_equal(result.user, '')
+  call assert_equal(result.machine, 'myserver')
+  call assert_equal(result.port, '')
+  call assert_equal(result.path, '/etc/nginx/nginx.conf')
+  call s:cleanup()
+endfunction
+
+"username containing special-chars"
+func Test_netrw_parse_special_char_user ()
+  call s:setup()
+  let result = TestNetrwCaptureRemotePath('scp://user-01@localhost:2222/test.txt')
+  call assert_equal(result.method, 'scp')
+  call assert_equal(result.user, 'user-01')
+  call assert_equal(result.machine, 'localhost')
+  call assert_equal(result.port, '2222')
+  call assert_equal(result.path, 'test.txt')
+  call s:cleanup()
+endfunction
index fd8ccb7c0b49d1c68f994b0348240614834fc2a5..2fdb0871b5763ea12771e9ad9d13634b42e456b9 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1875,
 /**/
     1874,
 /**/