No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

baked_in.go 52KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995
  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. field = fl.Parent().FieldByName(param)
  986. }
  987. switch field.Kind() {
  988. case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
  989. return !field.IsNil()
  990. default:
  991. if fl.(*validate).fldIsPointer && field.Interface() != nil {
  992. return true
  993. }
  994. return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
  995. }
  996. }
  997. // RequiredWith is the validation function
  998. // The field under validation must be present and not empty only if any of the other specified fields are present.
  999. func requiredWith(fl FieldLevel) bool {
  1000. params := parseOneOfParam2(fl.Param())
  1001. for _, param := range params {
  1002. if requireCheckFieldKind(fl, param) {
  1003. return requireCheckFieldKind(fl, "")
  1004. }
  1005. }
  1006. return true
  1007. }
  1008. // RequiredWithAll is the validation function
  1009. // The field under validation must be present and not empty only if all of the other specified fields are present.
  1010. func requiredWithAll(fl FieldLevel) bool {
  1011. isValidateCurrentField := true
  1012. params := parseOneOfParam2(fl.Param())
  1013. for _, param := range params {
  1014. if !requireCheckFieldKind(fl, param) {
  1015. isValidateCurrentField = false
  1016. }
  1017. }
  1018. if isValidateCurrentField {
  1019. return requireCheckFieldKind(fl, "")
  1020. }
  1021. return true
  1022. }
  1023. // RequiredWithout is the validation function
  1024. // The field under validation must be present and not empty only when any of the other specified fields are not present.
  1025. func requiredWithout(fl FieldLevel) bool {
  1026. isValidateCurrentField := false
  1027. params := parseOneOfParam2(fl.Param())
  1028. for _, param := range params {
  1029. if requireCheckFieldKind(fl, param) {
  1030. isValidateCurrentField = true
  1031. }
  1032. }
  1033. if !isValidateCurrentField {
  1034. return requireCheckFieldKind(fl, "")
  1035. }
  1036. return true
  1037. }
  1038. // RequiredWithoutAll is the validation function
  1039. // The field under validation must be present and not empty only when all of the other specified fields are not present.
  1040. func requiredWithoutAll(fl FieldLevel) bool {
  1041. isValidateCurrentField := true
  1042. params := parseOneOfParam2(fl.Param())
  1043. for _, param := range params {
  1044. if requireCheckFieldKind(fl, param) {
  1045. isValidateCurrentField = false
  1046. }
  1047. }
  1048. if isValidateCurrentField {
  1049. return requireCheckFieldKind(fl, "")
  1050. }
  1051. return true
  1052. }
  1053. // 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.
  1054. func isGteField(fl FieldLevel) bool {
  1055. field := fl.Field()
  1056. kind := field.Kind()
  1057. currentField, currentKind, ok := fl.GetStructFieldOK()
  1058. if !ok || currentKind != kind {
  1059. return false
  1060. }
  1061. switch kind {
  1062. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1063. return field.Int() >= currentField.Int()
  1064. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1065. return field.Uint() >= currentField.Uint()
  1066. case reflect.Float32, reflect.Float64:
  1067. return field.Float() >= currentField.Float()
  1068. case reflect.Struct:
  1069. fieldType := field.Type()
  1070. // Not Same underlying type i.e. struct and time
  1071. if fieldType != currentField.Type() {
  1072. return false
  1073. }
  1074. if fieldType == timeType {
  1075. t := currentField.Interface().(time.Time)
  1076. fieldTime := field.Interface().(time.Time)
  1077. return fieldTime.After(t) || fieldTime.Equal(t)
  1078. }
  1079. }
  1080. // default reflect.String
  1081. return len(field.String()) >= len(currentField.String())
  1082. }
  1083. // IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
  1084. func isGtField(fl FieldLevel) bool {
  1085. field := fl.Field()
  1086. kind := field.Kind()
  1087. currentField, currentKind, ok := fl.GetStructFieldOK()
  1088. if !ok || currentKind != kind {
  1089. return false
  1090. }
  1091. switch kind {
  1092. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1093. return field.Int() > currentField.Int()
  1094. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1095. return field.Uint() > currentField.Uint()
  1096. case reflect.Float32, reflect.Float64:
  1097. return field.Float() > currentField.Float()
  1098. case reflect.Struct:
  1099. fieldType := field.Type()
  1100. // Not Same underlying type i.e. struct and time
  1101. if fieldType != currentField.Type() {
  1102. return false
  1103. }
  1104. if fieldType == timeType {
  1105. t := currentField.Interface().(time.Time)
  1106. fieldTime := field.Interface().(time.Time)
  1107. return fieldTime.After(t)
  1108. }
  1109. }
  1110. // default reflect.String
  1111. return len(field.String()) > len(currentField.String())
  1112. }
  1113. // IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
  1114. func isGte(fl FieldLevel) bool {
  1115. field := fl.Field()
  1116. param := fl.Param()
  1117. switch field.Kind() {
  1118. case reflect.String:
  1119. p := asInt(param)
  1120. return int64(utf8.RuneCountInString(field.String())) >= p
  1121. case reflect.Slice, reflect.Map, reflect.Array:
  1122. p := asInt(param)
  1123. return int64(field.Len()) >= p
  1124. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1125. p := asInt(param)
  1126. return field.Int() >= p
  1127. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1128. p := asUint(param)
  1129. return field.Uint() >= p
  1130. case reflect.Float32, reflect.Float64:
  1131. p := asFloat(param)
  1132. return field.Float() >= p
  1133. case reflect.Struct:
  1134. if field.Type() == timeType {
  1135. now := time.Now().UTC()
  1136. t := field.Interface().(time.Time)
  1137. return t.After(now) || t.Equal(now)
  1138. }
  1139. }
  1140. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1141. }
  1142. // IsGt is the validation function for validating if the current field's value is greater than the param's value.
  1143. func isGt(fl FieldLevel) bool {
  1144. field := fl.Field()
  1145. param := fl.Param()
  1146. switch field.Kind() {
  1147. case reflect.String:
  1148. p := asInt(param)
  1149. return int64(utf8.RuneCountInString(field.String())) > p
  1150. case reflect.Slice, reflect.Map, reflect.Array:
  1151. p := asInt(param)
  1152. return int64(field.Len()) > p
  1153. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1154. p := asInt(param)
  1155. return field.Int() > p
  1156. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1157. p := asUint(param)
  1158. return field.Uint() > p
  1159. case reflect.Float32, reflect.Float64:
  1160. p := asFloat(param)
  1161. return field.Float() > p
  1162. case reflect.Struct:
  1163. if field.Type() == timeType {
  1164. return field.Interface().(time.Time).After(time.Now().UTC())
  1165. }
  1166. }
  1167. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1168. }
  1169. // HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
  1170. func hasLengthOf(fl FieldLevel) bool {
  1171. field := fl.Field()
  1172. param := fl.Param()
  1173. switch field.Kind() {
  1174. case reflect.String:
  1175. p := asInt(param)
  1176. return int64(utf8.RuneCountInString(field.String())) == p
  1177. case reflect.Slice, reflect.Map, reflect.Array:
  1178. p := asInt(param)
  1179. return int64(field.Len()) == p
  1180. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1181. p := asInt(param)
  1182. return field.Int() == p
  1183. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1184. p := asUint(param)
  1185. return field.Uint() == p
  1186. case reflect.Float32, reflect.Float64:
  1187. p := asFloat(param)
  1188. return field.Float() == p
  1189. }
  1190. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1191. }
  1192. // HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
  1193. func hasMinOf(fl FieldLevel) bool {
  1194. return isGte(fl)
  1195. }
  1196. // 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.
  1197. func isLteField(fl FieldLevel) bool {
  1198. field := fl.Field()
  1199. kind := field.Kind()
  1200. currentField, currentKind, ok := fl.GetStructFieldOK()
  1201. if !ok || currentKind != kind {
  1202. return false
  1203. }
  1204. switch kind {
  1205. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1206. return field.Int() <= currentField.Int()
  1207. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1208. return field.Uint() <= currentField.Uint()
  1209. case reflect.Float32, reflect.Float64:
  1210. return field.Float() <= currentField.Float()
  1211. case reflect.Struct:
  1212. fieldType := field.Type()
  1213. // Not Same underlying type i.e. struct and time
  1214. if fieldType != currentField.Type() {
  1215. return false
  1216. }
  1217. if fieldType == timeType {
  1218. t := currentField.Interface().(time.Time)
  1219. fieldTime := field.Interface().(time.Time)
  1220. return fieldTime.Before(t) || fieldTime.Equal(t)
  1221. }
  1222. }
  1223. // default reflect.String
  1224. return len(field.String()) <= len(currentField.String())
  1225. }
  1226. // IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
  1227. func isLtField(fl FieldLevel) bool {
  1228. field := fl.Field()
  1229. kind := field.Kind()
  1230. currentField, currentKind, ok := fl.GetStructFieldOK()
  1231. if !ok || currentKind != kind {
  1232. return false
  1233. }
  1234. switch kind {
  1235. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1236. return field.Int() < currentField.Int()
  1237. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1238. return field.Uint() < currentField.Uint()
  1239. case reflect.Float32, reflect.Float64:
  1240. return field.Float() < currentField.Float()
  1241. case reflect.Struct:
  1242. fieldType := field.Type()
  1243. // Not Same underlying type i.e. struct and time
  1244. if fieldType != currentField.Type() {
  1245. return false
  1246. }
  1247. if fieldType == timeType {
  1248. t := currentField.Interface().(time.Time)
  1249. fieldTime := field.Interface().(time.Time)
  1250. return fieldTime.Before(t)
  1251. }
  1252. }
  1253. // default reflect.String
  1254. return len(field.String()) < len(currentField.String())
  1255. }
  1256. // IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
  1257. func isLte(fl FieldLevel) bool {
  1258. field := fl.Field()
  1259. param := fl.Param()
  1260. switch field.Kind() {
  1261. case reflect.String:
  1262. p := asInt(param)
  1263. return int64(utf8.RuneCountInString(field.String())) <= p
  1264. case reflect.Slice, reflect.Map, reflect.Array:
  1265. p := asInt(param)
  1266. return int64(field.Len()) <= p
  1267. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1268. p := asInt(param)
  1269. return field.Int() <= p
  1270. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1271. p := asUint(param)
  1272. return field.Uint() <= p
  1273. case reflect.Float32, reflect.Float64:
  1274. p := asFloat(param)
  1275. return field.Float() <= p
  1276. case reflect.Struct:
  1277. if field.Type() == timeType {
  1278. now := time.Now().UTC()
  1279. t := field.Interface().(time.Time)
  1280. return t.Before(now) || t.Equal(now)
  1281. }
  1282. }
  1283. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1284. }
  1285. // IsLt is the validation function for validating if the current field's value is less than the param's value.
  1286. func isLt(fl FieldLevel) bool {
  1287. field := fl.Field()
  1288. param := fl.Param()
  1289. switch field.Kind() {
  1290. case reflect.String:
  1291. p := asInt(param)
  1292. return int64(utf8.RuneCountInString(field.String())) < p
  1293. case reflect.Slice, reflect.Map, reflect.Array:
  1294. p := asInt(param)
  1295. return int64(field.Len()) < p
  1296. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1297. p := asInt(param)
  1298. return field.Int() < p
  1299. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1300. p := asUint(param)
  1301. return field.Uint() < p
  1302. case reflect.Float32, reflect.Float64:
  1303. p := asFloat(param)
  1304. return field.Float() < p
  1305. case reflect.Struct:
  1306. if field.Type() == timeType {
  1307. return field.Interface().(time.Time).Before(time.Now().UTC())
  1308. }
  1309. }
  1310. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1311. }
  1312. // HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
  1313. func hasMaxOf(fl FieldLevel) bool {
  1314. return isLte(fl)
  1315. }
  1316. // IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
  1317. func isTCP4AddrResolvable(fl FieldLevel) bool {
  1318. if !isIP4Addr(fl) {
  1319. return false
  1320. }
  1321. _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
  1322. return err == nil
  1323. }
  1324. // IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
  1325. func isTCP6AddrResolvable(fl FieldLevel) bool {
  1326. if !isIP6Addr(fl) {
  1327. return false
  1328. }
  1329. _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
  1330. return err == nil
  1331. }
  1332. // IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
  1333. func isTCPAddrResolvable(fl FieldLevel) bool {
  1334. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  1335. return false
  1336. }
  1337. _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
  1338. return err == nil
  1339. }
  1340. // IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
  1341. func isUDP4AddrResolvable(fl FieldLevel) bool {
  1342. if !isIP4Addr(fl) {
  1343. return false
  1344. }
  1345. _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
  1346. return err == nil
  1347. }
  1348. // IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
  1349. func isUDP6AddrResolvable(fl FieldLevel) bool {
  1350. if !isIP6Addr(fl) {
  1351. return false
  1352. }
  1353. _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
  1354. return err == nil
  1355. }
  1356. // IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
  1357. func isUDPAddrResolvable(fl FieldLevel) bool {
  1358. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  1359. return false
  1360. }
  1361. _, err := net.ResolveUDPAddr("udp", fl.Field().String())
  1362. return err == nil
  1363. }
  1364. // IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
  1365. func isIP4AddrResolvable(fl FieldLevel) bool {
  1366. if !isIPv4(fl) {
  1367. return false
  1368. }
  1369. _, err := net.ResolveIPAddr("ip4", fl.Field().String())
  1370. return err == nil
  1371. }
  1372. // IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
  1373. func isIP6AddrResolvable(fl FieldLevel) bool {
  1374. if !isIPv6(fl) {
  1375. return false
  1376. }
  1377. _, err := net.ResolveIPAddr("ip6", fl.Field().String())
  1378. return err == nil
  1379. }
  1380. // IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
  1381. func isIPAddrResolvable(fl FieldLevel) bool {
  1382. if !isIP(fl) {
  1383. return false
  1384. }
  1385. _, err := net.ResolveIPAddr("ip", fl.Field().String())
  1386. return err == nil
  1387. }
  1388. // IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
  1389. func isUnixAddrResolvable(fl FieldLevel) bool {
  1390. _, err := net.ResolveUnixAddr("unix", fl.Field().String())
  1391. return err == nil
  1392. }
  1393. func isIP4Addr(fl FieldLevel) bool {
  1394. val := fl.Field().String()
  1395. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1396. val = val[0:idx]
  1397. }
  1398. ip := net.ParseIP(val)
  1399. return ip != nil && ip.To4() != nil
  1400. }
  1401. func isIP6Addr(fl FieldLevel) bool {
  1402. val := fl.Field().String()
  1403. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1404. if idx != 0 && val[idx-1:idx] == "]" {
  1405. val = val[1 : idx-1]
  1406. }
  1407. }
  1408. ip := net.ParseIP(val)
  1409. return ip != nil && ip.To4() == nil
  1410. }
  1411. func isHostnameRFC952(fl FieldLevel) bool {
  1412. return hostnameRegexRFC952.MatchString(fl.Field().String())
  1413. }
  1414. func isHostnameRFC1123(fl FieldLevel) bool {
  1415. return hostnameRegexRFC1123.MatchString(fl.Field().String())
  1416. }
  1417. func isFQDN(fl FieldLevel) bool {
  1418. val := fl.Field().String()
  1419. if val == "" {
  1420. return false
  1421. }
  1422. if val[len(val)-1] == '.' {
  1423. val = val[0 : len(val)-1]
  1424. }
  1425. return strings.ContainsAny(val, ".") &&
  1426. hostnameRegexRFC952.MatchString(val)
  1427. }
  1428. // IsDir is the validation function for validating if the current field's value is a valid directory.
  1429. func isDir(fl FieldLevel) bool {
  1430. field := fl.Field()
  1431. if field.Kind() == reflect.String {
  1432. fileInfo, err := os.Stat(field.String())
  1433. if err != nil {
  1434. return false
  1435. }
  1436. return fileInfo.IsDir()
  1437. }
  1438. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1439. }