mirror of
https://github.com/containers/podman.git
synced 2025-05-21 09:05:56 +08:00
Update gorilla/schema to v1.4.1 to fix CVE-2024-37298
Ref: RHEL-45919 Signed-off-by: Matt Heon <mheon@redhat.com>
This commit is contained in:
2
go.mod
2
go.mod
@ -36,7 +36,7 @@ require (
|
|||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/handlers v1.5.1
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/gorilla/schema v1.2.0
|
github.com/gorilla/schema v1.4.1
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/json-iterator/go v1.1.12
|
github.com/json-iterator/go v1.1.12
|
||||||
github.com/mattn/go-isatty v0.0.14
|
github.com/mattn/go-isatty v0.0.14
|
||||||
|
4
go.sum
4
go.sum
@ -642,8 +642,8 @@ github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
|||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
|
||||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
20
vendor/github.com/gorilla/schema/.editorconfig
generated
vendored
Normal file
20
vendor/github.com/gorilla/schema/.editorconfig
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
; https://editorconfig.org/
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
eclint_indent_style = unset
|
1
vendor/github.com/gorilla/schema/.gitignore
generated
vendored
Normal file
1
vendor/github.com/gorilla/schema/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
coverage.coverprofile
|
2
vendor/github.com/gorilla/schema/LICENSE
generated
vendored
2
vendor/github.com/gorilla/schema/LICENSE
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
|
Copyright (c) 2023 The Gorilla Authors. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
|
34
vendor/github.com/gorilla/schema/Makefile
generated
vendored
Normal file
34
vendor/github.com/gorilla/schema/Makefile
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
|
||||||
|
GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||||
|
|
||||||
|
GO_SEC=$(shell which gosec 2> /dev/null || echo '')
|
||||||
|
GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
|
||||||
|
|
||||||
|
GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
|
||||||
|
GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
|
||||||
|
|
||||||
|
.PHONY: golangci-lint
|
||||||
|
golangci-lint:
|
||||||
|
$(if $(GO_LINT), ,go install $(GO_LINT_URI))
|
||||||
|
@echo "##### Running golangci-lint"
|
||||||
|
golangci-lint run -v
|
||||||
|
|
||||||
|
.PHONY: gosec
|
||||||
|
gosec:
|
||||||
|
$(if $(GO_SEC), ,go install $(GO_SEC_URI))
|
||||||
|
@echo "##### Running gosec"
|
||||||
|
gosec ./...
|
||||||
|
|
||||||
|
.PHONY: govulncheck
|
||||||
|
govulncheck:
|
||||||
|
$(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
|
||||||
|
@echo "##### Running govulncheck"
|
||||||
|
govulncheck ./...
|
||||||
|
|
||||||
|
.PHONY: verify
|
||||||
|
verify: golangci-lint gosec govulncheck
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
@echo "##### Running tests"
|
||||||
|
go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
|
39
vendor/github.com/gorilla/schema/README.md
generated
vendored
39
vendor/github.com/gorilla/schema/README.md
generated
vendored
@ -1,8 +1,12 @@
|
|||||||
schema
|
# gorilla/schema
|
||||||
======
|
|
||||||
[](https://godoc.org/github.com/gorilla/schema) [](https://travis-ci.org/gorilla/schema)
|
|
||||||
[](https://sourcegraph.com/github.com/gorilla/schema?badge)
|
|
||||||
|
|
||||||
|

|
||||||
|
[](https://codecov.io/github/gorilla/schema)
|
||||||
|
[](https://godoc.org/github.com/gorilla/schema)
|
||||||
|
[](https://sourcegraph.com/github.com/gorilla/schema?badge)
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Package gorilla/schema converts structs to and from form values.
|
Package gorilla/schema converts structs to and from form values.
|
||||||
|
|
||||||
@ -83,7 +87,32 @@ The supported field types in the struct are:
|
|||||||
|
|
||||||
Unsupported types are simply ignored, however custom types can be registered to be converted.
|
Unsupported types are simply ignored, however custom types can be registered to be converted.
|
||||||
|
|
||||||
More examples are available on the Gorilla website: https://www.gorillatoolkit.org/pkg/schema
|
## Setting Defaults
|
||||||
|
|
||||||
|
It is possible to set default values when encoding/decoding by using the `default` tag option. The value of `default` is applied when a field has a zero value, a pointer has a nil value, or a slice is empty.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Person struct {
|
||||||
|
Phone string `schema:"phone,default:+123456"` // custom name
|
||||||
|
Age int `schema:"age,default:21"`
|
||||||
|
Admin bool `schema:"admin,default:false"`
|
||||||
|
Balance float64 `schema:"balance,default:10.0"`
|
||||||
|
Friends []string `schema:friends,default:john|bob`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `default` tag option is supported for the following types:
|
||||||
|
|
||||||
|
* bool
|
||||||
|
* float variants (float32, float64)
|
||||||
|
* int variants (int, int8, int16, int32, int64)
|
||||||
|
* uint variants (uint, uint8, uint16, uint32, uint64)
|
||||||
|
* string
|
||||||
|
* a slice of the above types. As shown in the example above, `|` should be used to separate between slice items.
|
||||||
|
* a pointer to one of the above types (pointer to slice and slice of pointers are not supported).
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Because primitive types like int, float, bool, unint and their variants have their default (or zero) values set by Golang, it is not possible to distinguish them from a provided value when decoding/encoding form values. In this case, the value provided by the `default` option tag will be always applied. For example, let's assume that the value submitted in the form for `balance` is `0.0` then the default of `10.0` will be applied, even if `0.0` is part of the form data for the `balance` field. In such cases, it is highly recommended to use pointers to allow schema to distinguish between when a form field has no provided value and when a form has a value equal to the corresponding default set by Golang for a particular type. If the type of the `Balance` field above is changed to `*float64`, then the zero value would be `nil`. In this case, if the form data value for `balance` is `0.0`, then the default will not be applied.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
24
vendor/github.com/gorilla/schema/cache.go
generated
vendored
24
vendor/github.com/gorilla/schema/cache.go
generated
vendored
@ -12,7 +12,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var invalidPath = errors.New("schema: invalid path")
|
var errInvalidPath = errors.New("schema: invalid path")
|
||||||
|
|
||||||
// newCache returns a new cache.
|
// newCache returns a new cache.
|
||||||
func newCache() *cache {
|
func newCache() *cache {
|
||||||
@ -53,13 +53,13 @@ func (c *cache) parsePath(p string, t reflect.Type) ([]pathPart, error) {
|
|||||||
keys := strings.Split(p, ".")
|
keys := strings.Split(p, ".")
|
||||||
for i := 0; i < len(keys); i++ {
|
for i := 0; i < len(keys); i++ {
|
||||||
if t.Kind() != reflect.Struct {
|
if t.Kind() != reflect.Struct {
|
||||||
return nil, invalidPath
|
return nil, errInvalidPath
|
||||||
}
|
}
|
||||||
if struc = c.get(t); struc == nil {
|
if struc = c.get(t); struc == nil {
|
||||||
return nil, invalidPath
|
return nil, errInvalidPath
|
||||||
}
|
}
|
||||||
if field = struc.get(keys[i]); field == nil {
|
if field = struc.get(keys[i]); field == nil {
|
||||||
return nil, invalidPath
|
return nil, errInvalidPath
|
||||||
}
|
}
|
||||||
// Valid field. Append index.
|
// Valid field. Append index.
|
||||||
path = append(path, field.name)
|
path = append(path, field.name)
|
||||||
@ -72,10 +72,10 @@ func (c *cache) parsePath(p string, t reflect.Type) ([]pathPart, error) {
|
|||||||
// So checking i+2 is not necessary anymore.
|
// So checking i+2 is not necessary anymore.
|
||||||
i++
|
i++
|
||||||
if i+1 > len(keys) {
|
if i+1 > len(keys) {
|
||||||
return nil, invalidPath
|
return nil, errInvalidPath
|
||||||
}
|
}
|
||||||
if index64, err = strconv.ParseInt(keys[i], 10, 0); err != nil {
|
if index64, err = strconv.ParseInt(keys[i], 10, 0); err != nil {
|
||||||
return nil, invalidPath
|
return nil, errInvalidPath
|
||||||
}
|
}
|
||||||
parts = append(parts, pathPart{
|
parts = append(parts, pathPart{
|
||||||
path: path,
|
path: path,
|
||||||
@ -197,6 +197,7 @@ func (c *cache) createField(field reflect.StructField, parentAlias string) *fiel
|
|||||||
isSliceOfStructs: isSlice && isStruct,
|
isSliceOfStructs: isSlice && isStruct,
|
||||||
isAnonymous: field.Anonymous,
|
isAnonymous: field.Anonymous,
|
||||||
isRequired: options.Contains("required"),
|
isRequired: options.Contains("required"),
|
||||||
|
defaultValue: options.getDefaultOptionValue(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,6 +249,7 @@ type fieldInfo struct {
|
|||||||
// isAnonymous indicates whether the field is embedded in the struct.
|
// isAnonymous indicates whether the field is embedded in the struct.
|
||||||
isAnonymous bool
|
isAnonymous bool
|
||||||
isRequired bool
|
isRequired bool
|
||||||
|
defaultValue string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fieldInfo) paths(prefix string) []string {
|
func (f *fieldInfo) paths(prefix string) []string {
|
||||||
@ -303,3 +305,13 @@ func (o tagOptions) Contains(option string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o tagOptions) getDefaultOptionValue() string {
|
||||||
|
for _, s := range o {
|
||||||
|
if strings.HasPrefix(s, "default:") {
|
||||||
|
return strings.Split(s, ":")[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
77
vendor/github.com/gorilla/schema/converter.go
generated
vendored
77
vendor/github.com/gorilla/schema/converter.go
generated
vendored
@ -143,3 +143,80 @@ func convertUint64(value string) reflect.Value {
|
|||||||
}
|
}
|
||||||
return invalidValue
|
return invalidValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertPointer(k reflect.Kind, value string) reflect.Value {
|
||||||
|
switch k {
|
||||||
|
case boolType:
|
||||||
|
if v := convertBool(value); v.IsValid() {
|
||||||
|
converted := v.Bool()
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case float32Type:
|
||||||
|
if v := convertFloat32(value); v.IsValid() {
|
||||||
|
converted := float32(v.Float())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case float64Type:
|
||||||
|
if v := convertFloat64(value); v.IsValid() {
|
||||||
|
converted := float64(v.Float())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case intType:
|
||||||
|
if v := convertInt(value); v.IsValid() {
|
||||||
|
converted := int(v.Int())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case int8Type:
|
||||||
|
if v := convertInt8(value); v.IsValid() {
|
||||||
|
converted := int8(v.Int())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case int16Type:
|
||||||
|
if v := convertInt16(value); v.IsValid() {
|
||||||
|
converted := int16(v.Int())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case int32Type:
|
||||||
|
if v := convertInt32(value); v.IsValid() {
|
||||||
|
converted := int32(v.Int())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case int64Type:
|
||||||
|
if v := convertInt64(value); v.IsValid() {
|
||||||
|
converted := int64(v.Int())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case stringType:
|
||||||
|
if v := convertString(value); v.IsValid() {
|
||||||
|
converted := v.String()
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case uintType:
|
||||||
|
if v := convertUint(value); v.IsValid() {
|
||||||
|
converted := uint(v.Uint())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case uint8Type:
|
||||||
|
if v := convertUint8(value); v.IsValid() {
|
||||||
|
converted := uint8(v.Uint())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case uint16Type:
|
||||||
|
if v := convertUint16(value); v.IsValid() {
|
||||||
|
converted := uint16(v.Uint())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case uint32Type:
|
||||||
|
if v := convertUint32(value); v.IsValid() {
|
||||||
|
converted := uint32(v.Uint())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
case uint64Type:
|
||||||
|
if v := convertUint64(value); v.IsValid() {
|
||||||
|
converted := uint64(v.Uint())
|
||||||
|
return reflect.ValueOf(&converted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return invalidValue
|
||||||
|
}
|
||||||
|
103
vendor/github.com/gorilla/schema/decoder.go
generated
vendored
103
vendor/github.com/gorilla/schema/decoder.go
generated
vendored
@ -12,9 +12,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultMaxSize = 16000
|
||||||
|
)
|
||||||
|
|
||||||
// NewDecoder returns a new Decoder.
|
// NewDecoder returns a new Decoder.
|
||||||
func NewDecoder() *Decoder {
|
func NewDecoder() *Decoder {
|
||||||
return &Decoder{cache: newCache()}
|
return &Decoder{cache: newCache(), maxSize: defaultMaxSize}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decoder decodes values from a map[string][]string to a struct.
|
// Decoder decodes values from a map[string][]string to a struct.
|
||||||
@ -22,6 +26,7 @@ type Decoder struct {
|
|||||||
cache *cache
|
cache *cache
|
||||||
zeroEmpty bool
|
zeroEmpty bool
|
||||||
ignoreUnknownKeys bool
|
ignoreUnknownKeys bool
|
||||||
|
maxSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAliasTag changes the tag used to locate custom field aliases.
|
// SetAliasTag changes the tag used to locate custom field aliases.
|
||||||
@ -54,6 +59,13 @@ func (d *Decoder) IgnoreUnknownKeys(i bool) {
|
|||||||
d.ignoreUnknownKeys = i
|
d.ignoreUnknownKeys = i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaxSize limits the size of slices for URL nested arrays or object arrays.
|
||||||
|
// Choose MaxSize carefully; large values may create many zero-value slice elements.
|
||||||
|
// Example: "items.100000=apple" would create a slice with 100,000 empty strings.
|
||||||
|
func (d *Decoder) MaxSize(size int) {
|
||||||
|
d.maxSize = size
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterConverter registers a converter function for a custom type.
|
// RegisterConverter registers a converter function for a custom type.
|
||||||
func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter) {
|
func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter) {
|
||||||
d.cache.registerConverter(value, converterFunc)
|
d.cache.registerConverter(value, converterFunc)
|
||||||
@ -84,6 +96,7 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string) error {
|
|||||||
errors[path] = UnknownKeyError{Key: path}
|
errors[path] = UnknownKeyError{Key: path}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errors.merge(d.setDefaults(t, v))
|
||||||
errors.merge(d.checkRequired(t, src))
|
errors.merge(d.checkRequired(t, src))
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return errors
|
return errors
|
||||||
@ -91,6 +104,88 @@ func (d *Decoder) Decode(dst interface{}, src map[string][]string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setDefaults sets the default values when the `default` tag is specified,
|
||||||
|
// default is supported on basic/primitive types and their pointers,
|
||||||
|
// nested structs can also have default tags
|
||||||
|
func (d *Decoder) setDefaults(t reflect.Type, v reflect.Value) MultiError {
|
||||||
|
struc := d.cache.get(t)
|
||||||
|
if struc == nil {
|
||||||
|
// unexpect, cache.get never return nil
|
||||||
|
return MultiError{"default-" + t.Name(): errors.New("cache fail")}
|
||||||
|
}
|
||||||
|
|
||||||
|
errs := MultiError{}
|
||||||
|
|
||||||
|
if v.Type().Kind() == reflect.Struct {
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
field := v.Field(i)
|
||||||
|
if field.Type().Kind() == reflect.Ptr && field.IsNil() && v.Type().Field(i).Anonymous {
|
||||||
|
field.Set(reflect.New(field.Type().Elem()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range struc.fields {
|
||||||
|
vCurrent := v.FieldByName(f.name)
|
||||||
|
|
||||||
|
if vCurrent.Type().Kind() == reflect.Struct && f.defaultValue == "" {
|
||||||
|
errs.merge(d.setDefaults(vCurrent.Type(), vCurrent))
|
||||||
|
} else if isPointerToStruct(vCurrent) && f.defaultValue == "" {
|
||||||
|
errs.merge(d.setDefaults(vCurrent.Elem().Type(), vCurrent.Elem()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.defaultValue != "" && f.isRequired {
|
||||||
|
errs.merge(MultiError{"default-" + f.name: errors.New("required fields cannot have a default value")})
|
||||||
|
} else if f.defaultValue != "" && vCurrent.IsZero() && !f.isRequired {
|
||||||
|
if f.typ.Kind() == reflect.Struct {
|
||||||
|
errs.merge(MultiError{"default-" + f.name: errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")})
|
||||||
|
} else if f.typ.Kind() == reflect.Slice {
|
||||||
|
vals := strings.Split(f.defaultValue, "|")
|
||||||
|
|
||||||
|
// check if slice has one of the supported types for defaults
|
||||||
|
if _, ok := builtinConverters[f.typ.Elem().Kind()]; !ok {
|
||||||
|
errs.merge(MultiError{"default-" + f.name: errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultSlice := reflect.MakeSlice(f.typ, 0, cap(vals))
|
||||||
|
for _, val := range vals {
|
||||||
|
// this check is to handle if the wrong value is provided
|
||||||
|
convertedVal := builtinConverters[f.typ.Elem().Kind()](val)
|
||||||
|
if !convertedVal.IsValid() {
|
||||||
|
errs.merge(MultiError{"default-" + f.name: fmt.Errorf("failed setting default: %s is not compatible with field %s type", val, f.name)})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
defaultSlice = reflect.Append(defaultSlice, convertedVal)
|
||||||
|
}
|
||||||
|
vCurrent.Set(defaultSlice)
|
||||||
|
} else if f.typ.Kind() == reflect.Ptr {
|
||||||
|
t1 := f.typ.Elem()
|
||||||
|
|
||||||
|
if t1.Kind() == reflect.Struct || t1.Kind() == reflect.Slice {
|
||||||
|
errs.merge(MultiError{"default-" + f.name: errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")})
|
||||||
|
}
|
||||||
|
|
||||||
|
// this check is to handle if the wrong value is provided
|
||||||
|
if convertedVal := convertPointer(t1.Kind(), f.defaultValue); convertedVal.IsValid() {
|
||||||
|
vCurrent.Set(convertedVal)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this check is to handle if the wrong value is provided
|
||||||
|
if convertedVal := builtinConverters[f.typ.Kind()](f.defaultValue); convertedVal.IsValid() {
|
||||||
|
vCurrent.Set(builtinConverters[f.typ.Kind()](f.defaultValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPointerToStruct(v reflect.Value) bool {
|
||||||
|
return !v.IsZero() && v.Type().Kind() == reflect.Ptr && v.Elem().Type().Kind() == reflect.Struct
|
||||||
|
}
|
||||||
|
|
||||||
// checkRequired checks whether required fields are empty
|
// checkRequired checks whether required fields are empty
|
||||||
//
|
//
|
||||||
// check type t recursively if t has struct fields.
|
// check type t recursively if t has struct fields.
|
||||||
@ -193,7 +288,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
|
|||||||
if v.Type().Kind() == reflect.Struct {
|
if v.Type().Kind() == reflect.Struct {
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for i := 0; i < v.NumField(); i++ {
|
||||||
field := v.Field(i)
|
field := v.Field(i)
|
||||||
if field.Type().Kind() == reflect.Ptr && field.IsNil() && v.Type().Field(i).Anonymous == true {
|
if field.Type().Kind() == reflect.Ptr && field.IsNil() && v.Type().Field(i).Anonymous {
|
||||||
field.Set(reflect.New(field.Type().Elem()))
|
field.Set(reflect.New(field.Type().Elem()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,6 +314,10 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
|
|||||||
// Slice of structs. Let's go recursive.
|
// Slice of structs. Let's go recursive.
|
||||||
if len(parts) > 1 {
|
if len(parts) > 1 {
|
||||||
idx := parts[0].index
|
idx := parts[0].index
|
||||||
|
// a defensive check to avoid creating a large slice based on user input index
|
||||||
|
if idx > d.maxSize {
|
||||||
|
return fmt.Errorf("%v index %d is larger than the configured maxSize %d", v.Kind(), idx, d.maxSize)
|
||||||
|
}
|
||||||
if v.IsNil() || v.Len() < idx+1 {
|
if v.IsNil() || v.Len() < idx+1 {
|
||||||
value := reflect.MakeSlice(t, idx+1, idx+1)
|
value := reflect.MakeSlice(t, idx+1, idx+1)
|
||||||
if v.Len() < idx+1 {
|
if v.Len() < idx+1 {
|
||||||
|
17
vendor/github.com/gorilla/schema/encoder.go
generated
vendored
17
vendor/github.com/gorilla/schema/encoder.go
generated
vendored
@ -93,8 +93,11 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encode struct pointer types if the field is a valid pointer and a struct.
|
// Encode struct pointer types if the field is a valid pointer and a struct.
|
||||||
if isValidStructPointer(v.Field(i)) {
|
if isValidStructPointer(v.Field(i)) && !e.hasCustomEncoder(v.Field(i).Type()) {
|
||||||
e.encode(v.Field(i).Elem(), dst)
|
err := e.encode(v.Field(i).Elem(), dst)
|
||||||
|
if err != nil {
|
||||||
|
errors[v.Field(i).Elem().Type().String()] = err
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +115,10 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if v.Field(i).Type().Kind() == reflect.Struct {
|
if v.Field(i).Type().Kind() == reflect.Struct {
|
||||||
e.encode(v.Field(i), dst)
|
err := e.encode(v.Field(i), dst)
|
||||||
|
if err != nil {
|
||||||
|
errors[v.Field(i).Type().String()] = err
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +148,11 @@ func (e *Encoder) encode(v reflect.Value, dst map[string][]string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) hasCustomEncoder(t reflect.Type) bool {
|
||||||
|
_, exists := e.regenc[t]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
func typeEncoder(t reflect.Type, reg map[reflect.Type]encoderFunc) encoderFunc {
|
func typeEncoder(t reflect.Type, reg map[reflect.Type]encoderFunc) encoderFunc {
|
||||||
if f, ok := reg[t]; ok {
|
if f, ok := reg[t]; ok {
|
||||||
return f
|
return f
|
||||||
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@ -488,8 +488,8 @@ github.com/gorilla/handlers
|
|||||||
# github.com/gorilla/mux v1.8.0
|
# github.com/gorilla/mux v1.8.0
|
||||||
## explicit; go 1.12
|
## explicit; go 1.12
|
||||||
github.com/gorilla/mux
|
github.com/gorilla/mux
|
||||||
# github.com/gorilla/schema v1.2.0
|
# github.com/gorilla/schema v1.4.1
|
||||||
## explicit
|
## explicit; go 1.20
|
||||||
github.com/gorilla/schema
|
github.com/gorilla/schema
|
||||||
# github.com/hashicorp/errwrap v1.1.0
|
# github.com/hashicorp/errwrap v1.1.0
|
||||||
## explicit
|
## explicit
|
||||||
|
Reference in New Issue
Block a user