diff --git a/cmd/restic/cmd_forget.go b/cmd/restic/cmd_forget.go index fbe4c1c8a..caa205a45 100644 --- a/cmd/restic/cmd_forget.go +++ b/cmd/restic/cmd_forget.go @@ -99,8 +99,40 @@ func init() { addPruneOptions(cmdForget) } +func verifyForgetOptions(opts *ForgetOptions) error { + var negValFound = false + + if opts.Last < -1 || opts.Hourly < -1 || opts.Daily < -1 || opts.Weekly < -1 || + opts.Monthly < -1 || opts.Yearly < -1 { + negValFound = true + } + + if !negValFound { + // durations := [6]restic.Duration{opts.Within, opts.WithinHourly, opts.WithinDaily, + // opts.WithinMonthly, opts.WithinWeekly, opts.WithinYearly} + for _, d := range [6]restic.Duration{opts.Within, opts.WithinHourly, opts.WithinDaily, + opts.WithinMonthly, opts.WithinWeekly, opts.WithinYearly} { + if d.Hours < -1 || d.Days < -1 || d.Months < -1 || d.Years < -1 { + negValFound = true + break + } + } + } + + if negValFound { + return errors.Fatal("negative values other than -1 are not allowed for --keep-* options") + } + + return nil +} + func runForget(ctx context.Context, opts ForgetOptions, gopts GlobalOptions, args []string) error { - err := verifyPruneOptions(&pruneOptions) + err := verifyForgetOptions(&opts) + if err != nil { + return err + } + + err = verifyPruneOptions(&pruneOptions) if err != nil { return err } diff --git a/cmd/restic/cmd_forget_test.go b/cmd/restic/cmd_forget_test.go new file mode 100644 index 000000000..778df4549 --- /dev/null +++ b/cmd/restic/cmd_forget_test.go @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/restic/restic/internal/restic" + rtest "github.com/restic/restic/internal/test" +) + +func TestPreventNegativeForgetOptionValues(t *testing.T) { + invalidForgetOpts := []ForgetOptions{ + {Last: -2}, + {Hourly: -2}, + {Daily: -2}, + {Weekly: -2}, + {Monthly: -2}, + {Yearly: -2}, + {Within: restic.Duration{Hours: -2}}, + {Within: restic.Duration{Days: -2}}, + {Within: restic.Duration{Months: -2}}, + {Within: restic.Duration{Years: -2}}, + {WithinHourly: restic.Duration{Hours: -2}}, + {WithinHourly: restic.Duration{Days: -2}}, + {WithinHourly: restic.Duration{Months: -2}}, + {WithinHourly: restic.Duration{Years: -2}}, + {WithinDaily: restic.Duration{Hours: -2}}, + {WithinDaily: restic.Duration{Days: -2}}, + {WithinDaily: restic.Duration{Months: -2}}, + {WithinDaily: restic.Duration{Years: -2}}, + {WithinWeekly: restic.Duration{Hours: -2}}, + {WithinWeekly: restic.Duration{Days: -2}}, + {WithinWeekly: restic.Duration{Months: -2}}, + {WithinWeekly: restic.Duration{Years: -2}}, + {WithinMonthly: restic.Duration{Hours: -2}}, + {WithinMonthly: restic.Duration{Days: -2}}, + {WithinMonthly: restic.Duration{Months: -2}}, + {WithinMonthly: restic.Duration{Years: -2}}, + {WithinYearly: restic.Duration{Hours: -2}}, + {WithinYearly: restic.Duration{Days: -2}}, + {WithinYearly: restic.Duration{Months: -2}}, + {WithinYearly: restic.Duration{Years: -2}}, + } + + for _, opts := range invalidForgetOpts { + err := verifyForgetOptions(&opts) + rtest.Assert(t, err != nil, fmt.Sprintf("should have returned error for %+v", opts)) + rtest.Equals(t, "Fatal: negative values other than -1 are not allowed for --keep-* options", err.Error()) + } +}