go-yaml/yaml — pull request #56 by jawher (2014-11-21 13:48:49+00:00)
Title: Fix a bug that causes the parsing to fail even though there aren't any errors

This bug is triggered when using a custom unmarsheller which calls the unmarshal callback multiple times with different types.

For example, suppose we want to parse a list of commands in a yaml file:

```yaml
commands:
- echo $PATH
- who am i
```

And we'd also like to support this short format:

```yaml
commands: "ls -al"
```

We should be able to handle this using a custom marshaller which tries to parse the value as a string first, and if that fails, retry the parse but as a string slice:

```go
type OneOrMany []string

func (c * OneOrMany) UnmarshalYAML(unmarshal func(interface{}) error) error {
single := ""
if err := unmarshal(&single); err == nil {
*c = []string{single}
return nil
}

multiple := []string{}
if err := unmarshal(&multiple); err != nil {
return err
}
*c = multiple
return nil
}
```

But the code above fails with the current version of yaml.v2.
Indeed, when a call to the unmarshal callback fails, the terrors field of decoders is no longer nil (it contains one error).
Afterwards, in decode.go line 230:

```go
d.terrors = d.terrors[:terrlen]
```

the error is removed from the terrors slice, but terrors is now a zero-length slice and not nil.
So even though a later call to unmarshal succeeds, the whole parse would be marked as failed by the follozing test in yaml.go line 93:

```go
if d.terrors != nil {
```

And we end up with an empty error.