fix(form):add max iteration to avoid stack overflow

This commit is contained in:
gc 2023-08-21 18:43:53 +08:00
parent bb2d8cf486
commit 8b7e6f4295

View File

@ -26,6 +26,8 @@ var (
ErrConvertToMapString = errors.New("can not convert to map of strings") ErrConvertToMapString = errors.New("can not convert to map of strings")
) )
const maxIterDepth = 255
func mapURI(ptr any, m map[string][]string) error { func mapURI(ptr any, m map[string][]string) error {
return mapFormByTag(ptr, m, "uri") return mapFormByTag(ptr, m, "uri")
} }
@ -74,15 +76,17 @@ func (form formSource) TrySet(value reflect.Value, field reflect.StructField, ta
} }
func mappingByPtr(ptr any, setter setter, tag string) error { func mappingByPtr(ptr any, setter setter, tag string) error {
_, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag) _, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag, 0)
return err return err
} }
func mapping(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) { func mapping(value reflect.Value, field reflect.StructField, setter setter, tag string, depth int) (bool, error) {
if field.Tag.Get(tag) == "-" { // just ignoring this field if field.Tag.Get(tag) == "-" { // just ignoring this field
return false, nil return false, nil
} }
if depth > maxIterDepth {
return false, fmt.Errorf("deep of nesting is too high > %d", maxIterDepth)
}
vKind := value.Kind() vKind := value.Kind()
if vKind == reflect.Ptr { if vKind == reflect.Ptr {
@ -92,7 +96,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
isNew = true isNew = true
vPtr = reflect.New(value.Type().Elem()) vPtr = reflect.New(value.Type().Elem())
} }
isSet, err := mapping(vPtr.Elem(), field, setter, tag) isSet, err := mapping(vPtr.Elem(), field, setter, tag, depth+1)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -121,7 +125,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
if sf.PkgPath != "" && !sf.Anonymous { // unexported if sf.PkgPath != "" && !sf.Anonymous { // unexported
continue continue
} }
ok, err := mapping(value.Field(i), sf, setter, tag) ok, err := mapping(value.Field(i), sf, setter, tag, depth+1)
if err != nil { if err != nil {
return false, err return false, err
} }