diff options
Diffstat (limited to 'vendor/gopkg.in/go-playground/validator.v9')
10 files changed, 487 insertions, 268 deletions
diff --git a/vendor/gopkg.in/go-playground/validator.v9/README.md b/vendor/gopkg.in/go-playground/validator.v9/README.md index 0259370..d783749 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/README.md +++ b/vendor/gopkg.in/go-playground/validator.v9/README.md @@ -1,7 +1,7 @@ Package validator ================ <img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -![Project status](https://img.shields.io/badge/version-9.9.0-green.svg) +![Project status](https://img.shields.io/badge/version-9.11.0-green.svg) [![Build Status](https://semaphoreci.com/api/v1/joeybloggs/validator/branches/v9/badge.svg)](https://semaphoreci.com/joeybloggs/validator) [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v9&service=github)](https://coveralls.io/github/go-playground/validator?branch=v9) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) @@ -66,69 +66,71 @@ Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usa Benchmarks ------ -###### Run on MacBook Pro (15-inch, 2017) Go version go1.9.2 darwin/amd64 +###### Run on MacBook Pro (15-inch, 2017) Go version go1.9.4 darwin/amd64 ```go -go test -bench=. -benchmem=true -BenchmarkFieldSuccess-8 20000000 79.9 ns/op 0 B/op 0 allocs/op -BenchmarkFieldSuccessParallel-8 50000000 25.0 ns/op 0 B/op 0 allocs/op -BenchmarkFieldFailure-8 5000000 281 ns/op 208 B/op 4 allocs/op -BenchmarkFieldFailureParallel-8 20000000 97.0 ns/op 208 B/op 4 allocs/op -BenchmarkFieldArrayDiveSuccess-8 3000000 591 ns/op 201 B/op 11 allocs/op -BenchmarkFieldArrayDiveSuccessParallel-8 10000000 195 ns/op 201 B/op 11 allocs/op -BenchmarkFieldArrayDiveFailure-8 2000000 878 ns/op 412 B/op 16 allocs/op -BenchmarkFieldArrayDiveFailureParallel-8 5000000 274 ns/op 413 B/op 16 allocs/op -BenchmarkFieldMapDiveSuccess-8 1000000 1279 ns/op 432 B/op 18 allocs/op -BenchmarkFieldMapDiveSuccessParallel-8 5000000 401 ns/op 432 B/op 18 allocs/op -BenchmarkFieldMapDiveFailure-8 1000000 1060 ns/op 512 B/op 16 allocs/op -BenchmarkFieldMapDiveFailureParallel-8 5000000 334 ns/op 512 B/op 16 allocs/op -BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1462 ns/op 480 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 463 ns/op 480 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1414 ns/op 721 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 446 ns/op 721 B/op 21 allocs/op -BenchmarkFieldCustomTypeSuccess-8 10000000 211 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeSuccessParallel-8 20000000 65.9 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeFailure-8 5000000 270 ns/op 208 B/op 4 allocs/op -BenchmarkFieldCustomTypeFailureParallel-8 20000000 93.3 ns/op 208 B/op 4 allocs/op -BenchmarkFieldOrTagSuccess-8 2000000 729 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagSuccessParallel-8 5000000 367 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagFailure-8 3000000 472 ns/op 224 B/op 5 allocs/op -BenchmarkFieldOrTagFailureParallel-8 5000000 373 ns/op 224 B/op 5 allocs/op -BenchmarkStructLevelValidationSuccess-8 10000000 201 ns/op 32 B/op 2 allocs/op -BenchmarkStructLevelValidationSuccessParallel-8 20000000 66.3 ns/op 32 B/op 2 allocs/op -BenchmarkStructLevelValidationFailure-8 3000000 468 ns/op 304 B/op 8 allocs/op -BenchmarkStructLevelValidationFailureParallel-8 10000000 172 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCustomTypeSuccess-8 5000000 376 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeSuccessParallel-8 20000000 126 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeFailure-8 2000000 646 ns/op 424 B/op 9 allocs/op -BenchmarkStructSimpleCustomTypeFailureParallel-8 10000000 240 ns/op 440 B/op 10 allocs/op -BenchmarkStructFilteredSuccess-8 3000000 582 ns/op 288 B/op 9 allocs/op -BenchmarkStructFilteredSuccessParallel-8 10000000 198 ns/op 288 B/op 9 allocs/op -BenchmarkStructFilteredFailure-8 3000000 447 ns/op 256 B/op 7 allocs/op -BenchmarkStructFilteredFailureParallel-8 10000000 156 ns/op 256 B/op 7 allocs/op -BenchmarkStructPartialSuccess-8 3000000 536 ns/op 256 B/op 6 allocs/op -BenchmarkStructPartialSuccessParallel-8 10000000 175 ns/op 256 B/op 6 allocs/op -BenchmarkStructPartialFailure-8 2000000 738 ns/op 480 B/op 11 allocs/op -BenchmarkStructPartialFailureParallel-8 5000000 256 ns/op 480 B/op 11 allocs/op -BenchmarkStructExceptSuccess-8 2000000 835 ns/op 496 B/op 12 allocs/op -BenchmarkStructExceptSuccessParallel-8 10000000 163 ns/op 240 B/op 5 allocs/op -BenchmarkStructExceptFailure-8 2000000 682 ns/op 464 B/op 10 allocs/op -BenchmarkStructExceptFailureParallel-8 10000000 244 ns/op 464 B/op 10 allocs/op -BenchmarkStructSimpleCrossFieldSuccess-8 5000000 392 ns/op 72 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldSuccessParallel-8 20000000 126 ns/op 72 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldFailure-8 2000000 611 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCrossFieldFailureParallel-8 10000000 214 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 567 ns/op 80 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 177 ns/op 80 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 807 ns/op 320 B/op 9 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 268 ns/op 320 B/op 9 allocs/op -BenchmarkStructSimpleSuccess-8 5000000 256 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleSuccessParallel-8 20000000 76.3 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleFailure-8 2000000 625 ns/op 424 B/op 9 allocs/op -BenchmarkStructSimpleFailureParallel-8 10000000 219 ns/op 424 B/op 9 allocs/op -BenchmarkStructComplexSuccess-8 1000000 1431 ns/op 128 B/op 8 allocs/op -BenchmarkStructComplexSuccessParallel-8 3000000 427 ns/op 128 B/op 8 allocs/op -BenchmarkStructComplexFailure-8 300000 4065 ns/op 3041 B/op 53 allocs/op -BenchmarkStructComplexFailureParallel-8 1000000 1478 ns/op 3041 B/op 53 allocs/op +goos: darwin +goarch: amd64 +pkg: github.com/go-playground/validator +BenchmarkFieldSuccess-8 20000000 86.4 ns/op 0 B/op 0 allocs/op +BenchmarkFieldSuccessParallel-8 50000000 27.6 ns/op 0 B/op 0 allocs/op +BenchmarkFieldFailure-8 5000000 297 ns/op 208 B/op 4 allocs/op +BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op +BenchmarkFieldArrayDiveSuccess-8 2000000 618 ns/op 201 B/op 11 allocs/op +BenchmarkFieldArrayDiveSuccessParallel-8 10000000 225 ns/op 201 B/op 11 allocs/op +BenchmarkFieldArrayDiveFailure-8 2000000 863 ns/op 412 B/op 16 allocs/op +BenchmarkFieldArrayDiveFailureParallel-8 5000000 322 ns/op 413 B/op 16 allocs/op +BenchmarkFieldMapDiveSuccess-8 1000000 1336 ns/op 432 B/op 18 allocs/op +BenchmarkFieldMapDiveSuccessParallel-8 3000000 474 ns/op 432 B/op 18 allocs/op +BenchmarkFieldMapDiveFailure-8 1000000 1103 ns/op 512 B/op 16 allocs/op +BenchmarkFieldMapDiveFailureParallel-8 5000000 412 ns/op 512 B/op 16 allocs/op +BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1572 ns/op 480 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 615 ns/op 480 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1438 ns/op 721 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 543 ns/op 721 B/op 21 allocs/op +BenchmarkFieldCustomTypeSuccess-8 10000000 230 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.5 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-8 5000000 284 ns/op 208 B/op 4 allocs/op +BenchmarkFieldCustomTypeFailureParallel-8 20000000 118 ns/op 208 B/op 4 allocs/op +BenchmarkFieldOrTagSuccess-8 2000000 824 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagSuccessParallel-8 3000000 472 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-8 3000000 487 ns/op 224 B/op 5 allocs/op +BenchmarkFieldOrTagFailureParallel-8 5000000 405 ns/op 224 B/op 5 allocs/op +BenchmarkStructLevelValidationSuccess-8 10000000 214 ns/op 32 B/op 2 allocs/op +BenchmarkStructLevelValidationSuccessParallel-8 20000000 78.0 ns/op 32 B/op 2 allocs/op +BenchmarkStructLevelValidationFailure-8 3000000 475 ns/op 304 B/op 8 allocs/op +BenchmarkStructLevelValidationFailureParallel-8 10000000 200 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-8 3000000 403 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 143 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeFailure-8 2000000 655 ns/op 424 B/op 9 allocs/op +BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 286 ns/op 440 B/op 10 allocs/op +BenchmarkStructFilteredSuccess-8 2000000 598 ns/op 288 B/op 9 allocs/op +BenchmarkStructFilteredSuccessParallel-8 10000000 231 ns/op 288 B/op 9 allocs/op +BenchmarkStructFilteredFailure-8 3000000 455 ns/op 256 B/op 7 allocs/op +BenchmarkStructFilteredFailureParallel-8 10000000 197 ns/op 256 B/op 7 allocs/op +BenchmarkStructPartialSuccess-8 3000000 552 ns/op 256 B/op 6 allocs/op +BenchmarkStructPartialSuccessParallel-8 10000000 206 ns/op 256 B/op 6 allocs/op +BenchmarkStructPartialFailure-8 2000000 750 ns/op 480 B/op 11 allocs/op +BenchmarkStructPartialFailureParallel-8 5000000 317 ns/op 480 B/op 11 allocs/op +BenchmarkStructExceptSuccess-8 2000000 853 ns/op 496 B/op 12 allocs/op +BenchmarkStructExceptSuccessParallel-8 10000000 179 ns/op 240 B/op 5 allocs/op +BenchmarkStructExceptFailure-8 2000000 698 ns/op 464 B/op 10 allocs/op +BenchmarkStructExceptFailureParallel-8 5000000 276 ns/op 464 B/op 10 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-8 3000000 412 ns/op 72 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 148 ns/op 72 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldFailure-8 2000000 630 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldFailureParallel-8 10000000 244 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 2000000 610 ns/op 80 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 205 ns/op 80 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 861 ns/op 320 B/op 9 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 315 ns/op 320 B/op 9 allocs/op +BenchmarkStructSimpleSuccess-8 5000000 279 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleSuccessParallel-8 20000000 86.4 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleFailure-8 2000000 636 ns/op 424 B/op 9 allocs/op +BenchmarkStructSimpleFailureParallel-8 10000000 264 ns/op 424 B/op 9 allocs/op +BenchmarkStructComplexSuccess-8 1000000 1539 ns/op 128 B/op 8 allocs/op +BenchmarkStructComplexSuccessParallel-8 3000000 557 ns/op 128 B/op 8 allocs/op +BenchmarkStructComplexFailure-8 300000 4136 ns/op 3041 B/op 53 allocs/op +BenchmarkStructComplexFailureParallel-8 1000000 1855 ns/op 3041 B/op 53 allocs/op ``` Complementary Software diff --git a/vendor/gopkg.in/go-playground/validator.v9/baked_in.go b/vendor/gopkg.in/go-playground/validator.v9/baked_in.go index 6654094..231b78e 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/baked_in.go +++ b/vendor/gopkg.in/go-playground/validator.v9/baked_in.go @@ -6,7 +6,9 @@ import ( "net" "net/url" "reflect" + "strconv" "strings" + "sync" "time" "unicode/utf8" ) @@ -55,88 +57,130 @@ var ( // you can add, remove or even replace items to suite your needs, // or even disregard and use your own map if so desired. bakedInValidators = map[string]Func{ - "required": hasValue, - "isdefault": isDefault, - "len": hasLengthOf, - "min": hasMinOf, - "max": hasMaxOf, - "eq": isEq, - "ne": isNe, - "lt": isLt, - "lte": isLte, - "gt": isGt, - "gte": isGte, - "eqfield": isEqField, - "eqcsfield": isEqCrossStructField, - "necsfield": isNeCrossStructField, - "gtcsfield": isGtCrossStructField, - "gtecsfield": isGteCrossStructField, - "ltcsfield": isLtCrossStructField, - "ltecsfield": isLteCrossStructField, - "nefield": isNeField, - "gtefield": isGteField, - "gtfield": isGtField, - "ltefield": isLteField, - "ltfield": isLtField, - "alpha": isAlpha, - "alphanum": isAlphanum, - "alphaunicode": isAlphaUnicode, - "alphanumunicode": isAlphanumUnicode, - "numeric": isNumeric, - "number": isNumber, - "hexadecimal": isHexadecimal, - "hexcolor": isHEXColor, - "rgb": isRGB, - "rgba": isRGBA, - "hsl": isHSL, - "hsla": isHSLA, - "email": isEmail, - "url": isURL, - "uri": isURI, - "base64": isBase64, - "contains": contains, - "containsany": containsAny, - "containsrune": containsRune, - "excludes": excludes, - "excludesall": excludesAll, - "excludesrune": excludesRune, - "isbn": isISBN, - "isbn10": isISBN10, - "isbn13": isISBN13, - "uuid": isUUID, - "uuid3": isUUID3, - "uuid4": isUUID4, - "uuid5": isUUID5, - "ascii": isASCII, - "printascii": isPrintableASCII, - "multibyte": hasMultiByteCharacter, - "datauri": isDataURI, - "latitude": isLatitude, - "longitude": isLongitude, - "ssn": isSSN, - "ipv4": isIPv4, - "ipv6": isIPv6, - "ip": isIP, - "cidrv4": isCIDRv4, - "cidrv6": isCIDRv6, - "cidr": isCIDR, - "tcp4_addr": isTCP4AddrResolvable, - "tcp6_addr": isTCP6AddrResolvable, - "tcp_addr": isTCPAddrResolvable, - "udp4_addr": isUDP4AddrResolvable, - "udp6_addr": isUDP6AddrResolvable, - "udp_addr": isUDPAddrResolvable, - "ip4_addr": isIP4AddrResolvable, - "ip6_addr": isIP6AddrResolvable, - "ip_addr": isIPAddrResolvable, - "unix_addr": isUnixAddrResolvable, - "mac": isMAC, - "hostname": isHostname, - "fqdn": isFQDN, - "unique": isUnique, + "required": hasValue, + "isdefault": isDefault, + "len": hasLengthOf, + "min": hasMinOf, + "max": hasMaxOf, + "eq": isEq, + "ne": isNe, + "lt": isLt, + "lte": isLte, + "gt": isGt, + "gte": isGte, + "eqfield": isEqField, + "eqcsfield": isEqCrossStructField, + "necsfield": isNeCrossStructField, + "gtcsfield": isGtCrossStructField, + "gtecsfield": isGteCrossStructField, + "ltcsfield": isLtCrossStructField, + "ltecsfield": isLteCrossStructField, + "nefield": isNeField, + "gtefield": isGteField, + "gtfield": isGtField, + "ltefield": isLteField, + "ltfield": isLtField, + "alpha": isAlpha, + "alphanum": isAlphanum, + "alphaunicode": isAlphaUnicode, + "alphanumunicode": isAlphanumUnicode, + "numeric": isNumeric, + "number": isNumber, + "hexadecimal": isHexadecimal, + "hexcolor": isHEXColor, + "rgb": isRGB, + "rgba": isRGBA, + "hsl": isHSL, + "hsla": isHSLA, + "email": isEmail, + "url": isURL, + "uri": isURI, + "base64": isBase64, + "contains": contains, + "containsany": containsAny, + "containsrune": containsRune, + "excludes": excludes, + "excludesall": excludesAll, + "excludesrune": excludesRune, + "isbn": isISBN, + "isbn10": isISBN10, + "isbn13": isISBN13, + "uuid": isUUID, + "uuid3": isUUID3, + "uuid4": isUUID4, + "uuid5": isUUID5, + "ascii": isASCII, + "printascii": isPrintableASCII, + "multibyte": hasMultiByteCharacter, + "datauri": isDataURI, + "latitude": isLatitude, + "longitude": isLongitude, + "ssn": isSSN, + "ipv4": isIPv4, + "ipv6": isIPv6, + "ip": isIP, + "cidrv4": isCIDRv4, + "cidrv6": isCIDRv6, + "cidr": isCIDR, + "tcp4_addr": isTCP4AddrResolvable, + "tcp6_addr": isTCP6AddrResolvable, + "tcp_addr": isTCPAddrResolvable, + "udp4_addr": isUDP4AddrResolvable, + "udp6_addr": isUDP6AddrResolvable, + "udp_addr": isUDPAddrResolvable, + "ip4_addr": isIP4AddrResolvable, + "ip6_addr": isIP6AddrResolvable, + "ip_addr": isIPAddrResolvable, + "unix_addr": isUnixAddrResolvable, + "mac": isMAC, + "hostname": isHostnameRFC952, // RFC 952 + "hostname_rfc1123": isHostnameRFC1123, // RFC 1123 + "fqdn": isFQDN, + "unique": isUnique, + "oneof": isOneOf, } ) +var oneofValsCache = map[string][]string{} +var oneofValsCacheRWLock = sync.RWMutex{} + +func parseOneOfParam2(s string) []string { + oneofValsCacheRWLock.RLock() + vals, ok := oneofValsCache[s] + oneofValsCacheRWLock.RUnlock() + if !ok { + oneofValsCacheRWLock.Lock() + vals = strings.Fields(s) + oneofValsCache[s] = vals + oneofValsCacheRWLock.Unlock() + } + return vals +} + +func isOneOf(fl FieldLevel) bool { + vals := parseOneOfParam2(fl.Param()) + + field := fl.Field() + + var v string + switch field.Kind() { + case reflect.String: + v = field.String() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v = strconv.FormatInt(field.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v = strconv.FormatUint(field.Uint(), 10) + default: + panic(fmt.Sprintf("Bad field type %T", field.Interface())) + } + for i := 0; i < len(vals); i++ { + if vals[i] == v { + return true + } + } + return false +} + // isUnique is the validation function for validating if each array|slice element is unique func isUnique(fl FieldLevel) bool { @@ -1511,8 +1555,12 @@ func isIP6Addr(fl FieldLevel) bool { return ip != nil && ip.To4() == nil } -func isHostname(fl FieldLevel) bool { - return hostnameRegex.MatchString(fl.Field().String()) +func isHostnameRFC952(fl FieldLevel) bool { + return hostnameRegexRFC952.MatchString(fl.Field().String()) +} + +func isHostnameRFC1123(fl FieldLevel) bool { + return hostnameRegexRFC1123.MatchString(fl.Field().String()) } func isFQDN(fl FieldLevel) bool { @@ -1526,6 +1574,6 @@ func isFQDN(fl FieldLevel) bool { val = val[0 : len(val)-1] } - return (strings.IndexAny(val, ".") > -1) && - hostnameRegex.MatchString(val) + return strings.ContainsAny(val, ".") && + hostnameRegexRFC952.MatchString(val) } diff --git a/vendor/gopkg.in/go-playground/validator.v9/benchmarks_test.go b/vendor/gopkg.in/go-playground/validator.v9/benchmarks_test.go index 3e7e79f..5ac871f 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/benchmarks_test.go +++ b/vendor/gopkg.in/go-playground/validator.v9/benchmarks_test.go @@ -1184,3 +1184,27 @@ func BenchmarkStructComplexFailureParallel(b *testing.B) { } }) } + +type TestOneof struct { + Color string `validate:"oneof=red green"` +} + +func BenchmarkOneof(b *testing.B) { + w := &TestOneof{Color: "green"} + val := New() + for i := 0; i < b.N; i++ { + val.Struct(w) + } +} + +func BenchmarkOneofParallel(b *testing.B) { + w := &TestOneof{Color: "green"} + val := New() + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + val.Struct(w) + } + }) +} diff --git a/vendor/gopkg.in/go-playground/validator.v9/cache.go b/vendor/gopkg.in/go-playground/validator.v9/cache.go index 8c59e16..c7fb0fb 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/cache.go +++ b/vendor/gopkg.in/go-playground/validator.v9/cache.go @@ -91,12 +91,14 @@ type cTag struct { aliasTag string actualAliasTag string param string - typeof tagType keys *cTag // only populated when using tag's 'keys' and 'endkeys' for map key validation next *cTag + fn FuncCtx + typeof tagType hasTag bool hasAlias bool - fn FuncCtx + hasParam bool // true if parameter used eg. eq= where the equal sign has been set + isBlockEnd bool // indicates the current tag represents the last validation in the block } func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStruct { @@ -291,6 +293,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true} current = current.next } + current.hasParam = len(vals) > 1 current.tag = vals[0] if len(current.tag) == 0 { @@ -309,8 +312,26 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1) } } + current.isBlockEnd = true } } - return } + +func (v *Validate) fetchCacheTag(tag string) *cTag { + // find cached tag + ctag, found := v.tagCache.Get(tag) + if !found { + v.tagCache.lock.Lock() + defer v.tagCache.lock.Unlock() + + // could have been multiple trying to access, but once first is done this ensures tag + // isn't parsed again. + ctag, found = v.tagCache.Get(tag) + if !found { + ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false) + v.tagCache.Set(tag, ctag) + } + } + return ctag +} diff --git a/vendor/gopkg.in/go-playground/validator.v9/doc.go b/vendor/gopkg.in/go-playground/validator.v9/doc.go index d3a69f7..f7efe23 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/doc.go +++ b/vendor/gopkg.in/go-playground/validator.v9/doc.go @@ -94,7 +94,7 @@ used "eqcsfield" it could be multiple levels down. Example: // NOTE: when calling validate.Struct(val) topStruct will be the top level struct passed // into the function - // when calling validate.FieldWithValue(val, field, tag) val will be + // when calling validate.VarWithValue(val, field, tag) val will be // whatever you pass, struct, field... // when calling validate.Field(field, tag) val will be nil @@ -132,7 +132,7 @@ so the above will become excludesall=0x2C. Field `validate:"excludesall=0x2C"` // GOOD! Use the UTF-8 hex representation. } -Pipe ("|") is the default separator of validation tags. If you wish to +Pipe ("|") is the 'or' validation tags deparator. If you wish to have a pipe included within the parameter i.e. excludesall=| you will need to use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe, so the above will become excludesall=0x7C @@ -295,6 +295,16 @@ validates the number of items. Usage: ne=10 +One Of + +For strings, ints, and uints, oneof will ensure that the value +is one of the values in the parameter. The parameter should be +a list of values separated by whitespace. Values may be +strings or numbers. + + Usage: oneof=red green + oneof=5 7 9 + Greater Than For numbers, this will ensure that the value is greater than the @@ -369,7 +379,7 @@ Example #1: Example #2: // Validating by field: - validate.FieldWithValue(password, confirmpassword, "eqfield") + validate.VarWithValue(password, confirmpassword, "eqfield") Field Equals Another Field (relative) @@ -391,7 +401,7 @@ Examples: Usage: nefield=Color2 // Validating by field: - validate.FieldWithValue(color1, color2, "nefield") + validate.VarWithValue(color1, color2, "nefield") Field Does Not Equal Another Field (relative) @@ -414,7 +424,7 @@ Example #1: Example #2: // Validating by field: - validate.FieldWithValue(start, end, "gtfield") + validate.VarWithValue(start, end, "gtfield") Field Greater Than Another Relative Field @@ -438,7 +448,7 @@ Example #1: Example #2: // Validating by field: - validate.FieldWithValue(start, end, "gtefield") + validate.VarWithValue(start, end, "gtefield") Field Greater Than or Equal To Another Relative Field @@ -461,7 +471,7 @@ Example #1: Example #2: // Validating by field: - validate.FieldWithValue(start, end, "ltfield") + validate.VarWithValue(start, end, "ltfield") Less Than Another Relative Field @@ -484,7 +494,7 @@ Example #1: Example #2: // Validating by field: - validate.FieldWithValue(start, end, "ltefield") + validate.VarWithValue(start, end, "ltefield") Less Than or Equal To Another Relative Field @@ -832,12 +842,18 @@ Note: See Go's ParseMAC for accepted formats and types: http://golang.org/src/net/mac.go?s=866:918#L29 -Hostname +Hostname RFC 952 -This validates that a string value is a valid Hostname +This validates that a string value is a valid Hostname according to RFC 952 https://tools.ietf.org/html/rfc952 Usage: hostname +Hostname RFC 1123 + +This validates that a string value is a valid Hostname according to RFC 1123 https://tools.ietf.org/html/rfc1123 + + Usage: hostname_rfc1123 or if you want to continue to use 'hostname' in your tags, create an alias. + Full Qualified Domain Name (FQDN) This validates that a string value contains a valid FQDN. diff --git a/vendor/gopkg.in/go-playground/validator.v9/regexes.go b/vendor/gopkg.in/go-playground/validator.v9/regexes.go index ec78ceb..78f3ea0 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/regexes.go +++ b/vendor/gopkg.in/go-playground/validator.v9/regexes.go @@ -30,7 +30,8 @@ const ( latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" sSNRegexString = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` - hostnameRegexString = `^[a-zA-Z][a-zA-Z0-9\-\.]+[a-z-Az0-9]$` + hostnameRegexStringRFC952 = `^[a-zA-Z][a-zA-Z0-9\-\.]+[a-z-Az0-9]$` // https://tools.ietf.org/html/rfc952 + hostnameRegexStringRFC1123 = `^[a-zA-Z0-9][a-zA-Z0-9\-\.]+[a-z-Az0-9]$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123 ) var ( @@ -61,5 +62,6 @@ var ( latitudeRegex = regexp.MustCompile(latitudeRegexString) longitudeRegex = regexp.MustCompile(longitudeRegexString) sSNRegex = regexp.MustCompile(sSNRegexString) - hostnameRegex = regexp.MustCompile(hostnameRegexString) + hostnameRegexRFC952 = regexp.MustCompile(hostnameRegexStringRFC952) + hostnameRegexRFC1123 = regexp.MustCompile(hostnameRegexStringRFC1123) ) diff --git a/vendor/gopkg.in/go-playground/validator.v9/util.go b/vendor/gopkg.in/go-playground/validator.v9/util.go index a01d4b1..16a5517 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/util.go +++ b/vendor/gopkg.in/go-playground/validator.v9/util.go @@ -80,7 +80,7 @@ BEGIN: typ := current.Type() fld := namespace - ns := namespace + var ns string if typ != timeType { diff --git a/vendor/gopkg.in/go-playground/validator.v9/validator.go b/vendor/gopkg.in/go-playground/validator.v9/validator.go index f180a9c..483e0a2 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/validator.go +++ b/vendor/gopkg.in/go-playground/validator.v9/validator.go @@ -14,24 +14,19 @@ type validate struct { ns []byte actualNs []byte errs ValidationErrors + includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise + ffn FilterFunc + slflParent reflect.Value // StructLevel & FieldLevel + slCurrent reflect.Value // StructLevel & FieldLevel + flField reflect.Value // StructLevel & FieldLevel + cf *cField // StructLevel & FieldLevel + ct *cTag // StructLevel & FieldLevel + misc []byte // misc reusable + str1 string // misc reusable + str2 string // misc reusable + fldIsPointer bool // StructLevel & FieldLevel isPartial bool hasExcludes bool - includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise - - ffn FilterFunc - - // StructLevel & FieldLevel fields - slflParent reflect.Value - slCurrent reflect.Value - flField reflect.Value - fldIsPointer bool - cf *cField - ct *cTag - - // misc reusable values - misc []byte - str1 string - str2 string } // parent and current will be the same the first run of validateStruct @@ -127,7 +122,6 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr } if kind == reflect.Invalid { - v.errs = append(v.errs, &fieldError{ v: v.v, @@ -378,14 +372,13 @@ OUTER: v.misc = append(v.misc, '|') v.misc = append(v.misc, ct.tag...) - if len(ct.param) > 0 { + if ct.hasParam { v.misc = append(v.misc, '=') v.misc = append(v.misc, ct.param...) } - if ct.next == nil || ct.next.typeof != typeOr { // ct.typeof != typeOr + if ct.isBlockEnd || ct.next == nil { // if we get here, no valid 'or' value and no more tags - v.str1 = string(append(ns, cf.altName...)) if v.v.hasTagNameFunc { @@ -474,9 +467,7 @@ OUTER: ) return - } - ct = ct.next } } diff --git a/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go b/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go index d3a1543..e84b452 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go +++ b/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go @@ -370,39 +370,37 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields . typ := val.Type() name := typ.Name() - if fields != nil { - for _, k := range fields { + for _, k := range fields { - flds := strings.Split(k, namespaceSeparator) - if len(flds) > 0 { + flds := strings.Split(k, namespaceSeparator) + if len(flds) > 0 { - vd.misc = append(vd.misc[0:0], name...) - vd.misc = append(vd.misc, '.') - - for _, s := range flds { + vd.misc = append(vd.misc[0:0], name...) + vd.misc = append(vd.misc, '.') - idx := strings.Index(s, leftBracket) + for _, s := range flds { - if idx != -1 { - for idx != -1 { - vd.misc = append(vd.misc, s[:idx]...) - vd.includeExclude[string(vd.misc)] = struct{}{} + idx := strings.Index(s, leftBracket) - idx2 := strings.Index(s, rightBracket) - idx2++ - vd.misc = append(vd.misc, s[idx:idx2]...) - vd.includeExclude[string(vd.misc)] = struct{}{} - s = s[idx2:] - idx = strings.Index(s, leftBracket) - } - } else { + if idx != -1 { + for idx != -1 { + vd.misc = append(vd.misc, s[:idx]...) + vd.includeExclude[string(vd.misc)] = struct{}{} - vd.misc = append(vd.misc, s...) + idx2 := strings.Index(s, rightBracket) + idx2++ + vd.misc = append(vd.misc, s[idx:idx2]...) vd.includeExclude[string(vd.misc)] = struct{}{} + s = s[idx2:] + idx = strings.Index(s, leftBracket) } + } else { - vd.misc = append(vd.misc, '.') + vd.misc = append(vd.misc, s...) + vd.includeExclude[string(vd.misc)] = struct{}{} } + + vd.misc = append(vd.misc, '.') } } } @@ -520,36 +518,18 @@ func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (e return nil } - // find cached tag - ctag, ok := v.tagCache.Get(tag) - if !ok { - v.tagCache.lock.Lock() - defer v.tagCache.lock.Unlock() - - // could have been multiple trying to access, but once first is done this ensures tag - // isn't parsed again. - ctag, ok = v.tagCache.Get(tag) - if !ok { - ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false) - v.tagCache.Set(tag, ctag) - } - } - + ctag := v.fetchCacheTag(tag) val := reflect.ValueOf(field) - vd := v.pool.Get().(*validate) vd.top = val vd.isPartial = false - vd.traverseField(ctx, val, val, vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag) if len(vd.errs) > 0 { err = vd.errs vd.errs = nil } - v.pool.Put(vd) - return } @@ -590,36 +570,17 @@ func (v *Validate) VarWithValueCtx(ctx context.Context, field interface{}, other if len(tag) == 0 || tag == skipValidationTag { return nil } - - // find cached tag - ctag, ok := v.tagCache.Get(tag) - if !ok { - v.tagCache.lock.Lock() - defer v.tagCache.lock.Unlock() - - // could have been multiple trying to access, but once first is done this ensures tag - // isn't parsed again. - ctag, ok = v.tagCache.Get(tag) - if !ok { - ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false) - v.tagCache.Set(tag, ctag) - } - } - + ctag := v.fetchCacheTag(tag) otherVal := reflect.ValueOf(other) - vd := v.pool.Get().(*validate) vd.top = otherVal vd.isPartial = false - vd.traverseField(ctx, otherVal, reflect.ValueOf(field), vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag) if len(vd.errs) > 0 { err = vd.errs vd.errs = nil } - v.pool.Put(vd) - return } diff --git a/vendor/gopkg.in/go-playground/validator.v9/validator_test.go b/vendor/gopkg.in/go-playground/validator.v9/validator_test.go index 7d085e8..9600d0f 100644 --- a/vendor/gopkg.in/go-playground/validator.v9/validator_test.go +++ b/vendor/gopkg.in/go-playground/validator.v9/validator_test.go @@ -1564,10 +1564,6 @@ func TestCrossNamespaceFieldValidation(t *testing.T) { Name string } - type MapStruct struct { - Name string - } - type Inner struct { CreatedAt *time.Time Slice []string @@ -1653,10 +1649,10 @@ func TestCrossNamespaceFieldValidation(t *testing.T) { Equal(t, kind, reflect.String) Equal(t, current.String(), "val2") - current, kind, ok = v.getStructFieldOKInternal(val, "Inner.CrazyNonExistantField") + current, _, ok = v.getStructFieldOKInternal(val, "Inner.CrazyNonExistantField") Equal(t, ok, false) - current, kind, ok = v.getStructFieldOKInternal(val, "Inner.Slice[101]") + current, _, ok = v.getStructFieldOKInternal(val, "Inner.Slice[101]") Equal(t, ok, false) current, kind, ok = v.getStructFieldOKInternal(val, "Inner.Map[key3]") @@ -1854,8 +1850,6 @@ func TestSQLValue2Validation(t *testing.T) { PanicMatches(t, func() { validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error") - type myValuer valuer - myVal := valuer{ Name: "", } @@ -1907,8 +1901,6 @@ func TestSQLValueValidation(t *testing.T) { PanicMatches(t, func() { errs = validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error") - type myValuer valuer - myVal := valuer{ Name: "", } @@ -2696,11 +2688,8 @@ func TestBadKeyValidation(t *testing.T) { func TestInterfaceErrValidation(t *testing.T) { - var v1 interface{} - var v2 interface{} - - v2 = 1 - v1 = v2 + var v2 interface{} = 1 + var v1 interface{} = v2 validate := New() errs := validate.Var(v1, "len=1") @@ -4325,6 +4314,66 @@ func TestIsEqValidation(t *testing.T) { PanicMatches(t, func() { validate.Var(now, "eq=now") }, "Bad field type time.Time") } +func TestOneOfValidation(t *testing.T) { + validate := New() + + passSpecs := []struct { + f interface{} + t string + }{ + {f: "red", t: "oneof=red green"}, + {f: "green", t: "oneof=red green"}, + {f: 5, t: "oneof=5 6"}, + {f: 6, t: "oneof=5 6"}, + {f: int8(6), t: "oneof=5 6"}, + {f: int16(6), t: "oneof=5 6"}, + {f: int32(6), t: "oneof=5 6"}, + {f: int64(6), t: "oneof=5 6"}, + {f: uint(6), t: "oneof=5 6"}, + {f: uint8(6), t: "oneof=5 6"}, + {f: uint16(6), t: "oneof=5 6"}, + {f: uint32(6), t: "oneof=5 6"}, + {f: uint64(6), t: "oneof=5 6"}, + } + + for _, spec := range passSpecs { + t.Logf("%#v", spec) + errs := validate.Var(spec.f, spec.t) + Equal(t, errs, nil) + } + + failSpecs := []struct { + f interface{} + t string + }{ + {f: "", t: "oneof=red green"}, + {f: "yellow", t: "oneof=red green"}, + {f: 5, t: "oneof=red green"}, + {f: 6, t: "oneof=red green"}, + {f: 6, t: "oneof=7"}, + {f: uint(6), t: "oneof=7"}, + {f: int8(5), t: "oneof=red green"}, + {f: int16(5), t: "oneof=red green"}, + {f: int32(5), t: "oneof=red green"}, + {f: int64(5), t: "oneof=red green"}, + {f: uint(5), t: "oneof=red green"}, + {f: uint8(5), t: "oneof=red green"}, + {f: uint16(5), t: "oneof=red green"}, + {f: uint32(5), t: "oneof=red green"}, + {f: uint64(5), t: "oneof=red green"}, + } + + for _, spec := range failSpecs { + t.Logf("%#v", spec) + errs := validate.Var(spec.f, spec.t) + AssertError(t, errs, "", "", "", "", "oneof") + } + + PanicMatches(t, func() { + validate.Var(3.14, "oneof=red green") + }, "Bad field type float64") +} + func TestBase64Validation(t *testing.T) { validate := New() @@ -5585,6 +5634,13 @@ func TestOrTag(t *testing.T) { errs = validate.Var(s, "omitempty,rgb|rgba") Equal(t, errs, nil) + s = "green" + errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") //should fail on first validation block + NotEqual(t, errs, nil) + ve := errs.(ValidationErrors) + Equal(t, len(ve), 1) + Equal(t, ve[0].Tag(), "eq=|eq=blue") + s = "this is right, but a blank or isn't" PanicMatches(t, func() { validate.Var(s, "rgb||len=13") }, "Invalid validation tag on field ''") @@ -7139,7 +7195,7 @@ func TestValidateStructRegisterCtx(t *testing.T) { Equal(t, ctxSlVal, "slVal") } -func TestHostnameValidation(t *testing.T) { +func TestHostnameRFC952Validation(t *testing.T) { tests := []struct { param string expected bool @@ -7150,6 +7206,7 @@ func TestHostnameValidation(t *testing.T) { {"test.example24.com", true}, {"test24.example24.com", true}, {"example", true}, + {"1.foo.com", false}, {"test.example.com.", false}, {"example.com.", false}, {"example24.com.", false}, @@ -7171,15 +7228,112 @@ func TestHostnameValidation(t *testing.T) { if test.expected { if !IsEqual(errs, nil) { - t.Fatalf("Index: %d hostname failed Error: %s", i, errs) + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) + } else { + val := getError(errs, "", "") + if val.Tag() != "hostname" { + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) + } + } + } + } +} + +func TestHostnameRFC1123Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"test.example.com", true}, + {"example.com", true}, + {"example24.com", true}, + {"test.example24.com", true}, + {"test24.example24.com", true}, + {"example", true}, + {"1.foo.com", true}, + {"test.example.com.", false}, + {"example.com.", false}, + {"example24.com.", false}, + {"test.example24.com.", false}, + {"test24.example24.com.", false}, + {"example.", false}, + {"192.168.0.1", true}, + {"email@example.com", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, + {"2001:cdba:0:0:0:0:3257:9652", false}, + {"2001:cdba::3257:9652", false}, + } + + validate := New() + + for i, test := range tests { + + errs := validate.Var(test.param, "hostname_rfc1123") + + if test.expected { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) + } else { + val := getError(errs, "", "") + if val.Tag() != "hostname_rfc1123" { + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) + } + } + } + } +} + +func TestHostnameRFC1123AliasValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"test.example.com", true}, + {"example.com", true}, + {"example24.com", true}, + {"test.example24.com", true}, + {"test24.example24.com", true}, + {"example", true}, + {"1.foo.com", true}, + {"test.example.com.", false}, + {"example.com.", false}, + {"example24.com.", false}, + {"test.example24.com.", false}, + {"test24.example24.com.", false}, + {"example.", false}, + {"192.168.0.1", true}, + {"email@example.com", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, + {"2001:cdba:0:0:0:0:3257:9652", false}, + {"2001:cdba::3257:9652", false}, + } + + validate := New() + validate.RegisterAlias("hostname", "hostname_rfc1123") + + for i, test := range tests { + + errs := validate.Var(test.param, "hostname") + + if test.expected { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) } } else { if IsEqual(errs, nil) { - t.Fatalf("Index: %d hostname failed Error: %s", i, errs) + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) } else { val := getError(errs, "", "") if val.Tag() != "hostname" { - t.Fatalf("Index: %d hostname failed Error: %s", i, errs) + t.Fatalf("Index: %d hostname failed Error: %v", i, errs) } } } @@ -7219,15 +7373,15 @@ func TestFQDNValidation(t *testing.T) { if test.expected { if !IsEqual(errs, nil) { - t.Fatalf("Index: %d fqdn failed Error: %s", i, errs) + t.Fatalf("Index: %d fqdn failed Error: %v", i, errs) } } else { if IsEqual(errs, nil) { - t.Fatalf("Index: %d fqdn failed Error: %s", i, errs) + t.Fatalf("Index: %d fqdn failed Error: %v", i, errs) } else { val := getError(errs, "", "") if val.Tag() != "fqdn" { - t.Fatalf("Index: %d fqdn failed Error: %s", i, errs) + t.Fatalf("Index: %d fqdn failed Error: %v", i, errs) } } } |