Explorar el Código

Fixes TypeError check in Unmarshal

decoder.terrors can be empty but non-nil if the unmarshaler function is called multiple times in UnmarshalYAML.
This fixes the case where d.terrors is empty but has a non-zero capacity, which previously resulted in returning a TypeError with an empty list of error strings.
Brian Bland hace 11 años
padre
commit
3e92d6a11b
Se han modificado 2 ficheros con 32 adiciones y 1 borrados
  1. 31 0
      decode_test.go
  2. 1 1
      yaml.go

+ 31 - 0
decode_test.go

@@ -647,6 +647,37 @@ func (s *S) TestUnmarshalerError(c *C) {
 	c.Assert(err, Equals, failingErr)
 }
 
+type sliceUnmarshaler []int
+
+func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
+	var slice []int
+	err := unmarshal(&slice)
+	if err == nil {
+		*su = slice
+		return nil
+	}
+
+	var intVal int
+	err = unmarshal(&intVal)
+	if err == nil {
+		*su = []int{intVal}
+		return nil
+	}
+
+	return err
+}
+
+func (s *S) TestUnmarshalerRetry(c *C) {
+	var su sliceUnmarshaler
+	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
+	c.Assert(err, IsNil)
+	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
+
+	err = yaml.Unmarshal([]byte("1"), &su)
+	c.Assert(err, IsNil)
+	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
+}
+
 // From http://yaml.org/type/merge.html
 var mergeTests = `
 anchors:

+ 1 - 1
yaml.go

@@ -90,7 +90,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 		}
 		d.unmarshal(node, v)
 	}
-	if d.terrors != nil {
+	if len(d.terrors) > 0 {
 		return &TypeError{d.terrors}
 	}
 	return nil