Sandbox the tag address in the preview too

A preview runs as soon as an entry is highlighted, so a crafted tags file did not
even need to be selected to get a shell command out of 'vim -c "silent {excmd}"'.
The address goes to ':execute' as a string literal with its quotes doubled, since
':sandbox' as a modifier would stop at the first '|'.

An entry with no address is refused rather than previewing the last line of the
file, which is where Ex mode leaves the cursor.
This commit is contained in:
Junegunn Choi
2026-09-28 22:50:14 +09:00
parent 506f0167b4
commit 96c08602ac
+13 -1
View File
@@ -30,9 +30,21 @@ else
exit 1
fi
# Ex mode starts on the last line, so an entry with no address would report the
# end of the file as the tag. Every other path refuses such an entry
if [ -z "${EXCMD}" ]; then
exit 1
fi
# The address comes from a tags file, which can be untrusted, and a preview runs
# as soon as an entry is highlighted. Sandboxed as a builtin tag jump is, so that
# it cannot run a shell command or touch a file. ':sandbox' on its own only covers
# the command up to the first '|', so hand the whole address to ':execute' as a
# string literal, doubling the quotes in it
EXCMD_LITERAL=${EXCMD//\'/\'\'}
CENTER="$("${VIMNAME}" -R -i NONE -u NONE -e -m -s "${FILE}" \
-c "set nomagic" \
-c "silent ${EXCMD}" \
-c "silent sandbox execute '${EXCMD_LITERAL}'" \
-c 'let l=line(".") | new | put =l | print | qa!')" || exit
START_LINE="$(( CENTER - FZF_PREVIEW_LINES / 2 ))"