Skip to content

Commit 96e31db

Browse files
authored
transport: Reject non-positive timeout values in server (#8290)
1 parent d3d2702 commit 96e31db

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

internal/transport/http_util.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,14 @@ func decodeTimeout(s string) (time.Duration, error) {
196196
if !ok {
197197
return 0, fmt.Errorf("transport: timeout unit is not recognized: %q", s)
198198
}
199-
t, err := strconv.ParseInt(s[:size-1], 10, 64)
199+
t, err := strconv.ParseUint(s[:size-1], 10, 64)
200200
if err != nil {
201201
return 0, err
202202
}
203-
const maxHours = math.MaxInt64 / int64(time.Hour)
203+
if t == 0 {
204+
return 0, fmt.Errorf("transport: timeout must be positive: %q", s)
205+
}
206+
const maxHours = math.MaxInt64 / uint64(time.Hour)
204207
if d == time.Hour && t > maxHours {
205208
// This timeout would overflow math.MaxInt64; clamp it.
206209
return time.Duration(math.MaxInt64), nil

internal/transport/http_util_test.go

+30-9
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,49 @@ import (
2222
"errors"
2323
"fmt"
2424
"io"
25+
"math"
2526
"net"
2627
"reflect"
2728
"testing"
2829
"time"
2930
)
3031

31-
func (s) TestTimeoutDecode(t *testing.T) {
32+
func (s) TestDecodeTimeout(t *testing.T) {
3233
for _, test := range []struct {
3334
// input
3435
s string
3536
// output
36-
d time.Duration
37-
err error
37+
d time.Duration
38+
wantErr bool
3839
}{
39-
{"1234S", time.Second * 1234, nil},
40-
{"1234x", 0, fmt.Errorf("transport: timeout unit is not recognized: %q", "1234x")},
41-
{"1", 0, fmt.Errorf("transport: timeout string is too short: %q", "1")},
42-
{"", 0, fmt.Errorf("transport: timeout string is too short: %q", "")},
40+
41+
{"00000001n", time.Nanosecond, false},
42+
{"10u", time.Microsecond * 10, false},
43+
{"00000010m", time.Millisecond * 10, false},
44+
{"1234S", time.Second * 1234, false},
45+
{"00000001M", time.Minute, false},
46+
{"09999999S", time.Second * 9999999, false},
47+
{"99999999S", time.Second * 99999999, false},
48+
{"99999999M", time.Minute * 99999999, false},
49+
{"2562047H", time.Hour * 2562047, false},
50+
{"2562048H", time.Duration(math.MaxInt64), false},
51+
{"99999999H", time.Duration(math.MaxInt64), false},
52+
{"-1S", 0, true},
53+
{"1234x", 0, true},
54+
{"1234s", 0, true},
55+
{"1234", 0, true},
56+
{"1", 0, true},
57+
{"", 0, true},
58+
{"9a1S", 0, true},
59+
{"0S", 0, true}, // PROTOCOL-HTTP2.md requires positive integers
60+
{"00000000S", 0, true},
61+
{"000000000S", 0, true},
4362
} {
4463
d, err := decodeTimeout(test.s)
45-
if d != test.d || fmt.Sprint(err) != fmt.Sprint(test.err) {
46-
t.Fatalf("timeoutDecode(%q) = %d, %v, want %d, %v", test.s, int64(d), err, int64(test.d), test.err)
64+
gotErr := err != nil
65+
if d != test.d || gotErr != test.wantErr {
66+
t.Errorf("timeoutDecode(%q) = %d, %v, want %d, wantErr=%v",
67+
test.s, int64(d), err, int64(test.d), test.wantErr)
4768
}
4869
}
4970
}

0 commit comments

Comments
 (0)