Skip to content

Commit 6a6c998

Browse files
authored
Prevent panic when decoding string named types (#743)
1 parent 04f9bb5 commit 6a6c998

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

decode.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -637,20 +637,29 @@ func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node)
637637
return v.Convert(typ), nil
638638
}
639639
// cast value to string
640+
var strVal string
640641
switch v.Type().Kind() {
641642
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
642-
return reflect.ValueOf(strconv.FormatInt(v.Int(), 10)), nil
643+
strVal = strconv.FormatInt(v.Int(), 10)
643644
case reflect.Float32, reflect.Float64:
644-
return reflect.ValueOf(fmt.Sprint(v.Float())), nil
645+
strVal = fmt.Sprint(v.Float())
645646
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
646-
return reflect.ValueOf(strconv.FormatUint(v.Uint(), 10)), nil
647+
strVal = strconv.FormatUint(v.Uint(), 10)
647648
case reflect.Bool:
648-
return reflect.ValueOf(strconv.FormatBool(v.Bool())), nil
649+
strVal = strconv.FormatBool(v.Bool())
650+
default:
651+
if !v.Type().ConvertibleTo(typ) {
652+
return reflect.Zero(typ), errors.ErrTypeMismatch(typ, v.Type(), src.GetToken())
653+
}
654+
return v.Convert(typ), nil
649655
}
650-
if !v.Type().ConvertibleTo(typ) {
651-
return reflect.Zero(typ), errors.ErrTypeMismatch(typ, v.Type(), src.GetToken())
656+
657+
val := reflect.ValueOf(strVal)
658+
if val.Type() != typ {
659+
// Handle named types, e.g., `type MyString string`
660+
val = val.Convert(typ)
652661
}
653-
return v.Convert(typ), nil
662+
return val, nil
654663
}
655664

656665
func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[string]ast.Node) error {

decode_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type Child struct {
2525
C int `yaml:"-"`
2626
}
2727

28+
type TestString string
29+
2830
func TestDecoder(t *testing.T) {
2931
tests := []struct {
3032
source string
@@ -35,6 +37,10 @@ func TestDecoder(t *testing.T) {
3537
source: "v: hi\n",
3638
value: map[string]string{"v": "hi"},
3739
},
40+
{
41+
source: "v: hi\n",
42+
value: map[string]TestString{"v": "hi"},
43+
},
3844
{
3945
source: "v: \"true\"\n",
4046
value: map[string]string{"v": "true"},
@@ -55,6 +61,10 @@ func TestDecoder(t *testing.T) {
5561
source: "v: 10\n",
5662
value: map[string]string{"v": "10"},
5763
},
64+
{
65+
source: "v: 10\n",
66+
value: map[string]TestString{"v": "10"},
67+
},
5868
{
5969
source: "v: -10\n",
6070
value: map[string]string{"v": "-10"},

0 commit comments

Comments
 (0)