Change parseTimeout to not handle non-second durations (#1706)

This commit is contained in:
dfawley
2017-12-05 10:04:04 -08:00
committed by GitHub
parent be077907e2
commit 43083423e4
3 changed files with 113 additions and 23 deletions

View File

@ -20,6 +20,9 @@ package grpc
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"google.golang.org/grpc/grpclog"
@ -70,12 +73,48 @@ type ServiceConfig struct {
Methods map[string]MethodConfig
}
func parseTimeout(t *string) (*time.Duration, error) {
if t == nil {
func parseDuration(s *string) (*time.Duration, error) {
if s == nil {
return nil, nil
}
d, err := time.ParseDuration(*t)
return &d, err
if !strings.HasSuffix(*s, "s") {
return nil, fmt.Errorf("malformed duration %q", *s)
}
ss := strings.SplitN((*s)[:len(*s)-1], ".", 3)
if len(ss) > 2 {
return nil, fmt.Errorf("malformed duration %q", *s)
}
// hasDigits is set if either the whole or fractional part of the number is
// present, since both are optional but one is required.
hasDigits := false
var d time.Duration
if len(ss[0]) > 0 {
i, err := strconv.ParseInt(ss[0], 10, 32)
if err != nil {
return nil, fmt.Errorf("malformed duration %q: %v", *s, err)
}
d = time.Duration(i) * time.Second
hasDigits = true
}
if len(ss) == 2 && len(ss[1]) > 0 {
if len(ss[1]) > 9 {
return nil, fmt.Errorf("malformed duration %q", *s)
}
f, err := strconv.ParseInt(ss[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("malformed duration %q: %v", *s, err)
}
for i := 9; i > len(ss[1]); i-- {
f *= 10
}
d += time.Duration(f)
hasDigits = true
}
if !hasDigits {
return nil, fmt.Errorf("malformed duration %q", *s)
}
return &d, nil
}
type jsonName struct {
@ -128,7 +167,7 @@ func parseServiceConfig(js string) (ServiceConfig, error) {
if m.Name == nil {
continue
}
d, err := parseTimeout(m.Timeout)
d, err := parseDuration(m.Timeout)
if err != nil {
grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err)
return ServiceConfig{}, err
@ -182,18 +221,6 @@ func getMaxSize(mcMax, doptMax *int, defaultVal int) *int {
return doptMax
}
func newBool(b bool) *bool {
return &b
}
func newInt(b int) *int {
return &b
}
func newDuration(b time.Duration) *time.Duration {
return &b
}
func newString(b string) *string {
return &b
}