baked_in.go 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999
  1. package validator
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/sha256"
  6. "fmt"
  7. "net"
  8. "net/url"
  9. "os"
  10. "reflect"
  11. "strconv"
  12. "strings"
  13. "sync"
  14. "time"
  15. "unicode/utf8"
  16. urn "github.com/leodido/go-urn"
  17. )
  18. // Func accepts a FieldLevel interface for all validation needs. The return
  19. // value should be true when validation succeeds.
  20. type Func func(fl FieldLevel) bool
  21. // FuncCtx accepts a context.Context and FieldLevel interface for all
  22. // validation needs. The return value should be true when validation succeeds.
  23. type FuncCtx func(ctx context.Context, fl FieldLevel) bool
  24. // wrapFunc wraps noramal Func makes it compatible with FuncCtx
  25. func wrapFunc(fn Func) FuncCtx {
  26. if fn == nil {
  27. return nil // be sure not to wrap a bad function.
  28. }
  29. return func(ctx context.Context, fl FieldLevel) bool {
  30. return fn(fl)
  31. }
  32. }
  33. var (
  34. restrictedTags = map[string]struct{}{
  35. diveTag: {},
  36. keysTag: {},
  37. endKeysTag: {},
  38. structOnlyTag: {},
  39. omitempty: {},
  40. skipValidationTag: {},
  41. utf8HexComma: {},
  42. utf8Pipe: {},
  43. noStructLevelTag: {},
  44. requiredTag: {},
  45. isdefault: {},
  46. }
  47. // BakedInAliasValidators is a default mapping of a single validation tag that
  48. // defines a common or complex set of validation(s) to simplify
  49. // adding validation to structs.
  50. bakedInAliases = map[string]string{
  51. "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
  52. }
  53. // BakedInValidators is the default map of ValidationFunc
  54. // you can add, remove or even replace items to suite your needs,
  55. // or even disregard and use your own map if so desired.
  56. bakedInValidators = map[string]Func{
  57. "required": hasValue,
  58. "required_with": requiredWith,
  59. "required_with_all": requiredWithAll,
  60. "required_without": requiredWithout,
  61. "required_without_all": requiredWithoutAll,
  62. "isdefault": isDefault,
  63. "len": hasLengthOf,
  64. "min": hasMinOf,
  65. "max": hasMaxOf,
  66. "eq": isEq,
  67. "ne": isNe,
  68. "lt": isLt,
  69. "lte": isLte,
  70. "gt": isGt,
  71. "gte": isGte,
  72. "eqfield": isEqField,
  73. "eqcsfield": isEqCrossStructField,
  74. "necsfield": isNeCrossStructField,
  75. "gtcsfield": isGtCrossStructField,
  76. "gtecsfield": isGteCrossStructField,
  77. "ltcsfield": isLtCrossStructField,
  78. "ltecsfield": isLteCrossStructField,
  79. "nefield": isNeField,
  80. "gtefield": isGteField,
  81. "gtfield": isGtField,
  82. "ltefield": isLteField,
  83. "ltfield": isLtField,
  84. "fieldcontains": fieldContains,
  85. "fieldexcludes": fieldExcludes,
  86. "alpha": isAlpha,
  87. "alphanum": isAlphanum,
  88. "alphaunicode": isAlphaUnicode,
  89. "alphanumunicode": isAlphanumUnicode,
  90. "numeric": isNumeric,
  91. "number": isNumber,
  92. "hexadecimal": isHexadecimal,
  93. "hexcolor": isHEXColor,
  94. "rgb": isRGB,
  95. "rgba": isRGBA,
  96. "hsl": isHSL,
  97. "hsla": isHSLA,
  98. "email": isEmail,
  99. "url": isURL,
  100. "uri": isURI,
  101. "urn_rfc2141": isUrnRFC2141, // RFC 2141
  102. "file": isFile,
  103. "base64": isBase64,
  104. "base64url": isBase64URL,
  105. "contains": contains,
  106. "containsany": containsAny,
  107. "containsrune": containsRune,
  108. "excludes": excludes,
  109. "excludesall": excludesAll,
  110. "excludesrune": excludesRune,
  111. "startswith": startsWith,
  112. "endswith": endsWith,
  113. "isbn": isISBN,
  114. "isbn10": isISBN10,
  115. "isbn13": isISBN13,
  116. "eth_addr": isEthereumAddress,
  117. "btc_addr": isBitcoinAddress,
  118. "btc_addr_bech32": isBitcoinBech32Address,
  119. "uuid": isUUID,
  120. "uuid3": isUUID3,
  121. "uuid4": isUUID4,
  122. "uuid5": isUUID5,
  123. "uuid_rfc4122": isUUIDRFC4122,
  124. "uuid3_rfc4122": isUUID3RFC4122,
  125. "uuid4_rfc4122": isUUID4RFC4122,
  126. "uuid5_rfc4122": isUUID5RFC4122,
  127. "ascii": isASCII,
  128. "printascii": isPrintableASCII,
  129. "multibyte": hasMultiByteCharacter,
  130. "datauri": isDataURI,
  131. "latitude": isLatitude,
  132. "longitude": isLongitude,
  133. "ssn": isSSN,
  134. "ipv4": isIPv4,
  135. "ipv6": isIPv6,
  136. "ip": isIP,
  137. "cidrv4": isCIDRv4,
  138. "cidrv6": isCIDRv6,
  139. "cidr": isCIDR,
  140. "tcp4_addr": isTCP4AddrResolvable,
  141. "tcp6_addr": isTCP6AddrResolvable,
  142. "tcp_addr": isTCPAddrResolvable,
  143. "udp4_addr": isUDP4AddrResolvable,
  144. "udp6_addr": isUDP6AddrResolvable,
  145. "udp_addr": isUDPAddrResolvable,
  146. "ip4_addr": isIP4AddrResolvable,
  147. "ip6_addr": isIP6AddrResolvable,
  148. "ip_addr": isIPAddrResolvable,
  149. "unix_addr": isUnixAddrResolvable,
  150. "mac": isMAC,
  151. "hostname": isHostnameRFC952, // RFC 952
  152. "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
  153. "fqdn": isFQDN,
  154. "unique": isUnique,
  155. "oneof": isOneOf,
  156. "html": isHTML,
  157. "html_encoded": isHTMLEncoded,
  158. "url_encoded": isURLEncoded,
  159. "dir": isDir,
  160. }
  161. )
  162. var oneofValsCache = map[string][]string{}
  163. var oneofValsCacheRWLock = sync.RWMutex{}
  164. func parseOneOfParam2(s string) []string {
  165. oneofValsCacheRWLock.RLock()
  166. vals, ok := oneofValsCache[s]
  167. oneofValsCacheRWLock.RUnlock()
  168. if !ok {
  169. oneofValsCacheRWLock.Lock()
  170. vals = strings.Fields(s)
  171. oneofValsCache[s] = vals
  172. oneofValsCacheRWLock.Unlock()
  173. }
  174. return vals
  175. }
  176. func isURLEncoded(fl FieldLevel) bool {
  177. return uRLEncodedRegex.MatchString(fl.Field().String())
  178. }
  179. func isHTMLEncoded(fl FieldLevel) bool {
  180. return hTMLEncodedRegex.MatchString(fl.Field().String())
  181. }
  182. func isHTML(fl FieldLevel) bool {
  183. return hTMLRegex.MatchString(fl.Field().String())
  184. }
  185. func isOneOf(fl FieldLevel) bool {
  186. vals := parseOneOfParam2(fl.Param())
  187. field := fl.Field()
  188. var v string
  189. switch field.Kind() {
  190. case reflect.String:
  191. v = field.String()
  192. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  193. v = strconv.FormatInt(field.Int(), 10)
  194. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  195. v = strconv.FormatUint(field.Uint(), 10)
  196. default:
  197. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  198. }
  199. for i := 0; i < len(vals); i++ {
  200. if vals[i] == v {
  201. return true
  202. }
  203. }
  204. return false
  205. }
  206. // isUnique is the validation function for validating if each array|slice|map value is unique
  207. func isUnique(fl FieldLevel) bool {
  208. field := fl.Field()
  209. v := reflect.ValueOf(struct{}{})
  210. switch field.Kind() {
  211. case reflect.Slice, reflect.Array:
  212. m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
  213. for i := 0; i < field.Len(); i++ {
  214. m.SetMapIndex(field.Index(i), v)
  215. }
  216. return field.Len() == m.Len()
  217. case reflect.Map:
  218. m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
  219. for _, k := range field.MapKeys() {
  220. m.SetMapIndex(field.MapIndex(k), v)
  221. }
  222. return field.Len() == m.Len()
  223. default:
  224. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  225. }
  226. }
  227. // IsMAC is the validation function for validating if the field's value is a valid MAC address.
  228. func isMAC(fl FieldLevel) bool {
  229. _, err := net.ParseMAC(fl.Field().String())
  230. return err == nil
  231. }
  232. // IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
  233. func isCIDRv4(fl FieldLevel) bool {
  234. ip, _, err := net.ParseCIDR(fl.Field().String())
  235. return err == nil && ip.To4() != nil
  236. }
  237. // IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
  238. func isCIDRv6(fl FieldLevel) bool {
  239. ip, _, err := net.ParseCIDR(fl.Field().String())
  240. return err == nil && ip.To4() == nil
  241. }
  242. // IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
  243. func isCIDR(fl FieldLevel) bool {
  244. _, _, err := net.ParseCIDR(fl.Field().String())
  245. return err == nil
  246. }
  247. // IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
  248. func isIPv4(fl FieldLevel) bool {
  249. ip := net.ParseIP(fl.Field().String())
  250. return ip != nil && ip.To4() != nil
  251. }
  252. // IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
  253. func isIPv6(fl FieldLevel) bool {
  254. ip := net.ParseIP(fl.Field().String())
  255. return ip != nil && ip.To4() == nil
  256. }
  257. // IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
  258. func isIP(fl FieldLevel) bool {
  259. ip := net.ParseIP(fl.Field().String())
  260. return ip != nil
  261. }
  262. // IsSSN is the validation function for validating if the field's value is a valid SSN.
  263. func isSSN(fl FieldLevel) bool {
  264. field := fl.Field()
  265. if field.Len() != 11 {
  266. return false
  267. }
  268. return sSNRegex.MatchString(field.String())
  269. }
  270. // IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
  271. func isLongitude(fl FieldLevel) bool {
  272. field := fl.Field()
  273. var v string
  274. switch field.Kind() {
  275. case reflect.String:
  276. v = field.String()
  277. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  278. v = strconv.FormatInt(field.Int(), 10)
  279. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  280. v = strconv.FormatUint(field.Uint(), 10)
  281. case reflect.Float32:
  282. v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
  283. case reflect.Float64:
  284. v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
  285. default:
  286. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  287. }
  288. return longitudeRegex.MatchString(v)
  289. }
  290. // IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
  291. func isLatitude(fl FieldLevel) bool {
  292. field := fl.Field()
  293. var v string
  294. switch field.Kind() {
  295. case reflect.String:
  296. v = field.String()
  297. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  298. v = strconv.FormatInt(field.Int(), 10)
  299. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  300. v = strconv.FormatUint(field.Uint(), 10)
  301. case reflect.Float32:
  302. v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
  303. case reflect.Float64:
  304. v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
  305. default:
  306. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  307. }
  308. return latitudeRegex.MatchString(v)
  309. }
  310. // IsDataURI is the validation function for validating if the field's value is a valid data URI.
  311. func isDataURI(fl FieldLevel) bool {
  312. uri := strings.SplitN(fl.Field().String(), ",", 2)
  313. if len(uri) != 2 {
  314. return false
  315. }
  316. if !dataURIRegex.MatchString(uri[0]) {
  317. return false
  318. }
  319. return base64Regex.MatchString(uri[1])
  320. }
  321. // HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
  322. func hasMultiByteCharacter(fl FieldLevel) bool {
  323. field := fl.Field()
  324. if field.Len() == 0 {
  325. return true
  326. }
  327. return multibyteRegex.MatchString(field.String())
  328. }
  329. // IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
  330. func isPrintableASCII(fl FieldLevel) bool {
  331. return printableASCIIRegex.MatchString(fl.Field().String())
  332. }
  333. // IsASCII is the validation function for validating if the field's value is a valid ASCII character.
  334. func isASCII(fl FieldLevel) bool {
  335. return aSCIIRegex.MatchString(fl.Field().String())
  336. }
  337. // IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
  338. func isUUID5(fl FieldLevel) bool {
  339. return uUID5Regex.MatchString(fl.Field().String())
  340. }
  341. // IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
  342. func isUUID4(fl FieldLevel) bool {
  343. return uUID4Regex.MatchString(fl.Field().String())
  344. }
  345. // IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
  346. func isUUID3(fl FieldLevel) bool {
  347. return uUID3Regex.MatchString(fl.Field().String())
  348. }
  349. // IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
  350. func isUUID(fl FieldLevel) bool {
  351. return uUIDRegex.MatchString(fl.Field().String())
  352. }
  353. // IsUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
  354. func isUUID5RFC4122(fl FieldLevel) bool {
  355. return uUID5RFC4122Regex.MatchString(fl.Field().String())
  356. }
  357. // IsUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
  358. func isUUID4RFC4122(fl FieldLevel) bool {
  359. return uUID4RFC4122Regex.MatchString(fl.Field().String())
  360. }
  361. // IsUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
  362. func isUUID3RFC4122(fl FieldLevel) bool {
  363. return uUID3RFC4122Regex.MatchString(fl.Field().String())
  364. }
  365. // IsUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
  366. func isUUIDRFC4122(fl FieldLevel) bool {
  367. return uUIDRFC4122Regex.MatchString(fl.Field().String())
  368. }
  369. // IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
  370. func isISBN(fl FieldLevel) bool {
  371. return isISBN10(fl) || isISBN13(fl)
  372. }
  373. // IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
  374. func isISBN13(fl FieldLevel) bool {
  375. s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
  376. if !iSBN13Regex.MatchString(s) {
  377. return false
  378. }
  379. var checksum int32
  380. var i int32
  381. factor := []int32{1, 3}
  382. for i = 0; i < 12; i++ {
  383. checksum += factor[i%2] * int32(s[i]-'0')
  384. }
  385. return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
  386. }
  387. // IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
  388. func isISBN10(fl FieldLevel) bool {
  389. s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
  390. if !iSBN10Regex.MatchString(s) {
  391. return false
  392. }
  393. var checksum int32
  394. var i int32
  395. for i = 0; i < 9; i++ {
  396. checksum += (i + 1) * int32(s[i]-'0')
  397. }
  398. if s[9] == 'X' {
  399. checksum += 10 * 10
  400. } else {
  401. checksum += 10 * int32(s[9]-'0')
  402. }
  403. return checksum%11 == 0
  404. }
  405. // IsEthereumAddress is the validation function for validating if the field's value is a valid ethereum address based currently only on the format
  406. func isEthereumAddress(fl FieldLevel) bool {
  407. address := fl.Field().String()
  408. if !ethAddressRegex.MatchString(address) {
  409. return false
  410. }
  411. if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
  412. return true
  413. }
  414. // checksum validation is blocked by https://github.com/golang/crypto/pull/28
  415. return true
  416. }
  417. // IsBitcoinAddress is the validation function for validating if the field's value is a valid btc address
  418. func isBitcoinAddress(fl FieldLevel) bool {
  419. address := fl.Field().String()
  420. if !btcAddressRegex.MatchString(address) {
  421. return false
  422. }
  423. alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
  424. decode := [25]byte{}
  425. for _, n := range []byte(address) {
  426. d := bytes.IndexByte(alphabet, n)
  427. for i := 24; i >= 0; i-- {
  428. d += 58 * int(decode[i])
  429. decode[i] = byte(d % 256)
  430. d /= 256
  431. }
  432. }
  433. h := sha256.New()
  434. _, _ = h.Write(decode[:21])
  435. d := h.Sum([]byte{})
  436. h = sha256.New()
  437. _, _ = h.Write(d)
  438. validchecksum := [4]byte{}
  439. computedchecksum := [4]byte{}
  440. copy(computedchecksum[:], h.Sum(d[:0]))
  441. copy(validchecksum[:], decode[21:])
  442. return validchecksum == computedchecksum
  443. }
  444. // IsBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
  445. func isBitcoinBech32Address(fl FieldLevel) bool {
  446. address := fl.Field().String()
  447. if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) {
  448. return false
  449. }
  450. am := len(address) % 8
  451. if am == 0 || am == 3 || am == 5 {
  452. return false
  453. }
  454. address = strings.ToLower(address)
  455. alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
  456. hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc
  457. addr := address[3:]
  458. dp := make([]int, 0, len(addr))
  459. for _, c := range addr {
  460. dp = append(dp, strings.IndexRune(alphabet, c))
  461. }
  462. ver := dp[0]
  463. if ver < 0 || ver > 16 {
  464. return false
  465. }
  466. if ver == 0 {
  467. if len(address) != 42 && len(address) != 62 {
  468. return false
  469. }
  470. }
  471. values := append(hr, dp...)
  472. GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
  473. p := 1
  474. for _, v := range values {
  475. b := p >> 25
  476. p = (p&0x1ffffff)<<5 ^ v
  477. for i := 0; i < 5; i++ {
  478. if (b>>uint(i))&1 == 1 {
  479. p ^= GEN[i]
  480. }
  481. }
  482. }
  483. if p != 1 {
  484. return false
  485. }
  486. b := uint(0)
  487. acc := 0
  488. mv := (1 << 5) - 1
  489. var sw []int
  490. for _, v := range dp[1 : len(dp)-6] {
  491. acc = (acc << 5) | v
  492. b += 5
  493. for b >= 8 {
  494. b -= 8
  495. sw = append(sw, (acc>>b)&mv)
  496. }
  497. }
  498. if len(sw) < 2 || len(sw) > 40 {
  499. return false
  500. }
  501. return true
  502. }
  503. // ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
  504. func excludesRune(fl FieldLevel) bool {
  505. return !containsRune(fl)
  506. }
  507. // ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
  508. func excludesAll(fl FieldLevel) bool {
  509. return !containsAny(fl)
  510. }
  511. // Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
  512. func excludes(fl FieldLevel) bool {
  513. return !contains(fl)
  514. }
  515. // ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
  516. func containsRune(fl FieldLevel) bool {
  517. r, _ := utf8.DecodeRuneInString(fl.Param())
  518. return strings.ContainsRune(fl.Field().String(), r)
  519. }
  520. // ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
  521. func containsAny(fl FieldLevel) bool {
  522. return strings.ContainsAny(fl.Field().String(), fl.Param())
  523. }
  524. // Contains is the validation function for validating that the field's value contains the text specified within the param.
  525. func contains(fl FieldLevel) bool {
  526. return strings.Contains(fl.Field().String(), fl.Param())
  527. }
  528. // StartsWith is the validation function for validating that the field's value starts with the text specified within the param.
  529. func startsWith(fl FieldLevel) bool {
  530. return strings.HasPrefix(fl.Field().String(), fl.Param())
  531. }
  532. // EndsWith is the validation function for validating that the field's value ends with the text specified within the param.
  533. func endsWith(fl FieldLevel) bool {
  534. return strings.HasSuffix(fl.Field().String(), fl.Param())
  535. }
  536. // FieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
  537. func fieldContains(fl FieldLevel) bool {
  538. field := fl.Field()
  539. currentField, _, ok := fl.GetStructFieldOK()
  540. if !ok {
  541. return false
  542. }
  543. return strings.Contains(field.String(), currentField.String())
  544. }
  545. // FieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
  546. func fieldExcludes(fl FieldLevel) bool {
  547. field := fl.Field()
  548. currentField, _, ok := fl.GetStructFieldOK()
  549. if !ok {
  550. return true
  551. }
  552. return !strings.Contains(field.String(), currentField.String())
  553. }
  554. // 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.
  555. func isNeField(fl FieldLevel) bool {
  556. field := fl.Field()
  557. kind := field.Kind()
  558. currentField, currentKind, ok := fl.GetStructFieldOK()
  559. if !ok || currentKind != kind {
  560. return true
  561. }
  562. switch kind {
  563. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  564. return field.Int() != currentField.Int()
  565. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  566. return field.Uint() != currentField.Uint()
  567. case reflect.Float32, reflect.Float64:
  568. return field.Float() != currentField.Float()
  569. case reflect.Slice, reflect.Map, reflect.Array:
  570. return int64(field.Len()) != int64(currentField.Len())
  571. case reflect.Struct:
  572. fieldType := field.Type()
  573. // Not Same underlying type i.e. struct and time
  574. if fieldType != currentField.Type() {
  575. return true
  576. }
  577. if fieldType == timeType {
  578. t := currentField.Interface().(time.Time)
  579. fieldTime := field.Interface().(time.Time)
  580. return !fieldTime.Equal(t)
  581. }
  582. }
  583. // default reflect.String:
  584. return field.String() != currentField.String()
  585. }
  586. // IsNe is the validation function for validating that the field's value does not equal the provided param value.
  587. func isNe(fl FieldLevel) bool {
  588. return !isEq(fl)
  589. }
  590. // 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.
  591. func isLteCrossStructField(fl FieldLevel) bool {
  592. field := fl.Field()
  593. kind := field.Kind()
  594. topField, topKind, ok := fl.GetStructFieldOK()
  595. if !ok || topKind != kind {
  596. return false
  597. }
  598. switch kind {
  599. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  600. return field.Int() <= topField.Int()
  601. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  602. return field.Uint() <= topField.Uint()
  603. case reflect.Float32, reflect.Float64:
  604. return field.Float() <= topField.Float()
  605. case reflect.Slice, reflect.Map, reflect.Array:
  606. return int64(field.Len()) <= int64(topField.Len())
  607. case reflect.Struct:
  608. fieldType := field.Type()
  609. // Not Same underlying type i.e. struct and time
  610. if fieldType != topField.Type() {
  611. return false
  612. }
  613. if fieldType == timeType {
  614. fieldTime := field.Interface().(time.Time)
  615. topTime := topField.Interface().(time.Time)
  616. return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
  617. }
  618. }
  619. // default reflect.String:
  620. return field.String() <= topField.String()
  621. }
  622. // 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.
  623. // NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
  624. func isLtCrossStructField(fl FieldLevel) bool {
  625. field := fl.Field()
  626. kind := field.Kind()
  627. topField, topKind, ok := fl.GetStructFieldOK()
  628. if !ok || topKind != kind {
  629. return false
  630. }
  631. switch kind {
  632. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  633. return field.Int() < topField.Int()
  634. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  635. return field.Uint() < topField.Uint()
  636. case reflect.Float32, reflect.Float64:
  637. return field.Float() < topField.Float()
  638. case reflect.Slice, reflect.Map, reflect.Array:
  639. return int64(field.Len()) < int64(topField.Len())
  640. case reflect.Struct:
  641. fieldType := field.Type()
  642. // Not Same underlying type i.e. struct and time
  643. if fieldType != topField.Type() {
  644. return false
  645. }
  646. if fieldType == timeType {
  647. fieldTime := field.Interface().(time.Time)
  648. topTime := topField.Interface().(time.Time)
  649. return fieldTime.Before(topTime)
  650. }
  651. }
  652. // default reflect.String:
  653. return field.String() < topField.String()
  654. }
  655. // 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.
  656. func isGteCrossStructField(fl FieldLevel) bool {
  657. field := fl.Field()
  658. kind := field.Kind()
  659. topField, topKind, ok := fl.GetStructFieldOK()
  660. if !ok || topKind != kind {
  661. return false
  662. }
  663. switch kind {
  664. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  665. return field.Int() >= topField.Int()
  666. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  667. return field.Uint() >= topField.Uint()
  668. case reflect.Float32, reflect.Float64:
  669. return field.Float() >= topField.Float()
  670. case reflect.Slice, reflect.Map, reflect.Array:
  671. return int64(field.Len()) >= int64(topField.Len())
  672. case reflect.Struct:
  673. fieldType := field.Type()
  674. // Not Same underlying type i.e. struct and time
  675. if fieldType != topField.Type() {
  676. return false
  677. }
  678. if fieldType == timeType {
  679. fieldTime := field.Interface().(time.Time)
  680. topTime := topField.Interface().(time.Time)
  681. return fieldTime.After(topTime) || fieldTime.Equal(topTime)
  682. }
  683. }
  684. // default reflect.String:
  685. return field.String() >= topField.String()
  686. }
  687. // 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.
  688. func isGtCrossStructField(fl FieldLevel) bool {
  689. field := fl.Field()
  690. kind := field.Kind()
  691. topField, topKind, ok := fl.GetStructFieldOK()
  692. if !ok || topKind != kind {
  693. return false
  694. }
  695. switch kind {
  696. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  697. return field.Int() > topField.Int()
  698. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  699. return field.Uint() > topField.Uint()
  700. case reflect.Float32, reflect.Float64:
  701. return field.Float() > topField.Float()
  702. case reflect.Slice, reflect.Map, reflect.Array:
  703. return int64(field.Len()) > int64(topField.Len())
  704. case reflect.Struct:
  705. fieldType := field.Type()
  706. // Not Same underlying type i.e. struct and time
  707. if fieldType != topField.Type() {
  708. return false
  709. }
  710. if fieldType == timeType {
  711. fieldTime := field.Interface().(time.Time)
  712. topTime := topField.Interface().(time.Time)
  713. return fieldTime.After(topTime)
  714. }
  715. }
  716. // default reflect.String:
  717. return field.String() > topField.String()
  718. }
  719. // 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.
  720. func isNeCrossStructField(fl FieldLevel) bool {
  721. field := fl.Field()
  722. kind := field.Kind()
  723. topField, currentKind, ok := fl.GetStructFieldOK()
  724. if !ok || currentKind != kind {
  725. return true
  726. }
  727. switch kind {
  728. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  729. return topField.Int() != field.Int()
  730. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  731. return topField.Uint() != field.Uint()
  732. case reflect.Float32, reflect.Float64:
  733. return topField.Float() != field.Float()
  734. case reflect.Slice, reflect.Map, reflect.Array:
  735. return int64(topField.Len()) != int64(field.Len())
  736. case reflect.Struct:
  737. fieldType := field.Type()
  738. // Not Same underlying type i.e. struct and time
  739. if fieldType != topField.Type() {
  740. return true
  741. }
  742. if fieldType == timeType {
  743. t := field.Interface().(time.Time)
  744. fieldTime := topField.Interface().(time.Time)
  745. return !fieldTime.Equal(t)
  746. }
  747. }
  748. // default reflect.String:
  749. return topField.String() != field.String()
  750. }
  751. // 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.
  752. func isEqCrossStructField(fl FieldLevel) bool {
  753. field := fl.Field()
  754. kind := field.Kind()
  755. topField, topKind, ok := fl.GetStructFieldOK()
  756. if !ok || topKind != kind {
  757. return false
  758. }
  759. switch kind {
  760. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  761. return topField.Int() == field.Int()
  762. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  763. return topField.Uint() == field.Uint()
  764. case reflect.Float32, reflect.Float64:
  765. return topField.Float() == field.Float()
  766. case reflect.Slice, reflect.Map, reflect.Array:
  767. return int64(topField.Len()) == int64(field.Len())
  768. case reflect.Struct:
  769. fieldType := field.Type()
  770. // Not Same underlying type i.e. struct and time
  771. if fieldType != topField.Type() {
  772. return false
  773. }
  774. if fieldType == timeType {
  775. t := field.Interface().(time.Time)
  776. fieldTime := topField.Interface().(time.Time)
  777. return fieldTime.Equal(t)
  778. }
  779. }
  780. // default reflect.String:
  781. return topField.String() == field.String()
  782. }
  783. // IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
  784. func isEqField(fl FieldLevel) bool {
  785. field := fl.Field()
  786. kind := field.Kind()
  787. currentField, currentKind, ok := fl.GetStructFieldOK()
  788. if !ok || currentKind != kind {
  789. return false
  790. }
  791. switch kind {
  792. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  793. return field.Int() == currentField.Int()
  794. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  795. return field.Uint() == currentField.Uint()
  796. case reflect.Float32, reflect.Float64:
  797. return field.Float() == currentField.Float()
  798. case reflect.Slice, reflect.Map, reflect.Array:
  799. return int64(field.Len()) == int64(currentField.Len())
  800. case reflect.Struct:
  801. fieldType := field.Type()
  802. // Not Same underlying type i.e. struct and time
  803. if fieldType != currentField.Type() {
  804. return false
  805. }
  806. if fieldType == timeType {
  807. t := currentField.Interface().(time.Time)
  808. fieldTime := field.Interface().(time.Time)
  809. return fieldTime.Equal(t)
  810. }
  811. }
  812. // default reflect.String:
  813. return field.String() == currentField.String()
  814. }
  815. // IsEq is the validation function for validating if the current field's value is equal to the param's value.
  816. func isEq(fl FieldLevel) bool {
  817. field := fl.Field()
  818. param := fl.Param()
  819. switch field.Kind() {
  820. case reflect.String:
  821. return field.String() == param
  822. case reflect.Slice, reflect.Map, reflect.Array:
  823. p := asInt(param)
  824. return int64(field.Len()) == p
  825. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  826. p := asInt(param)
  827. return field.Int() == p
  828. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  829. p := asUint(param)
  830. return field.Uint() == p
  831. case reflect.Float32, reflect.Float64:
  832. p := asFloat(param)
  833. return field.Float() == p
  834. }
  835. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  836. }
  837. // IsBase64 is the validation function for validating if the current field's value is a valid base 64.
  838. func isBase64(fl FieldLevel) bool {
  839. return base64Regex.MatchString(fl.Field().String())
  840. }
  841. // IsBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
  842. func isBase64URL(fl FieldLevel) bool {
  843. return base64URLRegex.MatchString(fl.Field().String())
  844. }
  845. // IsURI is the validation function for validating if the current field's value is a valid URI.
  846. func isURI(fl FieldLevel) bool {
  847. field := fl.Field()
  848. switch field.Kind() {
  849. case reflect.String:
  850. s := field.String()
  851. // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
  852. // emulate browser and strip the '#' suffix prior to validation. see issue-#237
  853. if i := strings.Index(s, "#"); i > -1 {
  854. s = s[:i]
  855. }
  856. if len(s) == 0 {
  857. return false
  858. }
  859. _, err := url.ParseRequestURI(s)
  860. return err == nil
  861. }
  862. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  863. }
  864. // IsURL is the validation function for validating if the current field's value is a valid URL.
  865. func isURL(fl FieldLevel) bool {
  866. field := fl.Field()
  867. switch field.Kind() {
  868. case reflect.String:
  869. var i int
  870. s := field.String()
  871. // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
  872. // emulate browser and strip the '#' suffix prior to validation. see issue-#237
  873. if i = strings.Index(s, "#"); i > -1 {
  874. s = s[:i]
  875. }
  876. if len(s) == 0 {
  877. return false
  878. }
  879. url, err := url.ParseRequestURI(s)
  880. if err != nil || url.Scheme == "" {
  881. return false
  882. }
  883. return err == nil
  884. }
  885. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  886. }
  887. // isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
  888. func isUrnRFC2141(fl FieldLevel) bool {
  889. field := fl.Field()
  890. switch field.Kind() {
  891. case reflect.String:
  892. str := field.String()
  893. _, match := urn.Parse([]byte(str))
  894. return match
  895. }
  896. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  897. }
  898. // IsFile is the validation function for validating if the current field's value is a valid file path.
  899. func isFile(fl FieldLevel) bool {
  900. field := fl.Field()
  901. switch field.Kind() {
  902. case reflect.String:
  903. fileInfo, err := os.Stat(field.String())
  904. if err != nil {
  905. return false
  906. }
  907. return !fileInfo.IsDir()
  908. }
  909. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  910. }
  911. // IsEmail is the validation function for validating if the current field's value is a valid email address.
  912. func isEmail(fl FieldLevel) bool {
  913. return emailRegex.MatchString(fl.Field().String())
  914. }
  915. // IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
  916. func isHSLA(fl FieldLevel) bool {
  917. return hslaRegex.MatchString(fl.Field().String())
  918. }
  919. // IsHSL is the validation function for validating if the current field's value is a valid HSL color.
  920. func isHSL(fl FieldLevel) bool {
  921. return hslRegex.MatchString(fl.Field().String())
  922. }
  923. // IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
  924. func isRGBA(fl FieldLevel) bool {
  925. return rgbaRegex.MatchString(fl.Field().String())
  926. }
  927. // IsRGB is the validation function for validating if the current field's value is a valid RGB color.
  928. func isRGB(fl FieldLevel) bool {
  929. return rgbRegex.MatchString(fl.Field().String())
  930. }
  931. // IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
  932. func isHEXColor(fl FieldLevel) bool {
  933. return hexcolorRegex.MatchString(fl.Field().String())
  934. }
  935. // IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
  936. func isHexadecimal(fl FieldLevel) bool {
  937. return hexadecimalRegex.MatchString(fl.Field().String())
  938. }
  939. // IsNumber is the validation function for validating if the current field's value is a valid number.
  940. func isNumber(fl FieldLevel) bool {
  941. switch fl.Field().Kind() {
  942. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
  943. return true
  944. default:
  945. return numberRegex.MatchString(fl.Field().String())
  946. }
  947. }
  948. // IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
  949. func isNumeric(fl FieldLevel) bool {
  950. switch fl.Field().Kind() {
  951. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
  952. return true
  953. default:
  954. return numericRegex.MatchString(fl.Field().String())
  955. }
  956. }
  957. // IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
  958. func isAlphanum(fl FieldLevel) bool {
  959. return alphaNumericRegex.MatchString(fl.Field().String())
  960. }
  961. // IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
  962. func isAlpha(fl FieldLevel) bool {
  963. return alphaRegex.MatchString(fl.Field().String())
  964. }
  965. // IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
  966. func isAlphanumUnicode(fl FieldLevel) bool {
  967. return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
  968. }
  969. // IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
  970. func isAlphaUnicode(fl FieldLevel) bool {
  971. return alphaUnicodeRegex.MatchString(fl.Field().String())
  972. }
  973. // isDefault is the opposite of required aka hasValue
  974. func isDefault(fl FieldLevel) bool {
  975. return !hasValue(fl)
  976. }
  977. // HasValue is the validation function for validating if the current field's value is not the default static value.
  978. func hasValue(fl FieldLevel) bool {
  979. return requireCheckFieldKind(fl, "")
  980. }
  981. // requireCheckField is a func for check field kind
  982. func requireCheckFieldKind(fl FieldLevel, param string) bool {
  983. field := fl.Field()
  984. if len(param) > 0 {
  985. if fl.Parent().Kind() == reflect.Ptr {
  986. field = fl.Parent().Elem().FieldByName(param)
  987. } else {
  988. field = fl.Parent().FieldByName(param)
  989. }
  990. }
  991. switch field.Kind() {
  992. case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
  993. return !field.IsNil()
  994. default:
  995. if fl.(*validate).fldIsPointer && field.Interface() != nil {
  996. return true
  997. }
  998. return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
  999. }
  1000. }
  1001. // RequiredWith is the validation function
  1002. // The field under validation must be present and not empty only if any of the other specified fields are present.
  1003. func requiredWith(fl FieldLevel) bool {
  1004. params := parseOneOfParam2(fl.Param())
  1005. for _, param := range params {
  1006. if requireCheckFieldKind(fl, param) {
  1007. return requireCheckFieldKind(fl, "")
  1008. }
  1009. }
  1010. return true
  1011. }
  1012. // RequiredWithAll is the validation function
  1013. // The field under validation must be present and not empty only if all of the other specified fields are present.
  1014. func requiredWithAll(fl FieldLevel) bool {
  1015. isValidateCurrentField := true
  1016. params := parseOneOfParam2(fl.Param())
  1017. for _, param := range params {
  1018. if !requireCheckFieldKind(fl, param) {
  1019. isValidateCurrentField = false
  1020. }
  1021. }
  1022. if isValidateCurrentField {
  1023. return requireCheckFieldKind(fl, "")
  1024. }
  1025. return true
  1026. }
  1027. // RequiredWithout is the validation function
  1028. // The field under validation must be present and not empty only when any of the other specified fields are not present.
  1029. func requiredWithout(fl FieldLevel) bool {
  1030. isValidateCurrentField := false
  1031. params := parseOneOfParam2(fl.Param())
  1032. for _, param := range params {
  1033. if requireCheckFieldKind(fl, param) {
  1034. isValidateCurrentField = true
  1035. }
  1036. }
  1037. if !isValidateCurrentField {
  1038. return requireCheckFieldKind(fl, "")
  1039. }
  1040. return true
  1041. }
  1042. // RequiredWithoutAll is the validation function
  1043. // The field under validation must be present and not empty only when all of the other specified fields are not present.
  1044. func requiredWithoutAll(fl FieldLevel) bool {
  1045. isValidateCurrentField := true
  1046. params := parseOneOfParam2(fl.Param())
  1047. for _, param := range params {
  1048. if requireCheckFieldKind(fl, param) {
  1049. isValidateCurrentField = false
  1050. }
  1051. }
  1052. if isValidateCurrentField {
  1053. return requireCheckFieldKind(fl, "")
  1054. }
  1055. return true
  1056. }
  1057. // 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.
  1058. func isGteField(fl FieldLevel) bool {
  1059. field := fl.Field()
  1060. kind := field.Kind()
  1061. currentField, currentKind, ok := fl.GetStructFieldOK()
  1062. if !ok || currentKind != kind {
  1063. return false
  1064. }
  1065. switch kind {
  1066. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1067. return field.Int() >= currentField.Int()
  1068. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1069. return field.Uint() >= currentField.Uint()
  1070. case reflect.Float32, reflect.Float64:
  1071. return field.Float() >= currentField.Float()
  1072. case reflect.Struct:
  1073. fieldType := field.Type()
  1074. // Not Same underlying type i.e. struct and time
  1075. if fieldType != currentField.Type() {
  1076. return false
  1077. }
  1078. if fieldType == timeType {
  1079. t := currentField.Interface().(time.Time)
  1080. fieldTime := field.Interface().(time.Time)
  1081. return fieldTime.After(t) || fieldTime.Equal(t)
  1082. }
  1083. }
  1084. // default reflect.String
  1085. return len(field.String()) >= len(currentField.String())
  1086. }
  1087. // IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
  1088. func isGtField(fl FieldLevel) bool {
  1089. field := fl.Field()
  1090. kind := field.Kind()
  1091. currentField, currentKind, ok := fl.GetStructFieldOK()
  1092. if !ok || currentKind != kind {
  1093. return false
  1094. }
  1095. switch kind {
  1096. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1097. return field.Int() > currentField.Int()
  1098. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1099. return field.Uint() > currentField.Uint()
  1100. case reflect.Float32, reflect.Float64:
  1101. return field.Float() > currentField.Float()
  1102. case reflect.Struct:
  1103. fieldType := field.Type()
  1104. // Not Same underlying type i.e. struct and time
  1105. if fieldType != currentField.Type() {
  1106. return false
  1107. }
  1108. if fieldType == timeType {
  1109. t := currentField.Interface().(time.Time)
  1110. fieldTime := field.Interface().(time.Time)
  1111. return fieldTime.After(t)
  1112. }
  1113. }
  1114. // default reflect.String
  1115. return len(field.String()) > len(currentField.String())
  1116. }
  1117. // IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
  1118. func isGte(fl FieldLevel) bool {
  1119. field := fl.Field()
  1120. param := fl.Param()
  1121. switch field.Kind() {
  1122. case reflect.String:
  1123. p := asInt(param)
  1124. return int64(utf8.RuneCountInString(field.String())) >= p
  1125. case reflect.Slice, reflect.Map, reflect.Array:
  1126. p := asInt(param)
  1127. return int64(field.Len()) >= p
  1128. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1129. p := asInt(param)
  1130. return field.Int() >= p
  1131. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1132. p := asUint(param)
  1133. return field.Uint() >= p
  1134. case reflect.Float32, reflect.Float64:
  1135. p := asFloat(param)
  1136. return field.Float() >= p
  1137. case reflect.Struct:
  1138. if field.Type() == timeType {
  1139. now := time.Now().UTC()
  1140. t := field.Interface().(time.Time)
  1141. return t.After(now) || t.Equal(now)
  1142. }
  1143. }
  1144. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1145. }
  1146. // IsGt is the validation function for validating if the current field's value is greater than the param's value.
  1147. func isGt(fl FieldLevel) bool {
  1148. field := fl.Field()
  1149. param := fl.Param()
  1150. switch field.Kind() {
  1151. case reflect.String:
  1152. p := asInt(param)
  1153. return int64(utf8.RuneCountInString(field.String())) > p
  1154. case reflect.Slice, reflect.Map, reflect.Array:
  1155. p := asInt(param)
  1156. return int64(field.Len()) > p
  1157. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1158. p := asInt(param)
  1159. return field.Int() > p
  1160. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1161. p := asUint(param)
  1162. return field.Uint() > p
  1163. case reflect.Float32, reflect.Float64:
  1164. p := asFloat(param)
  1165. return field.Float() > p
  1166. case reflect.Struct:
  1167. if field.Type() == timeType {
  1168. return field.Interface().(time.Time).After(time.Now().UTC())
  1169. }
  1170. }
  1171. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1172. }
  1173. // HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
  1174. func hasLengthOf(fl FieldLevel) bool {
  1175. field := fl.Field()
  1176. param := fl.Param()
  1177. switch field.Kind() {
  1178. case reflect.String:
  1179. p := asInt(param)
  1180. return int64(utf8.RuneCountInString(field.String())) == p
  1181. case reflect.Slice, reflect.Map, reflect.Array:
  1182. p := asInt(param)
  1183. return int64(field.Len()) == p
  1184. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1185. p := asInt(param)
  1186. return field.Int() == p
  1187. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1188. p := asUint(param)
  1189. return field.Uint() == p
  1190. case reflect.Float32, reflect.Float64:
  1191. p := asFloat(param)
  1192. return field.Float() == p
  1193. }
  1194. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1195. }
  1196. // HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
  1197. func hasMinOf(fl FieldLevel) bool {
  1198. return isGte(fl)
  1199. }
  1200. // 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.
  1201. func isLteField(fl FieldLevel) bool {
  1202. field := fl.Field()
  1203. kind := field.Kind()
  1204. currentField, currentKind, ok := fl.GetStructFieldOK()
  1205. if !ok || currentKind != kind {
  1206. return false
  1207. }
  1208. switch kind {
  1209. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1210. return field.Int() <= currentField.Int()
  1211. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1212. return field.Uint() <= currentField.Uint()
  1213. case reflect.Float32, reflect.Float64:
  1214. return field.Float() <= currentField.Float()
  1215. case reflect.Struct:
  1216. fieldType := field.Type()
  1217. // Not Same underlying type i.e. struct and time
  1218. if fieldType != currentField.Type() {
  1219. return false
  1220. }
  1221. if fieldType == timeType {
  1222. t := currentField.Interface().(time.Time)
  1223. fieldTime := field.Interface().(time.Time)
  1224. return fieldTime.Before(t) || fieldTime.Equal(t)
  1225. }
  1226. }
  1227. // default reflect.String
  1228. return len(field.String()) <= len(currentField.String())
  1229. }
  1230. // IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
  1231. func isLtField(fl FieldLevel) bool {
  1232. field := fl.Field()
  1233. kind := field.Kind()
  1234. currentField, currentKind, ok := fl.GetStructFieldOK()
  1235. if !ok || currentKind != kind {
  1236. return false
  1237. }
  1238. switch kind {
  1239. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1240. return field.Int() < currentField.Int()
  1241. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1242. return field.Uint() < currentField.Uint()
  1243. case reflect.Float32, reflect.Float64:
  1244. return field.Float() < currentField.Float()
  1245. case reflect.Struct:
  1246. fieldType := field.Type()
  1247. // Not Same underlying type i.e. struct and time
  1248. if fieldType != currentField.Type() {
  1249. return false
  1250. }
  1251. if fieldType == timeType {
  1252. t := currentField.Interface().(time.Time)
  1253. fieldTime := field.Interface().(time.Time)
  1254. return fieldTime.Before(t)
  1255. }
  1256. }
  1257. // default reflect.String
  1258. return len(field.String()) < len(currentField.String())
  1259. }
  1260. // IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
  1261. func isLte(fl FieldLevel) bool {
  1262. field := fl.Field()
  1263. param := fl.Param()
  1264. switch field.Kind() {
  1265. case reflect.String:
  1266. p := asInt(param)
  1267. return int64(utf8.RuneCountInString(field.String())) <= p
  1268. case reflect.Slice, reflect.Map, reflect.Array:
  1269. p := asInt(param)
  1270. return int64(field.Len()) <= p
  1271. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1272. p := asInt(param)
  1273. return field.Int() <= p
  1274. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1275. p := asUint(param)
  1276. return field.Uint() <= p
  1277. case reflect.Float32, reflect.Float64:
  1278. p := asFloat(param)
  1279. return field.Float() <= p
  1280. case reflect.Struct:
  1281. if field.Type() == timeType {
  1282. now := time.Now().UTC()
  1283. t := field.Interface().(time.Time)
  1284. return t.Before(now) || t.Equal(now)
  1285. }
  1286. }
  1287. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1288. }
  1289. // IsLt is the validation function for validating if the current field's value is less than the param's value.
  1290. func isLt(fl FieldLevel) bool {
  1291. field := fl.Field()
  1292. param := fl.Param()
  1293. switch field.Kind() {
  1294. case reflect.String:
  1295. p := asInt(param)
  1296. return int64(utf8.RuneCountInString(field.String())) < p
  1297. case reflect.Slice, reflect.Map, reflect.Array:
  1298. p := asInt(param)
  1299. return int64(field.Len()) < p
  1300. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1301. p := asInt(param)
  1302. return field.Int() < p
  1303. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1304. p := asUint(param)
  1305. return field.Uint() < p
  1306. case reflect.Float32, reflect.Float64:
  1307. p := asFloat(param)
  1308. return field.Float() < p
  1309. case reflect.Struct:
  1310. if field.Type() == timeType {
  1311. return field.Interface().(time.Time).Before(time.Now().UTC())
  1312. }
  1313. }
  1314. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1315. }
  1316. // HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
  1317. func hasMaxOf(fl FieldLevel) bool {
  1318. return isLte(fl)
  1319. }
  1320. // IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
  1321. func isTCP4AddrResolvable(fl FieldLevel) bool {
  1322. if !isIP4Addr(fl) {
  1323. return false
  1324. }
  1325. _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
  1326. return err == nil
  1327. }
  1328. // IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
  1329. func isTCP6AddrResolvable(fl FieldLevel) bool {
  1330. if !isIP6Addr(fl) {
  1331. return false
  1332. }
  1333. _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
  1334. return err == nil
  1335. }
  1336. // IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
  1337. func isTCPAddrResolvable(fl FieldLevel) bool {
  1338. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  1339. return false
  1340. }
  1341. _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
  1342. return err == nil
  1343. }
  1344. // IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
  1345. func isUDP4AddrResolvable(fl FieldLevel) bool {
  1346. if !isIP4Addr(fl) {
  1347. return false
  1348. }
  1349. _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
  1350. return err == nil
  1351. }
  1352. // IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
  1353. func isUDP6AddrResolvable(fl FieldLevel) bool {
  1354. if !isIP6Addr(fl) {
  1355. return false
  1356. }
  1357. _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
  1358. return err == nil
  1359. }
  1360. // IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
  1361. func isUDPAddrResolvable(fl FieldLevel) bool {
  1362. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  1363. return false
  1364. }
  1365. _, err := net.ResolveUDPAddr("udp", fl.Field().String())
  1366. return err == nil
  1367. }
  1368. // IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
  1369. func isIP4AddrResolvable(fl FieldLevel) bool {
  1370. if !isIPv4(fl) {
  1371. return false
  1372. }
  1373. _, err := net.ResolveIPAddr("ip4", fl.Field().String())
  1374. return err == nil
  1375. }
  1376. // IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
  1377. func isIP6AddrResolvable(fl FieldLevel) bool {
  1378. if !isIPv6(fl) {
  1379. return false
  1380. }
  1381. _, err := net.ResolveIPAddr("ip6", fl.Field().String())
  1382. return err == nil
  1383. }
  1384. // IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
  1385. func isIPAddrResolvable(fl FieldLevel) bool {
  1386. if !isIP(fl) {
  1387. return false
  1388. }
  1389. _, err := net.ResolveIPAddr("ip", fl.Field().String())
  1390. return err == nil
  1391. }
  1392. // IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
  1393. func isUnixAddrResolvable(fl FieldLevel) bool {
  1394. _, err := net.ResolveUnixAddr("unix", fl.Field().String())
  1395. return err == nil
  1396. }
  1397. func isIP4Addr(fl FieldLevel) bool {
  1398. val := fl.Field().String()
  1399. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1400. val = val[0:idx]
  1401. }
  1402. ip := net.ParseIP(val)
  1403. return ip != nil && ip.To4() != nil
  1404. }
  1405. func isIP6Addr(fl FieldLevel) bool {
  1406. val := fl.Field().String()
  1407. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1408. if idx != 0 && val[idx-1:idx] == "]" {
  1409. val = val[1 : idx-1]
  1410. }
  1411. }
  1412. ip := net.ParseIP(val)
  1413. return ip != nil && ip.To4() == nil
  1414. }
  1415. func isHostnameRFC952(fl FieldLevel) bool {
  1416. return hostnameRegexRFC952.MatchString(fl.Field().String())
  1417. }
  1418. func isHostnameRFC1123(fl FieldLevel) bool {
  1419. return hostnameRegexRFC1123.MatchString(fl.Field().String())
  1420. }
  1421. func isFQDN(fl FieldLevel) bool {
  1422. val := fl.Field().String()
  1423. if val == "" {
  1424. return false
  1425. }
  1426. if val[len(val)-1] == '.' {
  1427. val = val[0 : len(val)-1]
  1428. }
  1429. return strings.ContainsAny(val, ".") &&
  1430. hostnameRegexRFC952.MatchString(val)
  1431. }
  1432. // IsDir is the validation function for validating if the current field's value is a valid directory.
  1433. func isDir(fl FieldLevel) bool {
  1434. field := fl.Field()
  1435. if field.Kind() == reflect.String {
  1436. fileInfo, err := os.Stat(field.String())
  1437. if err != nil {
  1438. return false
  1439. }
  1440. return fileInfo.IsDir()
  1441. }
  1442. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1443. }