Procházet zdrojové kódy

Do not accept plain ints into time.Duration.

It used to work in v2, but that's very error prone as it's easy to say,
for example, 10 meaning 10 seconds, but it's really 10 nanoseconds.

Closes #200.
Gustavo Niemeyer před 7 roky
rodič
revize
9e322716c2
2 změnil soubory, kde provedl 14 přidání a 4 odebrání
  1. 7 4
      decode.go
  2. 7 0
      decode_test.go

+ 7 - 4
decode.go

@@ -555,24 +555,27 @@ func (d *decoder) scalar(n *Node, out reflect.Value) bool {
 		}
 		return true
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		// This used to work in v2, but it's very unfriendly.
+		isDuration := out.Type() == durationType
+
 		switch resolved := resolved.(type) {
 		case int:
-			if !out.OverflowInt(int64(resolved)) {
+			if !isDuration && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				return true
 			}
 		case int64:
-			if !out.OverflowInt(resolved) {
+			if !isDuration && !out.OverflowInt(resolved) {
 				out.SetInt(resolved)
 				return true
 			}
 		case uint64:
-			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+			if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				return true
 			}
 		case float64:
-			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+			if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				return true
 			}

+ 7 - 0
decode_test.go

@@ -809,6 +809,13 @@ func (s *S) TestUnmarshalNaN(c *C) {
 	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
 }
 
+func (s *S) TestUnmarshalDurationInt(c *C) {
+	// Don't accept plain ints as durations as it's unclear (issue #200).
+	var d time.Duration
+	err := yaml.Unmarshal([]byte("123"), &d)
+	c.Assert(err, ErrorMatches, "(?s).* line 1: cannot unmarshal !!int `123` into time.Duration")
+}
+
 var unmarshalErrorTests = []struct {
 	data, error string
 }{