diff --git a/changelog/unreleased/issue-4975 b/changelog/unreleased/issue-4975 new file mode 100644 index 000000000..0e29935f5 --- /dev/null +++ b/changelog/unreleased/issue-4975 @@ -0,0 +1,6 @@ +Bugfix: Prevent `backup --stdin-from-command` from panicking + +If --stdin-from-command is used, restic now checks whether there is a command behind it. + +https://github.com/restic/restic/issues/4975 +https://github.com/restic/restic/pull/4976 diff --git a/internal/fs/fs_reader_command.go b/internal/fs/fs_reader_command.go index 3830e5811..6d061f641 100644 --- a/internal/fs/fs_reader_command.go +++ b/internal/fs/fs_reader_command.go @@ -29,6 +29,10 @@ type CommandReader struct { } func NewCommandReader(ctx context.Context, args []string, logOutput io.Writer) (*CommandReader, error) { + if len(args) == 0 { + return nil, fmt.Errorf("no command was specified as argument") + } + // Prepare command and stdout command := exec.CommandContext(ctx, args[0], args[1:]...) stdout, err := command.StdoutPipe() diff --git a/internal/fs/fs_reader_command_test.go b/internal/fs/fs_reader_command_test.go index a9028544c..8f0d17b1e 100644 --- a/internal/fs/fs_reader_command_test.go +++ b/internal/fs/fs_reader_command_test.go @@ -34,6 +34,11 @@ func TestCommandReaderInvalid(t *testing.T) { test.Assert(t, err != nil, "missing error") } +func TestCommandReaderEmptyArgs(t *testing.T) { + _, err := fs.NewCommandReader(context.TODO(), []string{}, io.Discard) + test.Assert(t, err != nil, "missing error") +} + func TestCommandReaderOutput(t *testing.T) { reader, err := fs.NewCommandReader(context.TODO(), []string{"echo", "hello world"}, io.Discard) test.OK(t, err)