diff options
Diffstat (limited to 'vendor/github.com/go-playground/form/v4/decoder.go')
-rw-r--r-- | vendor/github.com/go-playground/form/v4/decoder.go | 752 |
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 -} |