From bd0511b415355bf84a3861c77d47d9337ab367b1 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Sun, 16 Jun 2024 14:40:13 +0200 Subject: [PATCH] cmd/age: detect output/input file reuse when possible Fixes #491 --- cmd/age/age.go | 25 +++++++++++++++++++++++++ cmd/age/testdata/output_file.txt | 23 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/cmd/age/age.go b/cmd/age/age.go index c49ce341..e5d17e2b 100644 --- a/cmd/age/age.go +++ b/cmd/age/age.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "os" + "path/filepath" "regexp" "runtime/debug" "strings" @@ -223,9 +224,21 @@ func main() { } } + var inUseFiles []string + for _, i := range identityFlags { + if i.Type != "i" { + continue + } + inUseFiles = append(inUseFiles, absPath(i.Value)) + } + for _, f := range recipientsFileFlags { + inUseFiles = append(inUseFiles, absPath(f)) + } + var in io.Reader = os.Stdin var out io.Writer = os.Stdout if name := flag.Arg(0); name != "" && name != "-" { + inUseFiles = append(inUseFiles, absPath(name)) f, err := os.Open(name) if err != nil { errorf("failed to open input file %q: %v", name, err) @@ -246,6 +259,11 @@ func main() { } } if name := outFlag; name != "" && name != "-" { + for _, f := range inUseFiles { + if f == absPath(name) { + errorf("input and output file are the same: %q", name) + } + } f := newLazyOpener(name) defer func() { if err := f.Close(); err != nil { @@ -532,3 +550,10 @@ func (l *lazyOpener) Close() error { } return nil } + +func absPath(name string) string { + if abs, err := filepath.Abs(name); err == nil { + return abs + } + return name +} diff --git a/cmd/age/testdata/output_file.txt b/cmd/age/testdata/output_file.txt index e7952a7e..5b16d654 100644 --- a/cmd/age/testdata/output_file.txt +++ b/cmd/age/testdata/output_file.txt @@ -25,9 +25,32 @@ age -d -i key.txt -o new empty.age ! stderr . cmp new empty +# https://github.com/FiloSottile/age/issues/491 +cp input inputcopy +! age -r age1xmwwc06ly3ee5rytxm9mflaz2u56jjj36s0mypdrwsvlul66mv4q47ryef -o inputcopy inputcopy +stderr 'input and output file are the same' +cmp inputcopy input +! age -r age1xmwwc06ly3ee5rytxm9mflaz2u56jjj36s0mypdrwsvlul66mv4q47ryef -o ./inputcopy inputcopy +stderr 'input and output file are the same' +cmp inputcopy input +mkdir foo +! age -r age1xmwwc06ly3ee5rytxm9mflaz2u56jjj36s0mypdrwsvlul66mv4q47ryef -o inputcopy foo/../inputcopy +stderr 'input and output file are the same' +cmp inputcopy input +cp key.txt keycopy +age -e -i keycopy -o test.age input +! age -d -i keycopy -o keycopy test.age +stderr 'input and output file are the same' +cmp key.txt keycopy + [!linux] [!darwin] skip # no pty support [darwin] [go1.20] skip # https://go.dev/issue/61779 +ttyin terminal +! age -p -o inputcopy inputcopy +stderr 'input and output file are the same' +cmp inputcopy input + # https://github.com/FiloSottile/age/issues/159 ttyin terminal age -p -a -o test.age input