mirror of
https://github.com/junegunn/fzf.git
synced 2026-08-15 12:21:06 +08:00
Pre-create become file with O_EXCL
Prevents another user on a shared TMPDIR from planting a file or a symbolic link at the predictable path while fzf is running, like the exit status file of the floating pane. Reject an empty become command.
This commit is contained in:
+13
-3
@@ -138,6 +138,17 @@ func runProxy(commandPrefix string, cmdBuilder func(temp string, needBash bool)
|
|||||||
temp := WriteTemporaryFile(append(exports, command), "\n")
|
temp := WriteTemporaryFile(append(exports, command), "\n")
|
||||||
defer os.Remove(temp)
|
defer os.Remove(temp)
|
||||||
|
|
||||||
|
// Pre-create the become file so that another user on a shared TMPDIR
|
||||||
|
// cannot plant a file or a symbolic link at the predictable path while
|
||||||
|
// fzf is running
|
||||||
|
becomeFile := temp + becomeSuffix
|
||||||
|
becomeF, err := os.OpenFile(becomeFile, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o600)
|
||||||
|
if err != nil {
|
||||||
|
return ExitError, err
|
||||||
|
}
|
||||||
|
becomeF.Close()
|
||||||
|
defer os.Remove(becomeFile)
|
||||||
|
|
||||||
cmd, err := cmdBuilder(temp, needBash)
|
cmd, err := cmdBuilder(temp, needBash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ExitError, err
|
return ExitError, err
|
||||||
@@ -155,16 +166,15 @@ func runProxy(commandPrefix string, cmdBuilder func(temp string, needBash bool)
|
|||||||
if exitError, ok := err.(*exec.ExitError); ok {
|
if exitError, ok := err.(*exec.ExitError); ok {
|
||||||
code := exitError.ExitCode()
|
code := exitError.ExitCode()
|
||||||
if code == ExitBecome {
|
if code == ExitBecome {
|
||||||
becomeFile := temp + becomeSuffix
|
|
||||||
data, err := os.ReadFile(becomeFile)
|
data, err := os.ReadFile(becomeFile)
|
||||||
os.Remove(becomeFile)
|
os.Remove(becomeFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ExitError, err
|
return ExitError, err
|
||||||
}
|
}
|
||||||
elems := strings.Split(string(data), "\x00")
|
if len(data) == 0 {
|
||||||
if len(elems) < 1 {
|
|
||||||
return ExitError, errors.New("invalid become command")
|
return ExitError, errors.New("invalid become command")
|
||||||
}
|
}
|
||||||
|
elems := strings.Split(string(data), "\x00")
|
||||||
command := elems[0]
|
command := elems[0]
|
||||||
env := []string{}
|
env := []string{}
|
||||||
if len(elems) > 1 {
|
if len(elems) > 1 {
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ class TestTmux < TestInteractive
|
|||||||
assert_equal '1', fzf_output
|
assert_equal '1', fzf_output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_floating_pane_become
|
||||||
|
tmux.send_keys "seq 100 | #{fzf(%(--popup center,80% --margin 0 --bind 'enter:become(echo became-{})'))}", :Enter
|
||||||
|
tmux.until { |lines| assert_equal 100, lines.item_count }
|
||||||
|
tmux.send_keys :Enter
|
||||||
|
assert_equal 'became-1', fzf_output
|
||||||
|
end
|
||||||
|
|
||||||
def test_explicit_border_falls_back_to_popup
|
def test_explicit_border_falls_back_to_popup
|
||||||
# display-popup requires an attached client, which the test environment
|
# display-popup requires an attached client, which the test environment
|
||||||
# may not have; intercept it with a tmux shim on PATH
|
# may not have; intercept it with a tmux shim on PATH
|
||||||
|
|||||||
Reference in New Issue
Block a user