From 5b2735a341dc6c5299a0d74ce0911b397f7b95ed Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 7 May 2024 13:33:31 -0700 Subject: [PATCH] Stricter parsing (#8) Closes issue #4 * check for leading P, allow for negative * use switch, add more invalid period string tests, increase parser strictness again * simplify negative parsing --- duration.go | 19 ++++++++++++------- duration_test.go | 12 ++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/duration.go b/duration.go index 08f9d3e..9a0f7a4 100644 --- a/duration.go +++ b/duration.go @@ -49,21 +49,26 @@ var ( // Parse attempts to parse the given duration string into a *Duration, // if parsing fails an error is returned instead. func Parse(d string) (*Duration, error) { - if !strings.Contains(d, "P") { - return nil, ErrUnexpectedInput - } - state := parsingPeriod duration := &Duration{} num := "" var err error + switch { + case strings.HasPrefix(d, "P"): // standard duration + case strings.HasPrefix(d, "-P"): // negative duration + duration.Negative = true + d = strings.TrimPrefix(d, "-") // remove the negative sign + default: + return nil, ErrUnexpectedInput + } + for _, char := range d { switch char { - case '-': - duration.Negative = true case 'P': - state = parsingPeriod + if state != parsingPeriod { + return nil, ErrUnexpectedInput + } case 'T': state = parsingTime case 'Y': diff --git a/duration_test.go b/duration_test.go index d938ec0..36a51c4 100644 --- a/duration_test.go +++ b/duration_test.go @@ -23,6 +23,18 @@ func TestParse(t *testing.T) { want: nil, wantErr: true, }, + { + name: "invalid-duration-2", + args: args{d: "P-T0S"}, + want: nil, + wantErr: true, + }, + { + name: "invalid-duration-3", + args: args{d: "PT0SP0D"}, + want: nil, + wantErr: true, + }, { name: "period-only", args: args{d: "P4Y"},