As deepmap/oapi-codegen didn't work with this newer version, upgrade to oapi-codegen/oapi-codegen v2. Mitigating CVE-2025-30153
197 lines
4.2 KiB
Go
197 lines
4.2 KiB
Go
// Copyright 2022 PerimeterX. All rights reserved.
|
|
// Use of this source code is governed by a MIT style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package marshmallow
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
var unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
|
|
|
|
type reflectionInfo struct {
|
|
path []int
|
|
t reflect.Type
|
|
}
|
|
|
|
func (r reflectionInfo) field(target reflect.Value) reflect.Value {
|
|
current := target
|
|
for _, i := range r.path {
|
|
current = current.Field(i)
|
|
}
|
|
return current
|
|
}
|
|
|
|
func mapStructFields(target interface{}) map[string]reflectionInfo {
|
|
t := reflectStructType(target)
|
|
result := cacheLookup(t)
|
|
if result != nil {
|
|
return result
|
|
}
|
|
result = make(map[string]reflectionInfo, t.NumField())
|
|
mapTypeFields(t, result, nil)
|
|
cacheStore(t, result)
|
|
return result
|
|
}
|
|
|
|
func mapTypeFields(t reflect.Type, result map[string]reflectionInfo, path []int) {
|
|
num := t.NumField()
|
|
for i := 0; i < num; i++ {
|
|
field := t.Field(i)
|
|
fieldPath := append(path, i)
|
|
if field.Anonymous && field.Type.Kind() == reflect.Struct {
|
|
mapTypeFields(field.Type, result, fieldPath)
|
|
continue
|
|
}
|
|
name := field.Tag.Get("json")
|
|
if name == "" || name == "-" {
|
|
continue
|
|
}
|
|
if index := strings.Index(name, ","); index > -1 {
|
|
name = name[:index]
|
|
}
|
|
result[name] = reflectionInfo{
|
|
path: fieldPath,
|
|
t: field.Type,
|
|
}
|
|
}
|
|
}
|
|
|
|
func reflectStructValue(target interface{}) reflect.Value {
|
|
v := reflect.ValueOf(target)
|
|
for v.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
}
|
|
return v
|
|
}
|
|
|
|
func reflectStructType(target interface{}) reflect.Type {
|
|
t := reflect.TypeOf(target)
|
|
for t.Kind() == reflect.Ptr {
|
|
t = t.Elem()
|
|
}
|
|
return t
|
|
}
|
|
|
|
var primitiveConverters = map[reflect.Kind]func(v interface{}) (interface{}, bool){
|
|
reflect.Bool: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(bool)
|
|
return res, ok
|
|
},
|
|
reflect.Int: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return int(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Int8: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return int8(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Int16: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return int16(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Int32: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return int32(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Int64: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return int64(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Uint: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return uint(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Uint8: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return uint8(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Uint16: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return uint16(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Uint32: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return uint32(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Uint64: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return uint64(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Float32: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return float32(res), true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Float64: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(float64)
|
|
if ok {
|
|
return res, true
|
|
}
|
|
return v, false
|
|
},
|
|
reflect.Interface: func(v interface{}) (interface{}, bool) {
|
|
return v, true
|
|
},
|
|
reflect.String: func(v interface{}) (interface{}, bool) {
|
|
res, ok := v.(string)
|
|
return res, ok
|
|
},
|
|
}
|
|
|
|
func assignValue(field reflect.Value, value interface{}) {
|
|
if value == nil {
|
|
return
|
|
}
|
|
reflectValue := reflect.ValueOf(value)
|
|
if reflectValue.Type().AssignableTo(field.Type()) {
|
|
field.Set(reflectValue)
|
|
}
|
|
}
|
|
|
|
func isValidValue(v interface{}) bool {
|
|
value := reflect.ValueOf(v)
|
|
return value.Kind() == reflect.Ptr && value.Elem().Kind() == reflect.Struct && !value.IsNil()
|
|
}
|
|
|
|
func safeReflectValue(t reflect.Type, v interface{}) reflect.Value {
|
|
if v == nil {
|
|
return reflect.Zero(t)
|
|
}
|
|
return reflect.ValueOf(v)
|
|
}
|