瀏覽代碼

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 7 年之前
父節點
當前提交
9e322716c2
共有 2 個文件被更改,包括 14 次插入4 次删除
  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
 		return true
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 	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) {
 		switch resolved := resolved.(type) {
 		case int:
 		case int:
-			if !out.OverflowInt(int64(resolved)) {
+			if !isDuration && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				out.SetInt(int64(resolved))
 				return true
 				return true
 			}
 			}
 		case int64:
 		case int64:
-			if !out.OverflowInt(resolved) {
+			if !isDuration && !out.OverflowInt(resolved) {
 				out.SetInt(resolved)
 				out.SetInt(resolved)
 				return true
 				return true
 			}
 			}
 		case uint64:
 		case uint64:
-			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+			if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				out.SetInt(int64(resolved))
 				return true
 				return true
 			}
 			}
 		case float64:
 		case float64:
-			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+			if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				out.SetInt(int64(resolved))
 				return true
 				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)
 	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 {
 var unmarshalErrorTests = []struct {
 	data, error string
 	data, error string
 }{
 }{