summaryrefslogtreecommitdiff
path: root/vendor/github.com/go-playground/form/v4/decoder.go
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/go-playground/form/v4/decoder.go
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/go-playground/form/v4/decoder.go')
-rw-r--r--vendor/github.com/go-playground/form/v4/decoder.go752
1 files changed, 0 insertions, 752 deletions
diff --git a/vendor/github.com/go-playground/form/v4/decoder.go b/vendor/github.com/go-playground/form/v4/decoder.go
deleted file mode 100644
index e21242279..000000000
--- a/vendor/github.com/go-playground/form/v4/decoder.go
+++ /dev/null
@@ -1,752 +0,0 @@
-package form
-
-import (
- "fmt"
- "log"
- "net/url"
- "reflect"
- "strconv"
- "time"
-)
-
-const (
- errArraySize = "Array size of '%d' is larger than the maximum currently set on the decoder of '%d'. To increase this limit please see, SetMaxArraySize(size uint)"
- errMissingStartBracket = "Invalid formatting for key '%s' missing '[' bracket"
- errMissingEndBracket = "Invalid formatting for key '%s' missing ']' bracket"
-)
-
-type decoder struct {
- d *Decoder
- errs DecodeErrors
- dm dataMap
- values url.Values
- maxKeyLen int
- namespace []byte
-}
-
-func (d *decoder) setError(namespace []byte, err error) {
- if d.errs == nil {
- d.errs = make(DecodeErrors)
- }
- d.errs[string(namespace)] = err
-}
-
-func (d *decoder) findAlias(ns string) *recursiveData {
- for i := 0; i < len(d.dm); i++ {
- if d.dm[i].alias == ns {
- return d.dm[i]
- }
- }
- return nil
-}
-
-func (d *decoder) parseMapData() {
- // already parsed
- if len(d.dm) > 0 {
- return
- }
-
- d.maxKeyLen = 0
- d.dm = d.dm[0:0]
-
- var i int
- var idx int
- var l int
- var insideBracket bool
- var rd *recursiveData
- var isNum bool
-
- for k := range d.values {
-
- if len(k) > d.maxKeyLen {
- d.maxKeyLen = len(k)
- }
-
- for i = 0; i < len(k); i++ {
-
- switch k[i] {
- case '[':
- idx = i
- insideBracket = true
- isNum = true
- case ']':
-
- if !insideBracket {
- log.Panicf(errMissingStartBracket, k)
- }
-
- if rd = d.findAlias(k[:idx]); rd == nil {
-
- l = len(d.dm) + 1
-
- if l > cap(d.dm) {
- dm := make(dataMap, l)
- copy(dm, d.dm)
- rd = new(recursiveData)
- dm[len(d.dm)] = rd
- d.dm = dm
- } else {
- l = len(d.dm)
- d.dm = d.dm[:l+1]
- rd = d.dm[l]
- rd.sliceLen = 0
- rd.keys = rd.keys[0:0]
- }
-
- rd.alias = k[:idx]
- }
-
- // is map + key
- ke := key{
- ivalue: -1,
- value: k[idx+1 : i],
- searchValue: k[idx : i+1],
- }
-
- // is key is number, most likely array key, keep track of just in case an array/slice.
- if isNum {
-
- // no need to check for error, it will always pass
- // as we have done the checking to ensure
- // the value is a number ahead of time.
- var err error
- ke.ivalue, err = strconv.Atoi(ke.value)
- if err != nil {
- ke.ivalue = -1
- }
-
- if ke.ivalue > rd.sliceLen {
- rd.sliceLen = ke.ivalue
-
- }
- }
-
- rd.keys = append(rd.keys, ke)
-
- insideBracket = false
- default:
- // checking if not a number, 0-9 is 48-57 in byte, see for yourself fmt.Println('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
- if insideBracket && (k[i] > 57 || k[i] < 48) {
- isNum = false
- }
- }
- }
-
- // if still inside bracket, that means no ending bracket was ever specified
- if insideBracket {
- log.Panicf(errMissingEndBracket, k)
- }
- }
-}
-
-func (d *decoder) traverseStruct(v reflect.Value, typ reflect.Type, namespace []byte) (set bool) {
-
- l := len(namespace)
- first := l == 0
-
- // anonymous structs will still work for caching as the whole definition is stored
- // including tags
- s, ok := d.d.structCache.Get(typ)
- if !ok {
- s = d.d.structCache.parseStruct(d.d.mode, v, typ, d.d.tagName)
- }
-
- for _, f := range s.fields {
- namespace = namespace[:l]
-
- if f.isAnonymous {
- if d.setFieldByType(v.Field(f.idx), namespace, 0) {
- set = true
- }
- }
-
- if first {
- namespace = append(namespace, f.name...)
- } else {
- namespace = append(namespace, d.d.namespacePrefix...)
- namespace = append(namespace, f.name...)
- namespace = append(namespace, d.d.namespaceSuffix...)
- }
-
- if d.setFieldByType(v.Field(f.idx), namespace, 0) {
- set = true
- }
- }
-
- return
-}
-
-func (d *decoder) setFieldByType(current reflect.Value, namespace []byte, idx int) (set bool) {
-
- var err error
- v, kind := ExtractType(current)
-
- arr, ok := d.values[string(namespace)]
-
- if d.d.customTypeFuncs != nil {
-
- if ok {
- if cf, ok := d.d.customTypeFuncs[v.Type()]; ok {
- val, err := cf(arr[idx:])
- if err != nil {
- d.setError(namespace, err)
- return
- }
-
- v.Set(reflect.ValueOf(val))
- set = true
- return
- }
- }
- }
- switch kind {
- case reflect.Interface:
- if !ok || idx == len(arr) {
- return
- }
- v.Set(reflect.ValueOf(arr[idx]))
- set = true
-
- case reflect.Ptr:
- newVal := reflect.New(v.Type().Elem())
- if set = d.setFieldByType(newVal.Elem(), namespace, idx); set {
- v.Set(newVal)
- }
-
- case reflect.String:
- if !ok || idx == len(arr) {
- return
- }
- v.SetString(arr[idx])
- set = true
-
- case reflect.Uint, reflect.Uint64:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var u64 uint64
- if u64, err = strconv.ParseUint(arr[idx], 10, 64); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetUint(u64)
- set = true
-
- case reflect.Uint8:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var u64 uint64
- if u64, err = strconv.ParseUint(arr[idx], 10, 8); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetUint(u64)
- set = true
-
- case reflect.Uint16:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var u64 uint64
- if u64, err = strconv.ParseUint(arr[idx], 10, 16); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetUint(u64)
- set = true
-
- case reflect.Uint32:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var u64 uint64
- if u64, err = strconv.ParseUint(arr[idx], 10, 32); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetUint(u64)
- set = true
-
- case reflect.Int, reflect.Int64:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var i64 int64
- if i64, err = strconv.ParseInt(arr[idx], 10, 64); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetInt(i64)
- set = true
-
- case reflect.Int8:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var i64 int64
- if i64, err = strconv.ParseInt(arr[idx], 10, 8); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetInt(i64)
- set = true
-
- case reflect.Int16:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var i64 int64
- if i64, err = strconv.ParseInt(arr[idx], 10, 16); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetInt(i64)
- set = true
-
- case reflect.Int32:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var i64 int64
- if i64, err = strconv.ParseInt(arr[idx], 10, 32); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetInt(i64)
- set = true
-
- case reflect.Float32:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var f float64
- if f, err = strconv.ParseFloat(arr[idx], 32); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetFloat(f)
- set = true
-
- case reflect.Float64:
- if !ok || idx == len(arr) || len(arr[idx]) == 0 {
- return
- }
- var f float64
- if f, err = strconv.ParseFloat(arr[idx], 64); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetFloat(f)
- set = true
-
- case reflect.Bool:
- if !ok || idx == len(arr) {
- return
- }
- var b bool
- if b, err = parseBool(arr[idx]); err != nil {
- d.setError(namespace, fmt.Errorf("Invalid Boolean Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
- return
- }
- v.SetBool(b)
- set = true
-
- case reflect.Slice:
- d.parseMapData()
- // slice elements could be mixed eg. number and non-numbers Value[0]=[]string{"10"} and Value=[]string{"10","20"}
-
- if ok && len(arr) > 0 {
- var varr reflect.Value
-
- var ol int
- l := len(arr)
-
- if v.IsNil() {
- varr = reflect.MakeSlice(v.Type(), len(arr), len(arr))
- } else {
-
- ol = v.Len()
- l += ol
-
- if v.Cap() <= l {
- varr = reflect.MakeSlice(v.Type(), l, l)
- } else {
- // preserve predefined capacity, possibly for reuse after decoding
- varr = reflect.MakeSlice(v.Type(), l, v.Cap())
- }
- reflect.Copy(varr, v)
- }
-
- for i := ol; i < l; i++ {
- newVal := reflect.New(v.Type().Elem()).Elem()
-
- if d.setFieldByType(newVal, namespace, i-ol) {
- set = true
- varr.Index(i).Set(newVal)
- }
- }
-
- v.Set(varr)
- }
-
- // maybe it's an numbered array i.e. Phone[0].Number
- if rd := d.findAlias(string(namespace)); rd != nil {
-
- var varr reflect.Value
- var kv key
-
- sl := rd.sliceLen + 1
-
- // checking below for maxArraySize, but if array exists and already
- // has sufficient capacity allocated then we do not check as the code
- // obviously allows a capacity greater than the maxArraySize.
-
- if v.IsNil() {
-
- if sl > d.d.maxArraySize {
- d.setError(namespace, fmt.Errorf(errArraySize, sl, d.d.maxArraySize))
- return
- }
-
- varr = reflect.MakeSlice(v.Type(), sl, sl)
-
- } else if v.Len() < sl {
-
- if v.Cap() <= sl {
-
- if sl > d.d.maxArraySize {
- d.setError(namespace, fmt.Errorf(errArraySize, sl, d.d.maxArraySize))
- return
- }
-
- varr = reflect.MakeSlice(v.Type(), sl, sl)
- } else {
- varr = reflect.MakeSlice(v.Type(), sl, v.Cap())
- }
-
- reflect.Copy(varr, v)
-
- } else {
- varr = v
- }
-
- for i := 0; i < len(rd.keys); i++ {
-
- kv = rd.keys[i]
- newVal := reflect.New(varr.Type().Elem()).Elem()
-
- if kv.ivalue == -1 {
- d.setError(namespace, fmt.Errorf("invalid slice index '%s'", kv.value))
- continue
- }
-
- if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) {
- set = true
- varr.Index(kv.ivalue).Set(newVal)
- }
- }
-
- if !set {
- return
- }
-
- v.Set(varr)
- }
-
- case reflect.Array:
- d.parseMapData()
-
- // array elements could be mixed eg. number and non-numbers Value[0]=[]string{"10"} and Value=[]string{"10","20"}
-
- if ok && len(arr) > 0 {
- var varr reflect.Value
- l := len(arr)
- overCapacity := v.Len() < l
- if overCapacity {
- // more values than array capacity, ignore values over capacity as it's possible some would just want
- // to grab the first x number of elements; in the future strict mode logic should return an error
- fmt.Println("warning number of post form array values is larger than array capacity, ignoring overflow values")
- }
- varr = reflect.Indirect(reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem())))
- reflect.Copy(varr, v)
-
- if v.Len() < len(arr) {
- l = v.Len()
- }
- for i := 0; i < l; i++ {
- newVal := reflect.New(v.Type().Elem()).Elem()
-
- if d.setFieldByType(newVal, namespace, i) {
- set = true
- varr.Index(i).Set(newVal)
- }
- }
- v.Set(varr)
- }
-
- // maybe it's an numbered array i.e. Phone[0].Number
- if rd := d.findAlias(string(namespace)); rd != nil {
- var varr reflect.Value
- var kv key
-
- overCapacity := rd.sliceLen >= v.Len()
- if overCapacity {
- // more values than array capacity, ignore values over capacity as it's possible some would just want
- // to grab the first x number of elements; in the future strict mode logic should return an error
- fmt.Println("warning number of post form array values is larger than array capacity, ignoring overflow values")
- }
- varr = reflect.Indirect(reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem())))
- reflect.Copy(varr, v)
-
- for i := 0; i < len(rd.keys); i++ {
- kv = rd.keys[i]
- if kv.ivalue >= v.Len() {
- continue
- }
- newVal := reflect.New(varr.Type().Elem()).Elem()
-
- if kv.ivalue == -1 {
- d.setError(namespace, fmt.Errorf("invalid array index '%s'", kv.value))
- continue
- }
-
- if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) {
- set = true
- varr.Index(kv.ivalue).Set(newVal)
- }
- }
-
- if !set {
- return
- }
- v.Set(varr)
- }
-
- case reflect.Map:
- var rd *recursiveData
-
- d.parseMapData()
-
- // no natural map support so skip directly to dm lookup
- if rd = d.findAlias(string(namespace)); rd == nil {
- return
- }
-
- var existing bool
- var kv key
- var mp reflect.Value
- var mk reflect.Value
-
- typ := v.Type()
-
- if v.IsNil() {
- mp = reflect.MakeMap(typ)
- } else {
- existing = true
- mp = v
- }
-
- for i := 0; i < len(rd.keys); i++ {
- newVal := reflect.New(typ.Elem()).Elem()
- mk = reflect.New(typ.Key()).Elem()
- kv = rd.keys[i]
-
- if err := d.getMapKey(kv.value, mk, namespace); err != nil {
- d.setError(namespace, err)
- continue
- }
-
- if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) {
- set = true
- mp.SetMapIndex(mk, newVal)
- }
- }
-
- if !set || existing {
- return
- }
-
- v.Set(mp)
-
- case reflect.Struct:
- typ := v.Type()
-
- // if we get here then no custom time function declared so use RFC3339 by default
- if typ == timeType {
-
- if !ok || len(arr[idx]) == 0 {
- return
- }
-
- t, err := time.Parse(time.RFC3339, arr[idx])
- if err != nil {
- d.setError(namespace, err)
- }
-
- v.Set(reflect.ValueOf(t))
- set = true
- return
- }
-
- d.parseMapData()
-
- // we must be recursing infinitly...but that's ok we caught it on the very first overun.
- if len(namespace) > d.maxKeyLen {
- return
- }
-
- set = d.traverseStruct(v, typ, namespace)
- }
- return
-}
-
-func (d *decoder) getMapKey(key string, current reflect.Value, namespace []byte) (err error) {
-
- v, kind := ExtractType(current)
-
- if d.d.customTypeFuncs != nil {
- if cf, ok := d.d.customTypeFuncs[v.Type()]; ok {
-
- val, er := cf([]string{key})
- if er != nil {
- err = er
- return
- }
-
- v.Set(reflect.ValueOf(val))
- return
- }
- }
-
- switch kind {
- case reflect.Interface:
- // If interface would have been set on the struct before decoding,
- // say to a struct value we would not get here but kind would be struct.
- v.Set(reflect.ValueOf(key))
- return
- case reflect.Ptr:
- newVal := reflect.New(v.Type().Elem())
- if err = d.getMapKey(key, newVal.Elem(), namespace); err == nil {
- v.Set(newVal)
- }
-
- case reflect.String:
- v.SetString(key)
-
- case reflect.Uint, reflect.Uint64:
-
- u64, e := strconv.ParseUint(key, 10, 64)
- if e != nil {
- err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetUint(u64)
-
- case reflect.Uint8:
-
- u64, e := strconv.ParseUint(key, 10, 8)
- if e != nil {
- err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetUint(u64)
-
- case reflect.Uint16:
-
- u64, e := strconv.ParseUint(key, 10, 16)
- if e != nil {
- err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetUint(u64)
-
- case reflect.Uint32:
-
- u64, e := strconv.ParseUint(key, 10, 32)
- if e != nil {
- err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetUint(u64)
-
- case reflect.Int, reflect.Int64:
-
- i64, e := strconv.ParseInt(key, 10, 64)
- if e != nil {
- err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetInt(i64)
-
- case reflect.Int8:
-
- i64, e := strconv.ParseInt(key, 10, 8)
- if e != nil {
- err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetInt(i64)
-
- case reflect.Int16:
-
- i64, e := strconv.ParseInt(key, 10, 16)
- if e != nil {
- err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetInt(i64)
-
- case reflect.Int32:
-
- i64, e := strconv.ParseInt(key, 10, 32)
- if e != nil {
- err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetInt(i64)
-
- case reflect.Float32:
-
- f, e := strconv.ParseFloat(key, 32)
- if e != nil {
- err = fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetFloat(f)
-
- case reflect.Float64:
-
- f, e := strconv.ParseFloat(key, 64)
- if e != nil {
- err = fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetFloat(f)
-
- case reflect.Bool:
-
- b, e := parseBool(key)
- if e != nil {
- err = fmt.Errorf("Invalid Boolean Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- return
- }
-
- v.SetBool(b)
-
- default:
- err = fmt.Errorf("Unsupported Map Key '%s', Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
- }
-
- return
-}