cmd/age: detect output/input file reuse when possible

Fixes #491
This commit is contained in:
Filippo Valsorda
2024-06-16 14:40:13 +02:00
parent febaaded87
commit bd0511b415
2 changed files with 48 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path/filepath"
"regexp" "regexp"
"runtime/debug" "runtime/debug"
"strings" "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 in io.Reader = os.Stdin
var out io.Writer = os.Stdout var out io.Writer = os.Stdout
if name := flag.Arg(0); name != "" && name != "-" { if name := flag.Arg(0); name != "" && name != "-" {
inUseFiles = append(inUseFiles, absPath(name))
f, err := os.Open(name) f, err := os.Open(name)
if err != nil { if err != nil {
errorf("failed to open input file %q: %v", name, err) errorf("failed to open input file %q: %v", name, err)
@@ -246,6 +259,11 @@ func main() {
} }
} }
if name := outFlag; name != "" && name != "-" { 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) f := newLazyOpener(name)
defer func() { defer func() {
if err := f.Close(); err != nil { if err := f.Close(); err != nil {
@@ -532,3 +550,10 @@ func (l *lazyOpener) Close() error {
} }
return nil return nil
} }
func absPath(name string) string {
if abs, err := filepath.Abs(name); err == nil {
return abs
}
return name
}

View File

@@ -25,9 +25,32 @@ age -d -i key.txt -o new empty.age
! stderr . ! stderr .
cmp new empty 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 [!linux] [!darwin] skip # no pty support
[darwin] [go1.20] skip # https://go.dev/issue/61779 [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 # https://github.com/FiloSottile/age/issues/159
ttyin terminal ttyin terminal
age -p -a -o test.age input age -p -a -o test.age input