Skip to content

Commit f17f78c

Browse files
Swantosauruschrisbra
authored andcommitted
patch 9.1.1875: username parsing bug in netrw plugin
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 <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent f0e11d3 commit f17f78c

File tree

4 files changed

+122
-2
lines changed

4 files changed

+122
-2
lines changed

runtime/pack/dist/opt/netrw/autoload/netrw.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
" 2025 Sep 17 by Vim Project tighten the regex to handle remote compressed archives #18318
1111
" 2025 Sep 18 by Vim Project 'equalalways' not always respected #18358
1212
" 2025 Oct 01 by Vim Project fix navigate to parent folder #18464
13+
" 2025 Oct 26 by Vim Project fix parsing of remote user names #18611
1314
" Copyright: Copyright (C) 2016 Charles E. Campbell {{{1
1415
" Permission is hereby granted to use and distribute this code,
1516
" with or without modifications, provided that this copyright
@@ -9312,7 +9313,7 @@ endfunction
93129313
function s:RemotePathAnalysis(dirname)
93139314

93149315
" method :// user @ machine :port /path
9315-
let dirpat = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
9316+
let dirpat = '^\(\w\{-}\)://\(\([^@]\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
93169317
let s:method = substitute(a:dirname,dirpat,'\1','')
93179318
let s:user = substitute(a:dirname,dirpat,'\3','')
93189319
let s:machine = substitute(a:dirname,dirpat,'\4','')
@@ -9656,5 +9657,4 @@ let &cpo= s:keepcpo
96569657
unlet s:keepcpo
96579658

96589659
" }}}
9659-
96609660
" vim:ts=8 sts=4 sw=4 et fdm=marker

src/testdir/Make_all.mak

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ NEW_TESTS = \
247247
test_plugin_helptoc \
248248
test_plugin_man \
249249
test_plugin_matchparen \
250+
test_plugin_netrw \
250251
test_plugin_tar \
251252
test_plugin_termdebug \
252253
test_plugin_tohtml \
@@ -520,6 +521,7 @@ NEW_TESTS_RES = \
520521
test_plugin_helptoc.res \
521522
test_plugin_man.res \
522523
test_plugin_matchparen.res \
524+
test_plugin_netrw.res \
523525
test_plugin_tar.res \
524526
test_plugin_termdebug.res \
525527
test_plugin_tohtml.res \

src/testdir/test_plugin_netrw.vim

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
let s:netrw_path = $VIMRUNTIME . '/pack/dist/opt/netrw/autoload/netrw.vim'
2+
let s:netrw_test_dir = 'samples'
3+
let s:netrw_test_path = s:netrw_test_dir . '/netrw.vim'
4+
5+
"make copy of netrw script and add function to print local variables"
6+
func s:appendDebugToNetrw(netrw_path, netrw_test_path)
7+
let netrwScript = readfile(a:netrw_path)
8+
9+
let netrwScript += [
10+
\ '\n',
11+
\ '"-- test helpers ---"',
12+
\ 'function! TestNetrwCaptureRemotePath(dirname)',
13+
\ ' call s:RemotePathAnalysis(a:dirname)',
14+
\ ' return {"method": s:method, "user": s:user, "machine": s:machine, "port": s:port, "path": s:path, "fname": s:fname}',
15+
\ 'endfunction'
16+
\ ]
17+
18+
call writefile(netrwScript, a:netrw_test_path)
19+
execute 'source' a:netrw_test_path
20+
endfunction
21+
22+
func s:setup()
23+
call s:appendDebugToNetrw(s:netrw_path, s:netrw_test_path)
24+
endfunction
25+
26+
func s:cleanup()
27+
call delete(s:netrw_test_path)
28+
endfunction
29+
30+
func s:combine
31+
\( usernames
32+
\, methods
33+
\, hosts
34+
\, ports
35+
\, dirs
36+
\, files)
37+
for username in a:usernames
38+
for method in a:methods
39+
for host in a:hosts
40+
for port in a:ports
41+
for dir in a:dirs
42+
for file in a:files
43+
" --- Build a full remote path ---
44+
45+
let port_str = empty(port) ? "" : ':' . port
46+
let remote = printf('%s://%s@%s%s/%s%s', method, username, host, port_str, dir, file)
47+
48+
let result = TestNetrwCaptureRemotePath(remote)
49+
50+
call assert_equal(result.method, method)
51+
call assert_equal(result.user, username)
52+
call assert_equal(result.machine, host)
53+
call assert_equal(result.port, port)
54+
call assert_equal(result.path, dir . file)
55+
endfor
56+
endfor
57+
endfor
58+
endfor
59+
endfor
60+
endfor
61+
endfunction
62+
63+
64+
func Test_netrw_parse_remote_simple()
65+
call s:setup()
66+
let result = TestNetrwCaptureRemotePath('scp://user@localhost:2222/test.txt')
67+
call assert_equal(result.method, 'scp')
68+
call assert_equal(result.user, 'user')
69+
call assert_equal(result.machine, 'localhost')
70+
call assert_equal(result.port, '2222')
71+
call assert_equal(result.path, 'test.txt')
72+
call s:cleanup()
73+
endfunction
74+
75+
"testing different combinations"
76+
func Test_netrw_parse_regular_usernames()
77+
call s:setup()
78+
79+
" --- sample data for combinations ---"
80+
let usernames = ["root", "toor", "user01", "skillIssue"]
81+
let methods = ["scp", "ssh", "ftp", "sftp"]
82+
let hosts = ["localhost", "server.com", "fit-workspaces.ksi.fit.cvut.cz", "192.168.1.42"]
83+
let ports = ["", "22","420", "443", "2222", "1234"]
84+
let dirs = ["", "somefolder/", "path/to/the/bottom/of/the/world/please/send/help/"]
85+
let files = ["test.txt", "tttt.vim", "Makefile"]
86+
87+
call s:combine(usernames, methods, hosts, ports, dirs, files)
88+
89+
call s:cleanup()
90+
endfunc
91+
92+
"Host myserver
93+
" HostName 192.168.1.42
94+
" User alice
95+
func Test_netrw_parse_ssh_config_entries()
96+
call s:setup()
97+
let result = TestNetrwCaptureRemotePath('scp://myserver//etc/nginx/nginx.conf')
98+
call assert_equal(result.method, 'scp')
99+
call assert_equal(result.user, '')
100+
call assert_equal(result.machine, 'myserver')
101+
call assert_equal(result.port, '')
102+
call assert_equal(result.path, '/etc/nginx/nginx.conf')
103+
call s:cleanup()
104+
endfunction
105+
106+
"username containing special-chars"
107+
func Test_netrw_parse_special_char_user ()
108+
call s:setup()
109+
let result = TestNetrwCaptureRemotePath('scp://user-01@localhost:2222/test.txt')
110+
call assert_equal(result.method, 'scp')
111+
call assert_equal(result.user, 'user-01')
112+
call assert_equal(result.machine, 'localhost')
113+
call assert_equal(result.port, '2222')
114+
call assert_equal(result.path, 'test.txt')
115+
call s:cleanup()
116+
endfunction

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@ static char *(features[]) =
729729

730730
static int included_patches[] =
731731
{ /* Add new patch number below this line */
732+
/**/
733+
1875,
732734
/**/
733735
1874,
734736
/**/

0 commit comments

Comments
 (0)