diff --git a/changelog/unreleased/issue-3861 b/changelog/unreleased/issue-3861 new file mode 100644 index 000000000..3d399df0b --- /dev/null +++ b/changelog/unreleased/issue-3861 @@ -0,0 +1,8 @@ +Bugfix: Yield error on invalid policy to `forget` + +The `forget` command previously silently ignored invalid/unsupported +units in the duration options, such as e.g. `--keep-within-daily 2w`. + +Specifying an invalid/unsupported duration unit now results in an error. + +https://github.com/restic/restic/issues/3861 diff --git a/internal/restic/duration.go b/internal/restic/duration.go index ad56bcc81..4c9112a7c 100644 --- a/internal/restic/duration.go +++ b/internal/restic/duration.go @@ -106,6 +106,8 @@ func ParseDuration(s string) (Duration, error) { d.Days = num case 'h': d.Hours = num + default: + return Duration{}, errors.Errorf("invalid unit %q found after number %d", s[0], num) } s = s[1:] diff --git a/internal/restic/duration_test.go b/internal/restic/duration_test.go index 716c00cc9..b46fc66be 100644 --- a/internal/restic/duration_test.go +++ b/internal/restic/duration_test.go @@ -63,23 +63,27 @@ func TestParseDuration(t *testing.T) { input string d Duration output string + err bool }{ - {"9h", Duration{Hours: 9}, "9h"}, - {"3d", Duration{Days: 3}, "3d"}, - {"4d2h", Duration{Days: 4, Hours: 2}, "4d2h"}, - {"7m5d", Duration{Months: 7, Days: 5}, "7m5d"}, - {"6m4d8h", Duration{Months: 6, Days: 4, Hours: 8}, "6m4d8h"}, - {"5d7m", Duration{Months: 7, Days: 5}, "7m5d"}, - {"4h3d9m", Duration{Months: 9, Days: 3, Hours: 4}, "9m3d4h"}, - {"-7m5d", Duration{Months: -7, Days: 5}, "-7m5d"}, - {"1y4m-5d-3h", Duration{Years: 1, Months: 4, Days: -5, Hours: -3}, "1y4m-5d-3h"}, - {"2y7m-5d", Duration{Years: 2, Months: 7, Days: -5}, "2y7m-5d"}, + {input: "9h", d: Duration{Hours: 9}, output: "9h"}, + {input: "3d", d: Duration{Days: 3}, output: "3d"}, + {input: "4d2h", d: Duration{Days: 4, Hours: 2}, output: "4d2h"}, + {input: "7m5d", d: Duration{Months: 7, Days: 5}, output: "7m5d"}, + {input: "6m4d8h", d: Duration{Months: 6, Days: 4, Hours: 8}, output: "6m4d8h"}, + {input: "5d7m", d: Duration{Months: 7, Days: 5}, output: "7m5d"}, + {input: "4h3d9m", d: Duration{Months: 9, Days: 3, Hours: 4}, output: "9m3d4h"}, + {input: "-7m5d", d: Duration{Months: -7, Days: 5}, output: "-7m5d"}, + {input: "1y4m-5d-3h", d: Duration{Years: 1, Months: 4, Days: -5, Hours: -3}, output: "1y4m-5d-3h"}, + {input: "2y7m-5d", d: Duration{Years: 2, Months: 7, Days: -5}, output: "2y7m-5d"}, + {input: "2w", err: true}, + {input: "1y4m3w1d", err: true}, + {input: "s", err: true}, } for _, test := range tests { t.Run("", func(t *testing.T) { d, err := ParseDuration(test.input) - if err != nil { + if err != nil && !test.err { t.Fatal(err) }