Skip to content

Commit

Permalink
Validate duration overflow
Browse files Browse the repository at this point in the history
Fix prometheus/prometheus#8526

Co-authored-by: Julien Pivotto <roidelapluie@gmail.com>

Signed-off-by: William Felipe Welter <wfelipew@gmail.com>
  • Loading branch information
wfelipew committed Mar 21, 2021
1 parent 6e540be commit 4240322
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
13 changes: 12 additions & 1 deletion model/time.go
Expand Up @@ -15,6 +15,7 @@ package model

import (
"encoding/json"
"errors"
"fmt"
"math"
"regexp"
Expand Down Expand Up @@ -202,13 +203,23 @@ func ParseDuration(durationStr string) (Duration, error) {

// Parse the match at pos `pos` in the regex and use `mult` to turn that
// into ms, then add that value to the total parsed duration.
var overflowErr error
m := func(pos int, mult time.Duration) {
if matches[pos] == "" {
return
}
n, _ := strconv.Atoi(matches[pos])

// Check if the provided duration overflows time.Duration (> ~ 290years).
if n > int((1<<63-1)/mult/time.Millisecond) {
overflowErr = errors.New("duration out of range")
}
d := time.Duration(n) * time.Millisecond
dur += d * mult

if dur < 0 {
overflowErr = errors.New("duration out of range")
}
}

m(2, 1000*60*60*24*365) // y
Expand All @@ -219,7 +230,7 @@ func ParseDuration(durationStr string) (Duration, error) {
m(12, 1000) // s
m(14, 1) // ms

return Duration(dur), nil
return Duration(dur), overflowErr
}

func (d Duration) String() string {
Expand Down
8 changes: 8 additions & 0 deletions model/time_test.go
Expand Up @@ -282,6 +282,10 @@ func TestDuration_UnmarshalJSON(t *testing.T) {
in: `"10y"`,
out: 10 * 365 * 24 * time.Hour,
},
{
in: `"289y"`,
out: 289 * 365 * 24 * time.Hour,
},
}

for _, c := range cases {
Expand Down Expand Up @@ -314,6 +318,10 @@ func TestParseBadDuration(t *testing.T) {
"-1w",
"1.5d",
"d",
"294y",
"200y10400w",
"107675d",
"2584200h",
"",
}

Expand Down

0 comments on commit 4240322

Please sign in to comment.