diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 80b1d15a..c4543f9a 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -15,6 +15,8 @@ import ( "github.com/gin-gonic/gin/internal/json" ) +var LimitMappingCallNumber = 10000 + var errUnknownType = errors.New("Unknown type") func mapUri(ptr interface{}, m map[string][]string) error { @@ -46,11 +48,11 @@ func (form formSource) TrySet(value reflect.Value, field reflect.StructField, ta } func mappingByPtr(ptr interface{}, setter setter, tag string) error { - _, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag) + _, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag, 0) 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, callNumber int) (bool, error) { var vKind = value.Kind() if vKind == reflect.Ptr { @@ -60,7 +62,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag isNew = true vPtr = reflect.New(value.Type().Elem()) } - isSetted, err := mapping(vPtr.Elem(), field, setter, tag) + isSetted, err := mapping(vPtr.Elem(), field, setter, tag, callNumber+1) if err != nil { return false, err } @@ -70,6 +72,10 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag return isSetted, nil } + if callNumber > LimitMappingCallNumber { + return false, errors.New("Maybe entering a circular reference") + } + if vKind != reflect.Struct || !field.Anonymous { ok, err := tryToSetValue(value, field, setter, tag) if err != nil { @@ -89,7 +95,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag if sf.PkgPath != "" && !sf.Anonymous { // unexported continue } - ok, err := mapping(value.Field(i), tValue.Field(i), setter, tag) + ok, err := mapping(value.Field(i), tValue.Field(i), setter, tag, callNumber+1) if err != nil { return false, err }