Prevent panic when decoding string named types (#743)

This commit is contained in:
Shuhei Kitagawa 2025-05-26 02:14:35 +02:00 committed by GitHub
parent 04f9bb53f7
commit 6a6c998c2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 7 deletions

View file

@ -637,20 +637,29 @@ func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node)
return v.Convert(typ), nil return v.Convert(typ), nil
} }
// cast value to string // cast value to string
var strVal string
switch v.Type().Kind() { switch v.Type().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return reflect.ValueOf(strconv.FormatInt(v.Int(), 10)), nil strVal = strconv.FormatInt(v.Int(), 10)
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
return reflect.ValueOf(fmt.Sprint(v.Float())), nil strVal = fmt.Sprint(v.Float())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return reflect.ValueOf(strconv.FormatUint(v.Uint(), 10)), nil strVal = strconv.FormatUint(v.Uint(), 10)
case reflect.Bool: case reflect.Bool:
return reflect.ValueOf(strconv.FormatBool(v.Bool())), nil strVal = strconv.FormatBool(v.Bool())
} default:
if !v.Type().ConvertibleTo(typ) { if !v.Type().ConvertibleTo(typ) {
return reflect.Zero(typ), errors.ErrTypeMismatch(typ, v.Type(), src.GetToken()) return reflect.Zero(typ), errors.ErrTypeMismatch(typ, v.Type(), src.GetToken())
} }
return v.Convert(typ), nil return v.Convert(typ), nil
}
val := reflect.ValueOf(strVal)
if val.Type() != typ {
// Handle named types, e.g., `type MyString string`
val = val.Convert(typ)
}
return val, nil
} }
func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[string]ast.Node) error { func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[string]ast.Node) error {

View file

@ -25,6 +25,8 @@ type Child struct {
C int `yaml:"-"` C int `yaml:"-"`
} }
type TestString string
func TestDecoder(t *testing.T) { func TestDecoder(t *testing.T) {
tests := []struct { tests := []struct {
source string source string
@ -35,6 +37,10 @@ func TestDecoder(t *testing.T) {
source: "v: hi\n", source: "v: hi\n",
value: map[string]string{"v": "hi"}, value: map[string]string{"v": "hi"},
}, },
{
source: "v: hi\n",
value: map[string]TestString{"v": "hi"},
},
{ {
source: "v: \"true\"\n", source: "v: \"true\"\n",
value: map[string]string{"v": "true"}, value: map[string]string{"v": "true"},
@ -55,6 +61,10 @@ func TestDecoder(t *testing.T) {
source: "v: 10\n", source: "v: 10\n",
value: map[string]string{"v": "10"}, value: map[string]string{"v": "10"},
}, },
{
source: "v: 10\n",
value: map[string]TestString{"v": "10"},
},
{ {
source: "v: -10\n", source: "v: -10\n",
value: map[string]string{"v": "-10"}, value: map[string]string{"v": "-10"},