PageRenderTime 1451ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/gopkg.in/go-playground/validator.v9/baked_in.go

https://bitbucket.org/afawkes/acs-engine
Go | 1469 lines | 906 code | 448 blank | 115 comment | 233 complexity | 519be583a8cd177a36e5d5c11b2608f1 MD5 | raw file
Possible License(s): MIT, Apache-2.0, 0BSD, AGPL-3.0, BSD-3-Clause, LGPL-3.0
  1. package validator
  2. import (
  3. "fmt"
  4. "net"
  5. "net/url"
  6. "reflect"
  7. "strings"
  8. "time"
  9. "unicode/utf8"
  10. )
  11. // Func accepts all values needed for file and cross field validation
  12. // fl = FieldLevel validation helper
  13. // field = field value for validation
  14. // fieldType = fields
  15. // param = parameter used in validation i.e. gt=0 param would be 0
  16. type Func func(fl FieldLevel) bool
  17. var (
  18. restrictedTags = map[string]struct{}{
  19. diveTag: {},
  20. structOnlyTag: {},
  21. omitempty: {},
  22. skipValidationTag: {},
  23. utf8HexComma: {},
  24. utf8Pipe: {},
  25. noStructLevelTag: {},
  26. requiredTag: {},
  27. }
  28. // BakedInAliasValidators is a default mapping of a single validation tag that
  29. // defines a common or complex set of validation(s) to simplify
  30. // adding validation to structs.
  31. bakedInAliases = map[string]string{
  32. "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
  33. }
  34. // BakedInValidators is the default map of ValidationFunc
  35. // you can add, remove or even replace items to suite your needs,
  36. // or even disregard and use your own map if so desired.
  37. bakedInValidators = map[string]Func{
  38. "required": hasValue,
  39. "len": hasLengthOf,
  40. "min": hasMinOf,
  41. "max": hasMaxOf,
  42. "eq": isEq,
  43. "ne": isNe,
  44. "lt": isLt,
  45. "lte": isLte,
  46. "gt": isGt,
  47. "gte": isGte,
  48. "eqfield": isEqField,
  49. "eqcsfield": isEqCrossStructField,
  50. "necsfield": isNeCrossStructField,
  51. "gtcsfield": isGtCrossStructField,
  52. "gtecsfield": isGteCrossStructField,
  53. "ltcsfield": isLtCrossStructField,
  54. "ltecsfield": isLteCrossStructField,
  55. "nefield": isNeField,
  56. "gtefield": isGteField,
  57. "gtfield": isGtField,
  58. "ltefield": isLteField,
  59. "ltfield": isLtField,
  60. "alpha": isAlpha,
  61. "alphanum": isAlphanum,
  62. "alphaunicode": isAlphaUnicode,
  63. "alphanumunicode": isAlphanumUnicode,
  64. "numeric": isNumeric,
  65. "number": isNumber,
  66. "hexadecimal": isHexadecimal,
  67. "hexcolor": isHEXColor,
  68. "rgb": isRGB,
  69. "rgba": isRGBA,
  70. "hsl": isHSL,
  71. "hsla": isHSLA,
  72. "email": isEmail,
  73. "url": isURL,
  74. "uri": isURI,
  75. "base64": isBase64,
  76. "contains": contains,
  77. "containsany": containsAny,
  78. "containsrune": containsRune,
  79. "excludes": excludes,
  80. "excludesall": excludesAll,
  81. "excludesrune": excludesRune,
  82. "isbn": isISBN,
  83. "isbn10": isISBN10,
  84. "isbn13": isISBN13,
  85. "uuid": isUUID,
  86. "uuid3": isUUID3,
  87. "uuid4": isUUID4,
  88. "uuid5": isUUID5,
  89. "ascii": isASCII,
  90. "printascii": isPrintableASCII,
  91. "multibyte": hasMultiByteCharacter,
  92. "datauri": isDataURI,
  93. "latitude": isLatitude,
  94. "longitude": isLongitude,
  95. "ssn": isSSN,
  96. "ipv4": isIPv4,
  97. "ipv6": isIPv6,
  98. "ip": isIP,
  99. "cidrv4": isCIDRv4,
  100. "cidrv6": isCIDRv6,
  101. "cidr": isCIDR,
  102. "tcp4_addr": isTCP4AddrResolvable,
  103. "tcp6_addr": isTCP6AddrResolvable,
  104. "tcp_addr": isTCPAddrResolvable,
  105. "udp4_addr": isUDP4AddrResolvable,
  106. "udp6_addr": isUDP6AddrResolvable,
  107. "udp_addr": isUDPAddrResolvable,
  108. "ip4_addr": isIP4AddrResolvable,
  109. "ip6_addr": isIP6AddrResolvable,
  110. "ip_addr": isIPAddrResolvable,
  111. "unix_addr": isUnixAddrResolvable,
  112. "mac": isMAC,
  113. }
  114. )
  115. // IsMAC is the validation function for validating if the field's value is a valid MAC address.
  116. func isMAC(fl FieldLevel) bool {
  117. _, err := net.ParseMAC(fl.Field().String())
  118. return err == nil
  119. }
  120. // IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
  121. func isCIDRv4(fl FieldLevel) bool {
  122. ip, _, err := net.ParseCIDR(fl.Field().String())
  123. return err == nil && ip.To4() != nil
  124. }
  125. // IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
  126. func isCIDRv6(fl FieldLevel) bool {
  127. ip, _, err := net.ParseCIDR(fl.Field().String())
  128. return err == nil && ip.To4() == nil
  129. }
  130. // IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
  131. func isCIDR(fl FieldLevel) bool {
  132. _, _, err := net.ParseCIDR(fl.Field().String())
  133. return err == nil
  134. }
  135. // IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
  136. func isIPv4(fl FieldLevel) bool {
  137. ip := net.ParseIP(fl.Field().String())
  138. return ip != nil && ip.To4() != nil
  139. }
  140. // IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
  141. func isIPv6(fl FieldLevel) bool {
  142. ip := net.ParseIP(fl.Field().String())
  143. return ip != nil && ip.To4() == nil
  144. }
  145. // IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
  146. func isIP(fl FieldLevel) bool {
  147. ip := net.ParseIP(fl.Field().String())
  148. return ip != nil
  149. }
  150. // IsSSN is the validation function for validating if the field's value is a valid SSN.
  151. func isSSN(fl FieldLevel) bool {
  152. field := fl.Field()
  153. if field.Len() != 11 {
  154. return false
  155. }
  156. return sSNRegex.MatchString(field.String())
  157. }
  158. // IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
  159. func isLongitude(fl FieldLevel) bool {
  160. return longitudeRegex.MatchString(fl.Field().String())
  161. }
  162. // IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
  163. func isLatitude(fl FieldLevel) bool {
  164. return latitudeRegex.MatchString(fl.Field().String())
  165. }
  166. // IsDataURI is the validation function for validating if the field's value is a valid data URI.
  167. func isDataURI(fl FieldLevel) bool {
  168. uri := strings.SplitN(fl.Field().String(), ",", 2)
  169. if len(uri) != 2 {
  170. return false
  171. }
  172. if !dataURIRegex.MatchString(uri[0]) {
  173. return false
  174. }
  175. return base64Regex.MatchString(uri[1])
  176. }
  177. // HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
  178. func hasMultiByteCharacter(fl FieldLevel) bool {
  179. field := fl.Field()
  180. if field.Len() == 0 {
  181. return true
  182. }
  183. return multibyteRegex.MatchString(field.String())
  184. }
  185. // IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
  186. func isPrintableASCII(fl FieldLevel) bool {
  187. return printableASCIIRegex.MatchString(fl.Field().String())
  188. }
  189. // IsASCII is the validation function for validating if the field's value is a valid ASCII character.
  190. func isASCII(fl FieldLevel) bool {
  191. return aSCIIRegex.MatchString(fl.Field().String())
  192. }
  193. // IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
  194. func isUUID5(fl FieldLevel) bool {
  195. return uUID5Regex.MatchString(fl.Field().String())
  196. }
  197. // IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
  198. func isUUID4(fl FieldLevel) bool {
  199. return uUID4Regex.MatchString(fl.Field().String())
  200. }
  201. // IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
  202. func isUUID3(fl FieldLevel) bool {
  203. return uUID3Regex.MatchString(fl.Field().String())
  204. }
  205. // IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
  206. func isUUID(fl FieldLevel) bool {
  207. return uUIDRegex.MatchString(fl.Field().String())
  208. }
  209. // IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
  210. func isISBN(fl FieldLevel) bool {
  211. return isISBN10(fl) || isISBN13(fl)
  212. }
  213. // IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
  214. func isISBN13(fl FieldLevel) bool {
  215. s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
  216. if !iSBN13Regex.MatchString(s) {
  217. return false
  218. }
  219. var checksum int32
  220. var i int32
  221. factor := []int32{1, 3}
  222. for i = 0; i < 12; i++ {
  223. checksum += factor[i%2] * int32(s[i]-'0')
  224. }
  225. return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
  226. }
  227. // IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
  228. func isISBN10(fl FieldLevel) bool {
  229. s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
  230. if !iSBN10Regex.MatchString(s) {
  231. return false
  232. }
  233. var checksum int32
  234. var i int32
  235. for i = 0; i < 9; i++ {
  236. checksum += (i + 1) * int32(s[i]-'0')
  237. }
  238. if s[9] == 'X' {
  239. checksum += 10 * 10
  240. } else {
  241. checksum += 10 * int32(s[9]-'0')
  242. }
  243. return checksum%11 == 0
  244. }
  245. // ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
  246. func excludesRune(fl FieldLevel) bool {
  247. return !containsRune(fl)
  248. }
  249. // ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
  250. func excludesAll(fl FieldLevel) bool {
  251. return !containsAny(fl)
  252. }
  253. // Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
  254. func excludes(fl FieldLevel) bool {
  255. return !contains(fl)
  256. }
  257. // ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
  258. func containsRune(fl FieldLevel) bool {
  259. r, _ := utf8.DecodeRuneInString(fl.Param())
  260. return strings.ContainsRune(fl.Field().String(), r)
  261. }
  262. // ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
  263. func containsAny(fl FieldLevel) bool {
  264. return strings.ContainsAny(fl.Field().String(), fl.Param())
  265. }
  266. // Contains is the validation function for validating that the field's value contains the text specified within the param.
  267. func contains(fl FieldLevel) bool {
  268. return strings.Contains(fl.Field().String(), fl.Param())
  269. }
  270. // IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value.
  271. func isNeField(fl FieldLevel) bool {
  272. field := fl.Field()
  273. kind := field.Kind()
  274. currentField, currentKind, ok := fl.GetStructFieldOK()
  275. if !ok || currentKind != kind {
  276. return true
  277. }
  278. switch kind {
  279. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  280. return field.Int() != currentField.Int()
  281. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  282. return field.Uint() != currentField.Uint()
  283. case reflect.Float32, reflect.Float64:
  284. return field.Float() != currentField.Float()
  285. case reflect.Slice, reflect.Map, reflect.Array:
  286. return int64(field.Len()) != int64(currentField.Len())
  287. case reflect.Struct:
  288. fieldType := field.Type()
  289. // Not Same underlying type i.e. struct and time
  290. if fieldType != currentField.Type() {
  291. return true
  292. }
  293. if fieldType == timeType {
  294. t := currentField.Interface().(time.Time)
  295. fieldTime := field.Interface().(time.Time)
  296. return !fieldTime.Equal(t)
  297. }
  298. }
  299. // default reflect.String:
  300. return field.String() != currentField.String()
  301. }
  302. // IsNe is the validation function for validating that the field's value does not equal the provided param value.
  303. func isNe(fl FieldLevel) bool {
  304. return !isEq(fl)
  305. }
  306. // IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value.
  307. func isLteCrossStructField(fl FieldLevel) bool {
  308. field := fl.Field()
  309. kind := field.Kind()
  310. topField, topKind, ok := fl.GetStructFieldOK()
  311. if !ok || topKind != kind {
  312. return false
  313. }
  314. switch kind {
  315. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  316. return field.Int() <= topField.Int()
  317. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  318. return field.Uint() <= topField.Uint()
  319. case reflect.Float32, reflect.Float64:
  320. return field.Float() <= topField.Float()
  321. case reflect.Slice, reflect.Map, reflect.Array:
  322. return int64(field.Len()) <= int64(topField.Len())
  323. case reflect.Struct:
  324. fieldType := field.Type()
  325. // Not Same underlying type i.e. struct and time
  326. if fieldType != topField.Type() {
  327. return false
  328. }
  329. if fieldType == timeType {
  330. fieldTime := field.Interface().(time.Time)
  331. topTime := topField.Interface().(time.Time)
  332. return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
  333. }
  334. }
  335. // default reflect.String:
  336. return field.String() <= topField.String()
  337. }
  338. // IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value.
  339. // NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
  340. func isLtCrossStructField(fl FieldLevel) bool {
  341. field := fl.Field()
  342. kind := field.Kind()
  343. topField, topKind, ok := fl.GetStructFieldOK()
  344. if !ok || topKind != kind {
  345. return false
  346. }
  347. switch kind {
  348. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  349. return field.Int() < topField.Int()
  350. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  351. return field.Uint() < topField.Uint()
  352. case reflect.Float32, reflect.Float64:
  353. return field.Float() < topField.Float()
  354. case reflect.Slice, reflect.Map, reflect.Array:
  355. return int64(field.Len()) < int64(topField.Len())
  356. case reflect.Struct:
  357. fieldType := field.Type()
  358. // Not Same underlying type i.e. struct and time
  359. if fieldType != topField.Type() {
  360. return false
  361. }
  362. if fieldType == timeType {
  363. fieldTime := field.Interface().(time.Time)
  364. topTime := topField.Interface().(time.Time)
  365. return fieldTime.Before(topTime)
  366. }
  367. }
  368. // default reflect.String:
  369. return field.String() < topField.String()
  370. }
  371. // IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value.
  372. func isGteCrossStructField(fl FieldLevel) bool {
  373. field := fl.Field()
  374. kind := field.Kind()
  375. topField, topKind, ok := fl.GetStructFieldOK()
  376. if !ok || topKind != kind {
  377. return false
  378. }
  379. switch kind {
  380. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  381. return field.Int() >= topField.Int()
  382. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  383. return field.Uint() >= topField.Uint()
  384. case reflect.Float32, reflect.Float64:
  385. return field.Float() >= topField.Float()
  386. case reflect.Slice, reflect.Map, reflect.Array:
  387. return int64(field.Len()) >= int64(topField.Len())
  388. case reflect.Struct:
  389. fieldType := field.Type()
  390. // Not Same underlying type i.e. struct and time
  391. if fieldType != topField.Type() {
  392. return false
  393. }
  394. if fieldType == timeType {
  395. fieldTime := field.Interface().(time.Time)
  396. topTime := topField.Interface().(time.Time)
  397. return fieldTime.After(topTime) || fieldTime.Equal(topTime)
  398. }
  399. }
  400. // default reflect.String:
  401. return field.String() >= topField.String()
  402. }
  403. // IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value.
  404. func isGtCrossStructField(fl FieldLevel) bool {
  405. field := fl.Field()
  406. kind := field.Kind()
  407. topField, topKind, ok := fl.GetStructFieldOK()
  408. if !ok || topKind != kind {
  409. return false
  410. }
  411. switch kind {
  412. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  413. return field.Int() > topField.Int()
  414. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  415. return field.Uint() > topField.Uint()
  416. case reflect.Float32, reflect.Float64:
  417. return field.Float() > topField.Float()
  418. case reflect.Slice, reflect.Map, reflect.Array:
  419. return int64(field.Len()) > int64(topField.Len())
  420. case reflect.Struct:
  421. fieldType := field.Type()
  422. // Not Same underlying type i.e. struct and time
  423. if fieldType != topField.Type() {
  424. return false
  425. }
  426. if fieldType == timeType {
  427. fieldTime := field.Interface().(time.Time)
  428. topTime := topField.Interface().(time.Time)
  429. return fieldTime.After(topTime)
  430. }
  431. }
  432. // default reflect.String:
  433. return field.String() > topField.String()
  434. }
  435. // IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value.
  436. func isNeCrossStructField(fl FieldLevel) bool {
  437. field := fl.Field()
  438. kind := field.Kind()
  439. topField, currentKind, ok := fl.GetStructFieldOK()
  440. if !ok || currentKind != kind {
  441. return true
  442. }
  443. switch kind {
  444. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  445. return topField.Int() != field.Int()
  446. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  447. return topField.Uint() != field.Uint()
  448. case reflect.Float32, reflect.Float64:
  449. return topField.Float() != field.Float()
  450. case reflect.Slice, reflect.Map, reflect.Array:
  451. return int64(topField.Len()) != int64(field.Len())
  452. case reflect.Struct:
  453. fieldType := field.Type()
  454. // Not Same underlying type i.e. struct and time
  455. if fieldType != topField.Type() {
  456. return true
  457. }
  458. if fieldType == timeType {
  459. t := field.Interface().(time.Time)
  460. fieldTime := topField.Interface().(time.Time)
  461. return !fieldTime.Equal(t)
  462. }
  463. }
  464. // default reflect.String:
  465. return topField.String() != field.String()
  466. }
  467. // IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value.
  468. func isEqCrossStructField(fl FieldLevel) bool {
  469. field := fl.Field()
  470. kind := field.Kind()
  471. topField, topKind, ok := fl.GetStructFieldOK()
  472. if !ok || topKind != kind {
  473. return false
  474. }
  475. switch kind {
  476. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  477. return topField.Int() == field.Int()
  478. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  479. return topField.Uint() == field.Uint()
  480. case reflect.Float32, reflect.Float64:
  481. return topField.Float() == field.Float()
  482. case reflect.Slice, reflect.Map, reflect.Array:
  483. return int64(topField.Len()) == int64(field.Len())
  484. case reflect.Struct:
  485. fieldType := field.Type()
  486. // Not Same underlying type i.e. struct and time
  487. if fieldType != topField.Type() {
  488. return false
  489. }
  490. if fieldType == timeType {
  491. t := field.Interface().(time.Time)
  492. fieldTime := topField.Interface().(time.Time)
  493. return fieldTime.Equal(t)
  494. }
  495. }
  496. // default reflect.String:
  497. return topField.String() == field.String()
  498. }
  499. // IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
  500. func isEqField(fl FieldLevel) bool {
  501. field := fl.Field()
  502. kind := field.Kind()
  503. currentField, currentKind, ok := fl.GetStructFieldOK()
  504. if !ok || currentKind != kind {
  505. return false
  506. }
  507. switch kind {
  508. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  509. return field.Int() == currentField.Int()
  510. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  511. return field.Uint() == currentField.Uint()
  512. case reflect.Float32, reflect.Float64:
  513. return field.Float() == currentField.Float()
  514. case reflect.Slice, reflect.Map, reflect.Array:
  515. return int64(field.Len()) == int64(currentField.Len())
  516. case reflect.Struct:
  517. fieldType := field.Type()
  518. // Not Same underlying type i.e. struct and time
  519. if fieldType != currentField.Type() {
  520. return false
  521. }
  522. if fieldType == timeType {
  523. t := currentField.Interface().(time.Time)
  524. fieldTime := field.Interface().(time.Time)
  525. return fieldTime.Equal(t)
  526. }
  527. }
  528. // default reflect.String:
  529. return field.String() == currentField.String()
  530. }
  531. // IsEq is the validation function for validating if the current field's value is equal to the param's value.
  532. func isEq(fl FieldLevel) bool {
  533. field := fl.Field()
  534. param := fl.Param()
  535. switch field.Kind() {
  536. case reflect.String:
  537. return field.String() == param
  538. case reflect.Slice, reflect.Map, reflect.Array:
  539. p := asInt(param)
  540. return int64(field.Len()) == p
  541. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  542. p := asInt(param)
  543. return field.Int() == p
  544. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  545. p := asUint(param)
  546. return field.Uint() == p
  547. case reflect.Float32, reflect.Float64:
  548. p := asFloat(param)
  549. return field.Float() == p
  550. }
  551. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  552. }
  553. // IsBase64 is the validation function for validating if the current field's value is a valid base 64.
  554. func isBase64(fl FieldLevel) bool {
  555. return base64Regex.MatchString(fl.Field().String())
  556. }
  557. // IsURI is the validation function for validating if the current field's value is a valid URI.
  558. func isURI(fl FieldLevel) bool {
  559. field := fl.Field()
  560. switch field.Kind() {
  561. case reflect.String:
  562. s := field.String()
  563. // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
  564. // emulate browser and strip the '#' suffix prior to validation. see issue-#237
  565. if i := strings.Index(s, "#"); i > -1 {
  566. s = s[:i]
  567. }
  568. if len(s) == 0 {
  569. return false
  570. }
  571. _, err := url.ParseRequestURI(s)
  572. return err == nil
  573. }
  574. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  575. }
  576. // IsURL is the validation function for validating if the current field's value is a valid URL.
  577. func isURL(fl FieldLevel) bool {
  578. field := fl.Field()
  579. switch field.Kind() {
  580. case reflect.String:
  581. var i int
  582. s := field.String()
  583. // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
  584. // emulate browser and strip the '#' suffix prior to validation. see issue-#237
  585. if i = strings.Index(s, "#"); i > -1 {
  586. s = s[:i]
  587. }
  588. if len(s) == 0 {
  589. return false
  590. }
  591. url, err := url.ParseRequestURI(s)
  592. if err != nil || url.Scheme == "" {
  593. return false
  594. }
  595. return err == nil
  596. }
  597. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  598. }
  599. // IsEmail is the validation function for validating if the current field's value is a valid email address.
  600. func isEmail(fl FieldLevel) bool {
  601. return emailRegex.MatchString(fl.Field().String())
  602. }
  603. // IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
  604. func isHSLA(fl FieldLevel) bool {
  605. return hslaRegex.MatchString(fl.Field().String())
  606. }
  607. // IsHSL is the validation function for validating if the current field's value is a valid HSL color.
  608. func isHSL(fl FieldLevel) bool {
  609. return hslRegex.MatchString(fl.Field().String())
  610. }
  611. // IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
  612. func isRGBA(fl FieldLevel) bool {
  613. return rgbaRegex.MatchString(fl.Field().String())
  614. }
  615. // IsRGB is the validation function for validating if the current field's value is a valid RGB color.
  616. func isRGB(fl FieldLevel) bool {
  617. return rgbRegex.MatchString(fl.Field().String())
  618. }
  619. // IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
  620. func isHEXColor(fl FieldLevel) bool {
  621. return hexcolorRegex.MatchString(fl.Field().String())
  622. }
  623. // IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
  624. func isHexadecimal(fl FieldLevel) bool {
  625. return hexadecimalRegex.MatchString(fl.Field().String())
  626. }
  627. // IsNumber is the validation function for validating if the current field's value is a valid number.
  628. func isNumber(fl FieldLevel) bool {
  629. return numberRegex.MatchString(fl.Field().String())
  630. }
  631. // IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
  632. func isNumeric(fl FieldLevel) bool {
  633. return numericRegex.MatchString(fl.Field().String())
  634. }
  635. // IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
  636. func isAlphanum(fl FieldLevel) bool {
  637. return alphaNumericRegex.MatchString(fl.Field().String())
  638. }
  639. // IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
  640. func isAlpha(fl FieldLevel) bool {
  641. return alphaRegex.MatchString(fl.Field().String())
  642. }
  643. // IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
  644. func isAlphanumUnicode(fl FieldLevel) bool {
  645. return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
  646. }
  647. // IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
  648. func isAlphaUnicode(fl FieldLevel) bool {
  649. return alphaUnicodeRegex.MatchString(fl.Field().String())
  650. }
  651. // HasValue is the validation function for validating if the current field's value is not the default static value.
  652. func hasValue(fl FieldLevel) bool {
  653. field := fl.Field()
  654. switch field.Kind() {
  655. case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
  656. return !field.IsNil()
  657. default:
  658. if fl.(*validate).fldIsPointer && field.Interface() != nil {
  659. return true
  660. }
  661. return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
  662. }
  663. }
  664. // IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
  665. func isGteField(fl FieldLevel) bool {
  666. field := fl.Field()
  667. kind := field.Kind()
  668. currentField, currentKind, ok := fl.GetStructFieldOK()
  669. if !ok || currentKind != kind {
  670. return false
  671. }
  672. switch kind {
  673. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  674. return field.Int() >= currentField.Int()
  675. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  676. return field.Uint() >= currentField.Uint()
  677. case reflect.Float32, reflect.Float64:
  678. return field.Float() >= currentField.Float()
  679. case reflect.Struct:
  680. fieldType := field.Type()
  681. // Not Same underlying type i.e. struct and time
  682. if fieldType != currentField.Type() {
  683. return false
  684. }
  685. if fieldType == timeType {
  686. t := currentField.Interface().(time.Time)
  687. fieldTime := field.Interface().(time.Time)
  688. return fieldTime.After(t) || fieldTime.Equal(t)
  689. }
  690. }
  691. // default reflect.String
  692. return len(field.String()) >= len(currentField.String())
  693. }
  694. // IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
  695. func isGtField(fl FieldLevel) bool {
  696. field := fl.Field()
  697. kind := field.Kind()
  698. currentField, currentKind, ok := fl.GetStructFieldOK()
  699. if !ok || currentKind != kind {
  700. return false
  701. }
  702. switch kind {
  703. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  704. return field.Int() > currentField.Int()
  705. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  706. return field.Uint() > currentField.Uint()
  707. case reflect.Float32, reflect.Float64:
  708. return field.Float() > currentField.Float()
  709. case reflect.Struct:
  710. fieldType := field.Type()
  711. // Not Same underlying type i.e. struct and time
  712. if fieldType != currentField.Type() {
  713. return false
  714. }
  715. if fieldType == timeType {
  716. t := currentField.Interface().(time.Time)
  717. fieldTime := field.Interface().(time.Time)
  718. return fieldTime.After(t)
  719. }
  720. }
  721. // default reflect.String
  722. return len(field.String()) > len(currentField.String())
  723. }
  724. // IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
  725. func isGte(fl FieldLevel) bool {
  726. field := fl.Field()
  727. param := fl.Param()
  728. switch field.Kind() {
  729. case reflect.String:
  730. p := asInt(param)
  731. return int64(utf8.RuneCountInString(field.String())) >= p
  732. case reflect.Slice, reflect.Map, reflect.Array:
  733. p := asInt(param)
  734. return int64(field.Len()) >= p
  735. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  736. p := asInt(param)
  737. return field.Int() >= p
  738. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  739. p := asUint(param)
  740. return field.Uint() >= p
  741. case reflect.Float32, reflect.Float64:
  742. p := asFloat(param)
  743. return field.Float() >= p
  744. case reflect.Struct:
  745. if field.Type() == timeType {
  746. now := time.Now().UTC()
  747. t := field.Interface().(time.Time)
  748. return t.After(now) || t.Equal(now)
  749. }
  750. }
  751. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  752. }
  753. // IsGt is the validation function for validating if the current field's value is greater than the param's value.
  754. func isGt(fl FieldLevel) bool {
  755. field := fl.Field()
  756. param := fl.Param()
  757. switch field.Kind() {
  758. case reflect.String:
  759. p := asInt(param)
  760. return int64(utf8.RuneCountInString(field.String())) > p
  761. case reflect.Slice, reflect.Map, reflect.Array:
  762. p := asInt(param)
  763. return int64(field.Len()) > p
  764. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  765. p := asInt(param)
  766. return field.Int() > p
  767. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  768. p := asUint(param)
  769. return field.Uint() > p
  770. case reflect.Float32, reflect.Float64:
  771. p := asFloat(param)
  772. return field.Float() > p
  773. case reflect.Struct:
  774. if field.Type() == timeType {
  775. return field.Interface().(time.Time).After(time.Now().UTC())
  776. }
  777. }
  778. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  779. }
  780. // HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
  781. func hasLengthOf(fl FieldLevel) bool {
  782. field := fl.Field()
  783. param := fl.Param()
  784. switch field.Kind() {
  785. case reflect.String:
  786. p := asInt(param)
  787. return int64(utf8.RuneCountInString(field.String())) == p
  788. case reflect.Slice, reflect.Map, reflect.Array:
  789. p := asInt(param)
  790. return int64(field.Len()) == p
  791. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  792. p := asInt(param)
  793. return field.Int() == p
  794. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  795. p := asUint(param)
  796. return field.Uint() == p
  797. case reflect.Float32, reflect.Float64:
  798. p := asFloat(param)
  799. return field.Float() == p
  800. }
  801. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  802. }
  803. // HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
  804. func hasMinOf(fl FieldLevel) bool {
  805. return isGte(fl)
  806. }
  807. // IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value.
  808. func isLteField(fl FieldLevel) bool {
  809. field := fl.Field()
  810. kind := field.Kind()
  811. currentField, currentKind, ok := fl.GetStructFieldOK()
  812. if !ok || currentKind != kind {
  813. return false
  814. }
  815. switch kind {
  816. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  817. return field.Int() <= currentField.Int()
  818. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  819. return field.Uint() <= currentField.Uint()
  820. case reflect.Float32, reflect.Float64:
  821. return field.Float() <= currentField.Float()
  822. case reflect.Struct:
  823. fieldType := field.Type()
  824. // Not Same underlying type i.e. struct and time
  825. if fieldType != currentField.Type() {
  826. return false
  827. }
  828. if fieldType == timeType {
  829. t := currentField.Interface().(time.Time)
  830. fieldTime := field.Interface().(time.Time)
  831. return fieldTime.Before(t) || fieldTime.Equal(t)
  832. }
  833. }
  834. // default reflect.String
  835. return len(field.String()) <= len(currentField.String())
  836. }
  837. // IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
  838. func isLtField(fl FieldLevel) bool {
  839. field := fl.Field()
  840. kind := field.Kind()
  841. currentField, currentKind, ok := fl.GetStructFieldOK()
  842. if !ok || currentKind != kind {
  843. return false
  844. }
  845. switch kind {
  846. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  847. return field.Int() < currentField.Int()
  848. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  849. return field.Uint() < currentField.Uint()
  850. case reflect.Float32, reflect.Float64:
  851. return field.Float() < currentField.Float()
  852. case reflect.Struct:
  853. fieldType := field.Type()
  854. // Not Same underlying type i.e. struct and time
  855. if fieldType != currentField.Type() {
  856. return false
  857. }
  858. if fieldType == timeType {
  859. t := currentField.Interface().(time.Time)
  860. fieldTime := field.Interface().(time.Time)
  861. return fieldTime.Before(t)
  862. }
  863. }
  864. // default reflect.String
  865. return len(field.String()) < len(currentField.String())
  866. }
  867. // IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
  868. func isLte(fl FieldLevel) bool {
  869. field := fl.Field()
  870. param := fl.Param()
  871. switch field.Kind() {
  872. case reflect.String:
  873. p := asInt(param)
  874. return int64(utf8.RuneCountInString(field.String())) <= p
  875. case reflect.Slice, reflect.Map, reflect.Array:
  876. p := asInt(param)
  877. return int64(field.Len()) <= p
  878. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  879. p := asInt(param)
  880. return field.Int() <= p
  881. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  882. p := asUint(param)
  883. return field.Uint() <= p
  884. case reflect.Float32, reflect.Float64:
  885. p := asFloat(param)
  886. return field.Float() <= p
  887. case reflect.Struct:
  888. if field.Type() == timeType {
  889. now := time.Now().UTC()
  890. t := field.Interface().(time.Time)
  891. return t.Before(now) || t.Equal(now)
  892. }
  893. }
  894. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  895. }
  896. // IsLt is the validation function for validating if the current field's value is less than the param's value.
  897. func isLt(fl FieldLevel) bool {
  898. field := fl.Field()
  899. param := fl.Param()
  900. switch field.Kind() {
  901. case reflect.String:
  902. p := asInt(param)
  903. return int64(utf8.RuneCountInString(field.String())) < p
  904. case reflect.Slice, reflect.Map, reflect.Array:
  905. p := asInt(param)
  906. return int64(field.Len()) < p
  907. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  908. p := asInt(param)
  909. return field.Int() < p
  910. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  911. p := asUint(param)
  912. return field.Uint() < p
  913. case reflect.Float32, reflect.Float64:
  914. p := asFloat(param)
  915. return field.Float() < p
  916. case reflect.Struct:
  917. if field.Type() == timeType {
  918. return field.Interface().(time.Time).Before(time.Now().UTC())
  919. }
  920. }
  921. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  922. }
  923. // HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
  924. func hasMaxOf(fl FieldLevel) bool {
  925. return isLte(fl)
  926. }
  927. // IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
  928. func isTCP4AddrResolvable(fl FieldLevel) bool {
  929. if !isIP4Addr(fl) {
  930. return false
  931. }
  932. _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
  933. return err == nil
  934. }
  935. // IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
  936. func isTCP6AddrResolvable(fl FieldLevel) bool {
  937. if !isIP6Addr(fl) {
  938. return false
  939. }
  940. _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
  941. return err == nil
  942. }
  943. // IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
  944. func isTCPAddrResolvable(fl FieldLevel) bool {
  945. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  946. return false
  947. }
  948. _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
  949. return err == nil
  950. }
  951. // IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
  952. func isUDP4AddrResolvable(fl FieldLevel) bool {
  953. if !isIP4Addr(fl) {
  954. return false
  955. }
  956. _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
  957. return err == nil
  958. }
  959. // IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
  960. func isUDP6AddrResolvable(fl FieldLevel) bool {
  961. if !isIP6Addr(fl) {
  962. return false
  963. }
  964. _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
  965. return err == nil
  966. }
  967. // IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
  968. func isUDPAddrResolvable(fl FieldLevel) bool {
  969. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  970. return false
  971. }
  972. _, err := net.ResolveUDPAddr("udp", fl.Field().String())
  973. return err == nil
  974. }
  975. // IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
  976. func isIP4AddrResolvable(fl FieldLevel) bool {
  977. if !isIPv4(fl) {
  978. return false
  979. }
  980. _, err := net.ResolveIPAddr("ip4", fl.Field().String())
  981. return err == nil
  982. }
  983. // IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
  984. func isIP6AddrResolvable(fl FieldLevel) bool {
  985. if !isIPv6(fl) {
  986. return false
  987. }
  988. _, err := net.ResolveIPAddr("ip6", fl.Field().String())
  989. return err == nil
  990. }
  991. // IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
  992. func isIPAddrResolvable(fl FieldLevel) bool {
  993. if !isIP(fl) {
  994. return false
  995. }
  996. _, err := net.ResolveIPAddr("ip", fl.Field().String())
  997. return err == nil
  998. }
  999. // IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
  1000. func isUnixAddrResolvable(fl FieldLevel) bool {
  1001. _, err := net.ResolveUnixAddr("unix", fl.Field().String())
  1002. return err == nil
  1003. }
  1004. func isIP4Addr(fl FieldLevel) bool {
  1005. val := fl.Field().String()
  1006. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1007. val = val[0:idx]
  1008. }
  1009. ip := net.ParseIP(val)
  1010. return ip != nil && ip.To4() != nil
  1011. }
  1012. func isIP6Addr(fl FieldLevel) bool {
  1013. val := fl.Field().String()
  1014. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1015. if idx != 0 && val[idx-1:idx] == "]" {
  1016. val = val[1 : idx-1]
  1017. }
  1018. }
  1019. ip := net.ParseIP(val)
  1020. return ip != nil && ip.To4() == nil
  1021. }