From 72bc6c5801867e8f99a87737a64c1713ceac1e01 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 28 Apr 2026 08:07:57 +0800 Subject: [PATCH] vim-patch:9.2.0405: when jumping to tags, will open URLs (#39461) Problem: when jumping to tags, will open URLs (Srinivas Piskala Ganesh Babu) Solution: Disallow trying to open remote files. closes: vim/vim#20068 Supported by AI https://github.com/vim/vim/commit/ae196b2d589562fbb3fcd64cd0cc33f052c6cf56 Co-authored-by: Christian Brabandt --- runtime/doc/tagsrch.txt | 3 +++ src/gen/gen_help_html.lua | 1 + src/nvim/errors.h | 1 + src/nvim/tag.c | 21 +++++++++++++++++---- test/old/testdir/test_tagjump.vim | 11 +++++++++++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index 67b2e41fbc..3daaf5b1b5 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -577,6 +577,9 @@ ctags). have an absolute or relative path. It may contain environment variables and wildcards (although the use of wildcards is doubtful). It cannot contain a . + *E1576* + Using a remote file via network protocol (e.g. using + http://remote/file.txt) is not allowed. {tagaddress} The Ex command that positions the cursor on the tag. It can be any Ex command, although restrictions apply (see |tag-security|). Posix only allows line numbers and search diff --git a/src/gen/gen_help_html.lua b/src/gen/gen_help_html.lua index fa0d155f65..3114be42e8 100644 --- a/src/gen/gen_help_html.lua +++ b/src/gen/gen_help_html.lua @@ -132,6 +132,7 @@ local exclude_invalid_urls = { ['http://wiki.services.openoffice.org/wiki/Dictionaries'] = 'spell.txt', ['http://www.adapower.com'] = 'ft_ada.txt', ['http://www.jclark.com/'] = 'quickfix.txt', + ['http://remote/file.txt'] = 'tagsrch.txt', -- Can't be accessed by GitHub runners: ['https://cacm.acm.org/research/a-look-at-the-design-of-lua/'] = 'faq.txt', diff --git a/src/nvim/errors.h b/src/nvim/errors.h index 113b2058ff..7b5f83f4f9 100644 --- a/src/nvim/errors.h +++ b/src/nvim/errors.h @@ -223,6 +223,7 @@ EXTERN const char e_cannot_have_more_than_nr_diff_anchors[] INIT( = N_("E1549: C EXTERN const char e_failed_to_find_all_diff_anchors[] INIT( = N_("E1550: Failed to find all diff anchors")); EXTERN const char e_diff_anchors_with_hidden_windows[] INIT( = N_("E1562: Diff anchors cannot be used with hidden diff windows")); EXTERN const char e_leadtab_requires_tab[] INIT( = N_("E1572: 'listchars' field \"leadtab\" requires \"tab\" to be specified")); +EXTERN const char e_tag_file_entry_must_not_be_url[] INIT( = N_("E1576: Tag file entry must not be a URL")); EXTERN const char e_trustfile[] INIT(= N_("E5570: Cannot update trust file: %s")); EXTERN const char e_cannot_read_from_str_2[] INIT(= N_("E282: Cannot read from \"%s\"")); diff --git a/src/nvim/tag.c b/src/nvim/tag.c index dc4c59e767..fb2ae19d79 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2734,7 +2734,7 @@ static int parse_match(char *lbuf, tagptrs_T *tagp) // Find out the actual file name of a tag. Concatenate the tags file name // with the matching tag file name. -// Returns an allocated string. +// Returns an allocated string, or NULL on failure. static char *tag_full_fname(tagptrs_T *tagp) { char c = *tagp->fname_end; @@ -2806,6 +2806,9 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help) // Expand file name, when needed (for environment variables). // If 'tagrelative' option set, may change file name. fname = expand_tag_fname(fname, tagp.tag_fname, true); + if (fname == NULL) { + goto erret; + } tofree_fname = fname; // free() it later // Check if the file with the tag exists before abandoning the current @@ -3057,13 +3060,21 @@ erret: /// If 'tagrelative' option set, change fname (name of file containing tag) /// according to tag_fname (name of tag file containing fname). /// -/// @return a pointer to allocated memory. +/// @return a pointer to allocated memory, or NULL on failure. static char *expand_tag_fname(char *fname, char *const tag_fname, const bool expand) { char *p; char *expanded_fname = NULL; expand_T xpc; + // Refuse to follow URLs from tag files. Tag entries are expected + // to reference local source files; a URL would otherwise be passed + // to netrw and trigger a network request. + if (path_with_url(fname)) { + emsg(_(e_tag_file_entry_must_not_be_url)); + return NULL; + } + fname = TO_SLASH_SAVE(fname); // Expand file name (for environment variables) when needed. @@ -3114,8 +3125,10 @@ static int test_for_current(char *fname, char *fname_end, char *tag_fname, char *fname_end = NUL; } char *fullname = expand_tag_fname(fname, tag_fname, true); - retval = (path_full_compare(fullname, buf_ffname, true, true) & kEqualFiles); - xfree(fullname); + if (fullname != NULL) { + retval = (path_full_compare(fullname, buf_ffname, true, true) & kEqualFiles); + xfree(fullname); + } *fname_end = c; } diff --git a/test/old/testdir/test_tagjump.vim b/test/old/testdir/test_tagjump.vim index 2d6ef245c9..01b4b8e75b 100644 --- a/test/old/testdir/test_tagjump.vim +++ b/test/old/testdir/test_tagjump.vim @@ -1751,4 +1751,15 @@ func Test_tag_backtick_filename_not_expanded() bwipe! endfunc +func Test_tagjump_refuse_url() + call writefile([ + \ "XTagURL\thttp://127.0.0.1:1/$XTAG_SECRET/file.c\t/^int main" + \ ], 'Xtags', 'D') + let save_tags = &tags + set tags=Xtags + + call assert_fails('tag XTagURL', 'E1576:') + let &tags = save_tags +endfunc + " vim: shiftwidth=2 sts=2 expandtab