[vim/vim] tagfunc "cmd" with a generic Ex command corrupts the tag entry (PR #20828)

1 view
Skip to first unread message

h_east

unread,
Jul 23, 2026, 9:06:57 AM (yesterday) Jul 23
to vim/vim, Subscribed
Problem:  When a tagfunc returns a "cmd" that is neither a line number nor
          a search pattern, the tag entry is corrupted: the "kind" field is
          lost and taglist() returns a mangled "cmd".
Solution: Accept any Ex command in "cmd" as in a tags file, terminate a
          generic command with a bar so the trailing fields are preserved,
          and reject a value that cannot be stored in a tag line with E987.

Supersedes #20790, opened as a separate PR at the author's request.

closes #20781


Why not the #20790 approach

#20790 wrapped every "cmd" with a leading ":" and a trailing "|". That
regressed a search-pattern jump: with cmd = "/bar/" the cursor landed on
column 1 instead of the matched column 5, because the stored ":/bar/|;""
no longer took the do_search() path and fell through to ":/bar/", which
only moves by line.

This PR classifies "cmd" like a tags file address instead:

  • a line number, or a delimited /pat/ or ?pat?, is stored unchanged, so
    the do_search() path and its column positioning are preserved (no
    regression);
  • any other Ex command is treated as generic, terminated with a "|" so
    the trailing ";"{kind} fields survive (this is what fixes the
    lost "kind" field reported in #20781);
  • a value that cannot be stored in a tag line (an unterminated pattern,
    trailing junk after the closing delimiter, or a /newline in a
    generic command) is rejected with E987.

Security

A generic command runs on a tag jump under 'secure' and the sandbox,
exactly like a command from a tags file. Destructive calls such as
delete(), writefile(), system() and ":!" are blocked (E523/E12), so this
adds no new attack surface.

Tests

  • Test_tagfunc_invalid_cmd: E987 for each invalid form; every valid form
    round-trips through taglist() with the "kind" field intact.
  • Test_tagfunc_cmd_jump: "/bar/", "call cursor(3, 5)" and "normal! 3G5|"
    all land on [3, 5] (a regression guard for the search-pattern column).
  • Test_tagfunc_cmd_secure: a destructive generic command is blocked with
    E12 and the target file survives.

make test_tagfunc and make test_tagjump both pass.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/20828

Commit Summary

  • 9de49f8 tagfunc "cmd" with a generic Ex command corrupts the tag entry

File Changes

(3 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20828@github.com>

Reply all
Reply to author
Forward
0 new messages