baked_in.go 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409
  1. package validator
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/sha256"
  6. "encoding/hex"
  7. "encoding/json"
  8. "fmt"
  9. "net"
  10. "net/url"
  11. "os"
  12. "reflect"
  13. "strconv"
  14. "strings"
  15. "sync"
  16. "time"
  17. "unicode/utf8"
  18. "golang.org/x/crypto/sha3"
  19. "golang.org/x/text/language"
  20. urn "github.com/leodido/go-urn"
  21. )
  22. // Func accepts a FieldLevel interface for all validation needs. The return
  23. // value should be true when validation succeeds.
  24. type Func func(fl FieldLevel) bool
  25. // FuncCtx accepts a context.Context and FieldLevel interface for all
  26. // validation needs. The return value should be true when validation succeeds.
  27. type FuncCtx func(ctx context.Context, fl FieldLevel) bool
  28. // wrapFunc wraps noramal Func makes it compatible with FuncCtx
  29. func wrapFunc(fn Func) FuncCtx {
  30. if fn == nil {
  31. return nil // be sure not to wrap a bad function.
  32. }
  33. return func(ctx context.Context, fl FieldLevel) bool {
  34. return fn(fl)
  35. }
  36. }
  37. var (
  38. restrictedTags = map[string]struct{}{
  39. diveTag: {},
  40. keysTag: {},
  41. endKeysTag: {},
  42. structOnlyTag: {},
  43. omitempty: {},
  44. skipValidationTag: {},
  45. utf8HexComma: {},
  46. utf8Pipe: {},
  47. noStructLevelTag: {},
  48. requiredTag: {},
  49. isdefault: {},
  50. }
  51. // bakedInAliases is a default mapping of a single validation tag that
  52. // defines a common or complex set of validation(s) to simplify
  53. // adding validation to structs.
  54. bakedInAliases = map[string]string{
  55. "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
  56. "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
  57. }
  58. // bakedInValidators is the default map of ValidationFunc
  59. // you can add, remove or even replace items to suite your needs,
  60. // or even disregard and use your own map if so desired.
  61. bakedInValidators = map[string]Func{
  62. "required": hasValue,
  63. "required_if": requiredIf,
  64. "required_unless": requiredUnless,
  65. "required_with": requiredWith,
  66. "required_with_all": requiredWithAll,
  67. "required_without": requiredWithout,
  68. "required_without_all": requiredWithoutAll,
  69. "excluded_with": excludedWith,
  70. "excluded_with_all": excludedWithAll,
  71. "excluded_without": excludedWithout,
  72. "excluded_without_all": excludedWithoutAll,
  73. "isdefault": isDefault,
  74. "len": hasLengthOf,
  75. "min": hasMinOf,
  76. "max": hasMaxOf,
  77. "eq": isEq,
  78. "ne": isNe,
  79. "lt": isLt,
  80. "lte": isLte,
  81. "gt": isGt,
  82. "gte": isGte,
  83. "eqfield": isEqField,
  84. "eqcsfield": isEqCrossStructField,
  85. "necsfield": isNeCrossStructField,
  86. "gtcsfield": isGtCrossStructField,
  87. "gtecsfield": isGteCrossStructField,
  88. "ltcsfield": isLtCrossStructField,
  89. "ltecsfield": isLteCrossStructField,
  90. "nefield": isNeField,
  91. "gtefield": isGteField,
  92. "gtfield": isGtField,
  93. "ltefield": isLteField,
  94. "ltfield": isLtField,
  95. "fieldcontains": fieldContains,
  96. "fieldexcludes": fieldExcludes,
  97. "alpha": isAlpha,
  98. "alphanum": isAlphanum,
  99. "alphaunicode": isAlphaUnicode,
  100. "alphanumunicode": isAlphanumUnicode,
  101. "boolean": isBoolean,
  102. "numeric": isNumeric,
  103. "number": isNumber,
  104. "hexadecimal": isHexadecimal,
  105. "hexcolor": isHEXColor,
  106. "rgb": isRGB,
  107. "rgba": isRGBA,
  108. "hsl": isHSL,
  109. "hsla": isHSLA,
  110. "e164": isE164,
  111. "email": isEmail,
  112. "url": isURL,
  113. "uri": isURI,
  114. "urn_rfc2141": isUrnRFC2141, // RFC 2141
  115. "file": isFile,
  116. "base64": isBase64,
  117. "base64url": isBase64URL,
  118. "contains": contains,
  119. "containsany": containsAny,
  120. "containsrune": containsRune,
  121. "excludes": excludes,
  122. "excludesall": excludesAll,
  123. "excludesrune": excludesRune,
  124. "startswith": startsWith,
  125. "endswith": endsWith,
  126. "startsnotwith": startsNotWith,
  127. "endsnotwith": endsNotWith,
  128. "isbn": isISBN,
  129. "isbn10": isISBN10,
  130. "isbn13": isISBN13,
  131. "eth_addr": isEthereumAddress,
  132. "btc_addr": isBitcoinAddress,
  133. "btc_addr_bech32": isBitcoinBech32Address,
  134. "uuid": isUUID,
  135. "uuid3": isUUID3,
  136. "uuid4": isUUID4,
  137. "uuid5": isUUID5,
  138. "uuid_rfc4122": isUUIDRFC4122,
  139. "uuid3_rfc4122": isUUID3RFC4122,
  140. "uuid4_rfc4122": isUUID4RFC4122,
  141. "uuid5_rfc4122": isUUID5RFC4122,
  142. "ascii": isASCII,
  143. "printascii": isPrintableASCII,
  144. "multibyte": hasMultiByteCharacter,
  145. "datauri": isDataURI,
  146. "latitude": isLatitude,
  147. "longitude": isLongitude,
  148. "ssn": isSSN,
  149. "ipv4": isIPv4,
  150. "ipv6": isIPv6,
  151. "ip": isIP,
  152. "cidrv4": isCIDRv4,
  153. "cidrv6": isCIDRv6,
  154. "cidr": isCIDR,
  155. "tcp4_addr": isTCP4AddrResolvable,
  156. "tcp6_addr": isTCP6AddrResolvable,
  157. "tcp_addr": isTCPAddrResolvable,
  158. "udp4_addr": isUDP4AddrResolvable,
  159. "udp6_addr": isUDP6AddrResolvable,
  160. "udp_addr": isUDPAddrResolvable,
  161. "ip4_addr": isIP4AddrResolvable,
  162. "ip6_addr": isIP6AddrResolvable,
  163. "ip_addr": isIPAddrResolvable,
  164. "unix_addr": isUnixAddrResolvable,
  165. "mac": isMAC,
  166. "hostname": isHostnameRFC952, // RFC 952
  167. "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
  168. "fqdn": isFQDN,
  169. "unique": isUnique,
  170. "oneof": isOneOf,
  171. "html": isHTML,
  172. "html_encoded": isHTMLEncoded,
  173. "url_encoded": isURLEncoded,
  174. "dir": isDir,
  175. "json": isJSON,
  176. "jwt": isJWT,
  177. "hostname_port": isHostnamePort,
  178. "lowercase": isLowercase,
  179. "uppercase": isUppercase,
  180. "datetime": isDatetime,
  181. "timezone": isTimeZone,
  182. "iso3166_1_alpha2": isIso3166Alpha2,
  183. "iso3166_1_alpha3": isIso3166Alpha3,
  184. "iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
  185. "iso3166_2": isIso31662,
  186. "iso4217": isIso4217,
  187. "iso4217_numeric": isIso4217Numeric,
  188. "bcp47_language_tag": isBCP47LanguageTag,
  189. "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2,
  190. "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field,
  191. "bic": isIsoBicFormat,
  192. }
  193. )
  194. var oneofValsCache = map[string][]string{}
  195. var oneofValsCacheRWLock = sync.RWMutex{}
  196. func parseOneOfParam2(s string) []string {
  197. oneofValsCacheRWLock.RLock()
  198. vals, ok := oneofValsCache[s]
  199. oneofValsCacheRWLock.RUnlock()
  200. if !ok {
  201. oneofValsCacheRWLock.Lock()
  202. vals = splitParamsRegex.FindAllString(s, -1)
  203. for i := 0; i < len(vals); i++ {
  204. vals[i] = strings.Replace(vals[i], "'", "", -1)
  205. }
  206. oneofValsCache[s] = vals
  207. oneofValsCacheRWLock.Unlock()
  208. }
  209. return vals
  210. }
  211. func isURLEncoded(fl FieldLevel) bool {
  212. return uRLEncodedRegex.MatchString(fl.Field().String())
  213. }
  214. func isHTMLEncoded(fl FieldLevel) bool {
  215. return hTMLEncodedRegex.MatchString(fl.Field().String())
  216. }
  217. func isHTML(fl FieldLevel) bool {
  218. return hTMLRegex.MatchString(fl.Field().String())
  219. }
  220. func isOneOf(fl FieldLevel) bool {
  221. vals := parseOneOfParam2(fl.Param())
  222. field := fl.Field()
  223. var v string
  224. switch field.Kind() {
  225. case reflect.String:
  226. v = field.String()
  227. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  228. v = strconv.FormatInt(field.Int(), 10)
  229. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  230. v = strconv.FormatUint(field.Uint(), 10)
  231. default:
  232. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  233. }
  234. for i := 0; i < len(vals); i++ {
  235. if vals[i] == v {
  236. return true
  237. }
  238. }
  239. return false
  240. }
  241. // isUnique is the validation function for validating if each array|slice|map value is unique
  242. func isUnique(fl FieldLevel) bool {
  243. field := fl.Field()
  244. param := fl.Param()
  245. v := reflect.ValueOf(struct{}{})
  246. switch field.Kind() {
  247. case reflect.Slice, reflect.Array:
  248. elem := field.Type().Elem()
  249. if elem.Kind() == reflect.Ptr {
  250. elem = elem.Elem()
  251. }
  252. if param == "" {
  253. m := reflect.MakeMap(reflect.MapOf(elem, v.Type()))
  254. for i := 0; i < field.Len(); i++ {
  255. m.SetMapIndex(reflect.Indirect(field.Index(i)), v)
  256. }
  257. return field.Len() == m.Len()
  258. }
  259. sf, ok := elem.FieldByName(param)
  260. if !ok {
  261. panic(fmt.Sprintf("Bad field name %s", param))
  262. }
  263. sfTyp := sf.Type
  264. if sfTyp.Kind() == reflect.Ptr {
  265. sfTyp = sfTyp.Elem()
  266. }
  267. m := reflect.MakeMap(reflect.MapOf(sfTyp, v.Type()))
  268. for i := 0; i < field.Len(); i++ {
  269. m.SetMapIndex(reflect.Indirect(reflect.Indirect(field.Index(i)).FieldByName(param)), v)
  270. }
  271. return field.Len() == m.Len()
  272. case reflect.Map:
  273. m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
  274. for _, k := range field.MapKeys() {
  275. m.SetMapIndex(field.MapIndex(k), v)
  276. }
  277. return field.Len() == m.Len()
  278. default:
  279. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  280. }
  281. }
  282. // isMAC is the validation function for validating if the field's value is a valid MAC address.
  283. func isMAC(fl FieldLevel) bool {
  284. _, err := net.ParseMAC(fl.Field().String())
  285. return err == nil
  286. }
  287. // isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
  288. func isCIDRv4(fl FieldLevel) bool {
  289. ip, _, err := net.ParseCIDR(fl.Field().String())
  290. return err == nil && ip.To4() != nil
  291. }
  292. // isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
  293. func isCIDRv6(fl FieldLevel) bool {
  294. ip, _, err := net.ParseCIDR(fl.Field().String())
  295. return err == nil && ip.To4() == nil
  296. }
  297. // isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
  298. func isCIDR(fl FieldLevel) bool {
  299. _, _, err := net.ParseCIDR(fl.Field().String())
  300. return err == nil
  301. }
  302. // isIPv4 is the validation function for validating if a value is a valid v4 IP address.
  303. func isIPv4(fl FieldLevel) bool {
  304. ip := net.ParseIP(fl.Field().String())
  305. return ip != nil && ip.To4() != nil
  306. }
  307. // isIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
  308. func isIPv6(fl FieldLevel) bool {
  309. ip := net.ParseIP(fl.Field().String())
  310. return ip != nil && ip.To4() == nil
  311. }
  312. // isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
  313. func isIP(fl FieldLevel) bool {
  314. ip := net.ParseIP(fl.Field().String())
  315. return ip != nil
  316. }
  317. // isSSN is the validation function for validating if the field's value is a valid SSN.
  318. func isSSN(fl FieldLevel) bool {
  319. field := fl.Field()
  320. if field.Len() != 11 {
  321. return false
  322. }
  323. return sSNRegex.MatchString(field.String())
  324. }
  325. // isLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
  326. func isLongitude(fl FieldLevel) bool {
  327. field := fl.Field()
  328. var v string
  329. switch field.Kind() {
  330. case reflect.String:
  331. v = field.String()
  332. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  333. v = strconv.FormatInt(field.Int(), 10)
  334. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  335. v = strconv.FormatUint(field.Uint(), 10)
  336. case reflect.Float32:
  337. v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
  338. case reflect.Float64:
  339. v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
  340. default:
  341. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  342. }
  343. return longitudeRegex.MatchString(v)
  344. }
  345. // isLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
  346. func isLatitude(fl FieldLevel) bool {
  347. field := fl.Field()
  348. var v string
  349. switch field.Kind() {
  350. case reflect.String:
  351. v = field.String()
  352. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  353. v = strconv.FormatInt(field.Int(), 10)
  354. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  355. v = strconv.FormatUint(field.Uint(), 10)
  356. case reflect.Float32:
  357. v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
  358. case reflect.Float64:
  359. v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
  360. default:
  361. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  362. }
  363. return latitudeRegex.MatchString(v)
  364. }
  365. // isDataURI is the validation function for validating if the field's value is a valid data URI.
  366. func isDataURI(fl FieldLevel) bool {
  367. uri := strings.SplitN(fl.Field().String(), ",", 2)
  368. if len(uri) != 2 {
  369. return false
  370. }
  371. if !dataURIRegex.MatchString(uri[0]) {
  372. return false
  373. }
  374. return base64Regex.MatchString(uri[1])
  375. }
  376. // hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
  377. func hasMultiByteCharacter(fl FieldLevel) bool {
  378. field := fl.Field()
  379. if field.Len() == 0 {
  380. return true
  381. }
  382. return multibyteRegex.MatchString(field.String())
  383. }
  384. // isPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
  385. func isPrintableASCII(fl FieldLevel) bool {
  386. return printableASCIIRegex.MatchString(fl.Field().String())
  387. }
  388. // isASCII is the validation function for validating if the field's value is a valid ASCII character.
  389. func isASCII(fl FieldLevel) bool {
  390. return aSCIIRegex.MatchString(fl.Field().String())
  391. }
  392. // isUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
  393. func isUUID5(fl FieldLevel) bool {
  394. return uUID5Regex.MatchString(fl.Field().String())
  395. }
  396. // isUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
  397. func isUUID4(fl FieldLevel) bool {
  398. return uUID4Regex.MatchString(fl.Field().String())
  399. }
  400. // isUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
  401. func isUUID3(fl FieldLevel) bool {
  402. return uUID3Regex.MatchString(fl.Field().String())
  403. }
  404. // isUUID is the validation function for validating if the field's value is a valid UUID of any version.
  405. func isUUID(fl FieldLevel) bool {
  406. return uUIDRegex.MatchString(fl.Field().String())
  407. }
  408. // isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
  409. func isUUID5RFC4122(fl FieldLevel) bool {
  410. return uUID5RFC4122Regex.MatchString(fl.Field().String())
  411. }
  412. // isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
  413. func isUUID4RFC4122(fl FieldLevel) bool {
  414. return uUID4RFC4122Regex.MatchString(fl.Field().String())
  415. }
  416. // isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
  417. func isUUID3RFC4122(fl FieldLevel) bool {
  418. return uUID3RFC4122Regex.MatchString(fl.Field().String())
  419. }
  420. // isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
  421. func isUUIDRFC4122(fl FieldLevel) bool {
  422. return uUIDRFC4122Regex.MatchString(fl.Field().String())
  423. }
  424. // isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
  425. func isISBN(fl FieldLevel) bool {
  426. return isISBN10(fl) || isISBN13(fl)
  427. }
  428. // isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
  429. func isISBN13(fl FieldLevel) bool {
  430. s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
  431. if !iSBN13Regex.MatchString(s) {
  432. return false
  433. }
  434. var checksum int32
  435. var i int32
  436. factor := []int32{1, 3}
  437. for i = 0; i < 12; i++ {
  438. checksum += factor[i%2] * int32(s[i]-'0')
  439. }
  440. return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
  441. }
  442. // isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
  443. func isISBN10(fl FieldLevel) bool {
  444. s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
  445. if !iSBN10Regex.MatchString(s) {
  446. return false
  447. }
  448. var checksum int32
  449. var i int32
  450. for i = 0; i < 9; i++ {
  451. checksum += (i + 1) * int32(s[i]-'0')
  452. }
  453. if s[9] == 'X' {
  454. checksum += 10 * 10
  455. } else {
  456. checksum += 10 * int32(s[9]-'0')
  457. }
  458. return checksum%11 == 0
  459. }
  460. // isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
  461. func isEthereumAddress(fl FieldLevel) bool {
  462. address := fl.Field().String()
  463. if !ethAddressRegex.MatchString(address) {
  464. return false
  465. }
  466. if ethAddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
  467. return true
  468. }
  469. // Checksum validation. Reference: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
  470. address = address[2:] // Skip "0x" prefix.
  471. h := sha3.NewLegacyKeccak256()
  472. // hash.Hash's io.Writer implementation says it never returns an error. https://golang.org/pkg/hash/#Hash
  473. _, _ = h.Write([]byte(strings.ToLower(address)))
  474. hash := hex.EncodeToString(h.Sum(nil))
  475. for i := 0; i < len(address); i++ {
  476. if address[i] <= '9' { // Skip 0-9 digits: they don't have upper/lower-case.
  477. continue
  478. }
  479. if hash[i] > '7' && address[i] >= 'a' || hash[i] <= '7' && address[i] <= 'F' {
  480. return false
  481. }
  482. }
  483. return true
  484. }
  485. // isBitcoinAddress is the validation function for validating if the field's value is a valid btc address
  486. func isBitcoinAddress(fl FieldLevel) bool {
  487. address := fl.Field().String()
  488. if !btcAddressRegex.MatchString(address) {
  489. return false
  490. }
  491. alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
  492. decode := [25]byte{}
  493. for _, n := range []byte(address) {
  494. d := bytes.IndexByte(alphabet, n)
  495. for i := 24; i >= 0; i-- {
  496. d += 58 * int(decode[i])
  497. decode[i] = byte(d % 256)
  498. d /= 256
  499. }
  500. }
  501. h := sha256.New()
  502. _, _ = h.Write(decode[:21])
  503. d := h.Sum([]byte{})
  504. h = sha256.New()
  505. _, _ = h.Write(d)
  506. validchecksum := [4]byte{}
  507. computedchecksum := [4]byte{}
  508. copy(computedchecksum[:], h.Sum(d[:0]))
  509. copy(validchecksum[:], decode[21:])
  510. return validchecksum == computedchecksum
  511. }
  512. // isBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
  513. func isBitcoinBech32Address(fl FieldLevel) bool {
  514. address := fl.Field().String()
  515. if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) {
  516. return false
  517. }
  518. am := len(address) % 8
  519. if am == 0 || am == 3 || am == 5 {
  520. return false
  521. }
  522. address = strings.ToLower(address)
  523. alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
  524. hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc
  525. addr := address[3:]
  526. dp := make([]int, 0, len(addr))
  527. for _, c := range addr {
  528. dp = append(dp, strings.IndexRune(alphabet, c))
  529. }
  530. ver := dp[0]
  531. if ver < 0 || ver > 16 {
  532. return false
  533. }
  534. if ver == 0 {
  535. if len(address) != 42 && len(address) != 62 {
  536. return false
  537. }
  538. }
  539. values := append(hr, dp...)
  540. GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
  541. p := 1
  542. for _, v := range values {
  543. b := p >> 25
  544. p = (p&0x1ffffff)<<5 ^ v
  545. for i := 0; i < 5; i++ {
  546. if (b>>uint(i))&1 == 1 {
  547. p ^= GEN[i]
  548. }
  549. }
  550. }
  551. if p != 1 {
  552. return false
  553. }
  554. b := uint(0)
  555. acc := 0
  556. mv := (1 << 5) - 1
  557. var sw []int
  558. for _, v := range dp[1 : len(dp)-6] {
  559. acc = (acc << 5) | v
  560. b += 5
  561. for b >= 8 {
  562. b -= 8
  563. sw = append(sw, (acc>>b)&mv)
  564. }
  565. }
  566. if len(sw) < 2 || len(sw) > 40 {
  567. return false
  568. }
  569. return true
  570. }
  571. // excludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
  572. func excludesRune(fl FieldLevel) bool {
  573. return !containsRune(fl)
  574. }
  575. // excludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
  576. func excludesAll(fl FieldLevel) bool {
  577. return !containsAny(fl)
  578. }
  579. // excludes is the validation function for validating that the field's value does not contain the text specified within the param.
  580. func excludes(fl FieldLevel) bool {
  581. return !contains(fl)
  582. }
  583. // containsRune is the validation function for validating that the field's value contains the rune specified within the param.
  584. func containsRune(fl FieldLevel) bool {
  585. r, _ := utf8.DecodeRuneInString(fl.Param())
  586. return strings.ContainsRune(fl.Field().String(), r)
  587. }
  588. // containsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
  589. func containsAny(fl FieldLevel) bool {
  590. return strings.ContainsAny(fl.Field().String(), fl.Param())
  591. }
  592. // contains is the validation function for validating that the field's value contains the text specified within the param.
  593. func contains(fl FieldLevel) bool {
  594. return strings.Contains(fl.Field().String(), fl.Param())
  595. }
  596. // startsWith is the validation function for validating that the field's value starts with the text specified within the param.
  597. func startsWith(fl FieldLevel) bool {
  598. return strings.HasPrefix(fl.Field().String(), fl.Param())
  599. }
  600. // endsWith is the validation function for validating that the field's value ends with the text specified within the param.
  601. func endsWith(fl FieldLevel) bool {
  602. return strings.HasSuffix(fl.Field().String(), fl.Param())
  603. }
  604. // startsNotWith is the validation function for validating that the field's value does not start with the text specified within the param.
  605. func startsNotWith(fl FieldLevel) bool {
  606. return !startsWith(fl)
  607. }
  608. // endsNotWith is the validation function for validating that the field's value does not end with the text specified within the param.
  609. func endsNotWith(fl FieldLevel) bool {
  610. return !endsWith(fl)
  611. }
  612. // fieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
  613. func fieldContains(fl FieldLevel) bool {
  614. field := fl.Field()
  615. currentField, _, ok := fl.GetStructFieldOK()
  616. if !ok {
  617. return false
  618. }
  619. return strings.Contains(field.String(), currentField.String())
  620. }
  621. // fieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
  622. func fieldExcludes(fl FieldLevel) bool {
  623. field := fl.Field()
  624. currentField, _, ok := fl.GetStructFieldOK()
  625. if !ok {
  626. return true
  627. }
  628. return !strings.Contains(field.String(), currentField.String())
  629. }
  630. // 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.
  631. func isNeField(fl FieldLevel) bool {
  632. field := fl.Field()
  633. kind := field.Kind()
  634. currentField, currentKind, ok := fl.GetStructFieldOK()
  635. if !ok || currentKind != kind {
  636. return true
  637. }
  638. switch kind {
  639. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  640. return field.Int() != currentField.Int()
  641. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  642. return field.Uint() != currentField.Uint()
  643. case reflect.Float32, reflect.Float64:
  644. return field.Float() != currentField.Float()
  645. case reflect.Slice, reflect.Map, reflect.Array:
  646. return int64(field.Len()) != int64(currentField.Len())
  647. case reflect.Bool:
  648. return field.Bool() != currentField.Bool()
  649. case reflect.Struct:
  650. fieldType := field.Type()
  651. // Not Same underlying type i.e. struct and time
  652. if fieldType != currentField.Type() {
  653. return true
  654. }
  655. if fieldType == timeType {
  656. t := currentField.Interface().(time.Time)
  657. fieldTime := field.Interface().(time.Time)
  658. return !fieldTime.Equal(t)
  659. }
  660. }
  661. // default reflect.String:
  662. return field.String() != currentField.String()
  663. }
  664. // isNe is the validation function for validating that the field's value does not equal the provided param value.
  665. func isNe(fl FieldLevel) bool {
  666. return !isEq(fl)
  667. }
  668. // 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.
  669. func isLteCrossStructField(fl FieldLevel) bool {
  670. field := fl.Field()
  671. kind := field.Kind()
  672. topField, topKind, ok := fl.GetStructFieldOK()
  673. if !ok || topKind != kind {
  674. return false
  675. }
  676. switch kind {
  677. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  678. return field.Int() <= topField.Int()
  679. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  680. return field.Uint() <= topField.Uint()
  681. case reflect.Float32, reflect.Float64:
  682. return field.Float() <= topField.Float()
  683. case reflect.Slice, reflect.Map, reflect.Array:
  684. return int64(field.Len()) <= int64(topField.Len())
  685. case reflect.Struct:
  686. fieldType := field.Type()
  687. // Not Same underlying type i.e. struct and time
  688. if fieldType != topField.Type() {
  689. return false
  690. }
  691. if fieldType == timeType {
  692. fieldTime := field.Interface().(time.Time)
  693. topTime := topField.Interface().(time.Time)
  694. return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
  695. }
  696. }
  697. // default reflect.String:
  698. return field.String() <= topField.String()
  699. }
  700. // 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.
  701. // NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
  702. func isLtCrossStructField(fl FieldLevel) bool {
  703. field := fl.Field()
  704. kind := field.Kind()
  705. topField, topKind, ok := fl.GetStructFieldOK()
  706. if !ok || topKind != kind {
  707. return false
  708. }
  709. switch kind {
  710. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  711. return field.Int() < topField.Int()
  712. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  713. return field.Uint() < topField.Uint()
  714. case reflect.Float32, reflect.Float64:
  715. return field.Float() < topField.Float()
  716. case reflect.Slice, reflect.Map, reflect.Array:
  717. return int64(field.Len()) < int64(topField.Len())
  718. case reflect.Struct:
  719. fieldType := field.Type()
  720. // Not Same underlying type i.e. struct and time
  721. if fieldType != topField.Type() {
  722. return false
  723. }
  724. if fieldType == timeType {
  725. fieldTime := field.Interface().(time.Time)
  726. topTime := topField.Interface().(time.Time)
  727. return fieldTime.Before(topTime)
  728. }
  729. }
  730. // default reflect.String:
  731. return field.String() < topField.String()
  732. }
  733. // 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.
  734. func isGteCrossStructField(fl FieldLevel) bool {
  735. field := fl.Field()
  736. kind := field.Kind()
  737. topField, topKind, ok := fl.GetStructFieldOK()
  738. if !ok || topKind != kind {
  739. return false
  740. }
  741. switch kind {
  742. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  743. return field.Int() >= topField.Int()
  744. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  745. return field.Uint() >= topField.Uint()
  746. case reflect.Float32, reflect.Float64:
  747. return field.Float() >= topField.Float()
  748. case reflect.Slice, reflect.Map, reflect.Array:
  749. return int64(field.Len()) >= int64(topField.Len())
  750. case reflect.Struct:
  751. fieldType := field.Type()
  752. // Not Same underlying type i.e. struct and time
  753. if fieldType != topField.Type() {
  754. return false
  755. }
  756. if fieldType == timeType {
  757. fieldTime := field.Interface().(time.Time)
  758. topTime := topField.Interface().(time.Time)
  759. return fieldTime.After(topTime) || fieldTime.Equal(topTime)
  760. }
  761. }
  762. // default reflect.String:
  763. return field.String() >= topField.String()
  764. }
  765. // 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.
  766. func isGtCrossStructField(fl FieldLevel) bool {
  767. field := fl.Field()
  768. kind := field.Kind()
  769. topField, topKind, ok := fl.GetStructFieldOK()
  770. if !ok || topKind != kind {
  771. return false
  772. }
  773. switch kind {
  774. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  775. return field.Int() > topField.Int()
  776. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  777. return field.Uint() > topField.Uint()
  778. case reflect.Float32, reflect.Float64:
  779. return field.Float() > topField.Float()
  780. case reflect.Slice, reflect.Map, reflect.Array:
  781. return int64(field.Len()) > int64(topField.Len())
  782. case reflect.Struct:
  783. fieldType := field.Type()
  784. // Not Same underlying type i.e. struct and time
  785. if fieldType != topField.Type() {
  786. return false
  787. }
  788. if fieldType == timeType {
  789. fieldTime := field.Interface().(time.Time)
  790. topTime := topField.Interface().(time.Time)
  791. return fieldTime.After(topTime)
  792. }
  793. }
  794. // default reflect.String:
  795. return field.String() > topField.String()
  796. }
  797. // 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.
  798. func isNeCrossStructField(fl FieldLevel) bool {
  799. field := fl.Field()
  800. kind := field.Kind()
  801. topField, currentKind, ok := fl.GetStructFieldOK()
  802. if !ok || currentKind != kind {
  803. return true
  804. }
  805. switch kind {
  806. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  807. return topField.Int() != field.Int()
  808. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  809. return topField.Uint() != field.Uint()
  810. case reflect.Float32, reflect.Float64:
  811. return topField.Float() != field.Float()
  812. case reflect.Slice, reflect.Map, reflect.Array:
  813. return int64(topField.Len()) != int64(field.Len())
  814. case reflect.Bool:
  815. return topField.Bool() != field.Bool()
  816. case reflect.Struct:
  817. fieldType := field.Type()
  818. // Not Same underlying type i.e. struct and time
  819. if fieldType != topField.Type() {
  820. return true
  821. }
  822. if fieldType == timeType {
  823. t := field.Interface().(time.Time)
  824. fieldTime := topField.Interface().(time.Time)
  825. return !fieldTime.Equal(t)
  826. }
  827. }
  828. // default reflect.String:
  829. return topField.String() != field.String()
  830. }
  831. // 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.
  832. func isEqCrossStructField(fl FieldLevel) bool {
  833. field := fl.Field()
  834. kind := field.Kind()
  835. topField, topKind, ok := fl.GetStructFieldOK()
  836. if !ok || topKind != kind {
  837. return false
  838. }
  839. switch kind {
  840. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  841. return topField.Int() == field.Int()
  842. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  843. return topField.Uint() == field.Uint()
  844. case reflect.Float32, reflect.Float64:
  845. return topField.Float() == field.Float()
  846. case reflect.Slice, reflect.Map, reflect.Array:
  847. return int64(topField.Len()) == int64(field.Len())
  848. case reflect.Bool:
  849. return topField.Bool() == field.Bool()
  850. case reflect.Struct:
  851. fieldType := field.Type()
  852. // Not Same underlying type i.e. struct and time
  853. if fieldType != topField.Type() {
  854. return false
  855. }
  856. if fieldType == timeType {
  857. t := field.Interface().(time.Time)
  858. fieldTime := topField.Interface().(time.Time)
  859. return fieldTime.Equal(t)
  860. }
  861. }
  862. // default reflect.String:
  863. return topField.String() == field.String()
  864. }
  865. // isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
  866. func isEqField(fl FieldLevel) bool {
  867. field := fl.Field()
  868. kind := field.Kind()
  869. currentField, currentKind, ok := fl.GetStructFieldOK()
  870. if !ok || currentKind != kind {
  871. return false
  872. }
  873. switch kind {
  874. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  875. return field.Int() == currentField.Int()
  876. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  877. return field.Uint() == currentField.Uint()
  878. case reflect.Float32, reflect.Float64:
  879. return field.Float() == currentField.Float()
  880. case reflect.Slice, reflect.Map, reflect.Array:
  881. return int64(field.Len()) == int64(currentField.Len())
  882. case reflect.Bool:
  883. return field.Bool() == currentField.Bool()
  884. case reflect.Struct:
  885. fieldType := field.Type()
  886. // Not Same underlying type i.e. struct and time
  887. if fieldType != currentField.Type() {
  888. return false
  889. }
  890. if fieldType == timeType {
  891. t := currentField.Interface().(time.Time)
  892. fieldTime := field.Interface().(time.Time)
  893. return fieldTime.Equal(t)
  894. }
  895. }
  896. // default reflect.String:
  897. return field.String() == currentField.String()
  898. }
  899. // isEq is the validation function for validating if the current field's value is equal to the param's value.
  900. func isEq(fl FieldLevel) bool {
  901. field := fl.Field()
  902. param := fl.Param()
  903. switch field.Kind() {
  904. case reflect.String:
  905. return field.String() == param
  906. case reflect.Slice, reflect.Map, reflect.Array:
  907. p := asInt(param)
  908. return int64(field.Len()) == p
  909. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  910. p := asIntFromType(field.Type(), param)
  911. return field.Int() == p
  912. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  913. p := asUint(param)
  914. return field.Uint() == p
  915. case reflect.Float32, reflect.Float64:
  916. p := asFloat(param)
  917. return field.Float() == p
  918. case reflect.Bool:
  919. p := asBool(param)
  920. return field.Bool() == p
  921. }
  922. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  923. }
  924. // isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2
  925. // example: `postcode_iso3166_alpha2=US`
  926. func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
  927. field := fl.Field()
  928. param := fl.Param()
  929. reg, found := postCodeRegexDict[param]
  930. if !found {
  931. return false
  932. }
  933. return reg.MatchString(field.String())
  934. }
  935. // isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2
  936. // example: `postcode_iso3166_alpha2_field=CountryCode`
  937. func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
  938. field := fl.Field()
  939. params := parseOneOfParam2(fl.Param())
  940. if len(params) != 1 {
  941. return false
  942. }
  943. currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0])
  944. if !found {
  945. return false
  946. }
  947. if kind != reflect.String {
  948. panic(fmt.Sprintf("Bad field type %T", currentField.Interface()))
  949. }
  950. reg, found := postCodeRegexDict[currentField.String()]
  951. if !found {
  952. return false
  953. }
  954. return reg.MatchString(field.String())
  955. }
  956. // isBase64 is the validation function for validating if the current field's value is a valid base 64.
  957. func isBase64(fl FieldLevel) bool {
  958. return base64Regex.MatchString(fl.Field().String())
  959. }
  960. // isBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
  961. func isBase64URL(fl FieldLevel) bool {
  962. return base64URLRegex.MatchString(fl.Field().String())
  963. }
  964. // isURI is the validation function for validating if the current field's value is a valid URI.
  965. func isURI(fl FieldLevel) bool {
  966. field := fl.Field()
  967. switch field.Kind() {
  968. case reflect.String:
  969. s := field.String()
  970. // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
  971. // emulate browser and strip the '#' suffix prior to validation. see issue-#237
  972. if i := strings.Index(s, "#"); i > -1 {
  973. s = s[:i]
  974. }
  975. if len(s) == 0 {
  976. return false
  977. }
  978. _, err := url.ParseRequestURI(s)
  979. return err == nil
  980. }
  981. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  982. }
  983. // isURL is the validation function for validating if the current field's value is a valid URL.
  984. func isURL(fl FieldLevel) bool {
  985. field := fl.Field()
  986. switch field.Kind() {
  987. case reflect.String:
  988. var i int
  989. s := field.String()
  990. // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
  991. // emulate browser and strip the '#' suffix prior to validation. see issue-#237
  992. if i = strings.Index(s, "#"); i > -1 {
  993. s = s[:i]
  994. }
  995. if len(s) == 0 {
  996. return false
  997. }
  998. url, err := url.ParseRequestURI(s)
  999. if err != nil || url.Scheme == "" {
  1000. return false
  1001. }
  1002. return true
  1003. }
  1004. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1005. }
  1006. // isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
  1007. func isUrnRFC2141(fl FieldLevel) bool {
  1008. field := fl.Field()
  1009. switch field.Kind() {
  1010. case reflect.String:
  1011. str := field.String()
  1012. _, match := urn.Parse([]byte(str))
  1013. return match
  1014. }
  1015. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1016. }
  1017. // isFile is the validation function for validating if the current field's value is a valid file path.
  1018. func isFile(fl FieldLevel) bool {
  1019. field := fl.Field()
  1020. switch field.Kind() {
  1021. case reflect.String:
  1022. fileInfo, err := os.Stat(field.String())
  1023. if err != nil {
  1024. return false
  1025. }
  1026. return !fileInfo.IsDir()
  1027. }
  1028. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1029. }
  1030. // isE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number.
  1031. func isE164(fl FieldLevel) bool {
  1032. return e164Regex.MatchString(fl.Field().String())
  1033. }
  1034. // isEmail is the validation function for validating if the current field's value is a valid email address.
  1035. func isEmail(fl FieldLevel) bool {
  1036. return emailRegex.MatchString(fl.Field().String())
  1037. }
  1038. // isHSLA is the validation function for validating if the current field's value is a valid HSLA color.
  1039. func isHSLA(fl FieldLevel) bool {
  1040. return hslaRegex.MatchString(fl.Field().String())
  1041. }
  1042. // isHSL is the validation function for validating if the current field's value is a valid HSL color.
  1043. func isHSL(fl FieldLevel) bool {
  1044. return hslRegex.MatchString(fl.Field().String())
  1045. }
  1046. // isRGBA is the validation function for validating if the current field's value is a valid RGBA color.
  1047. func isRGBA(fl FieldLevel) bool {
  1048. return rgbaRegex.MatchString(fl.Field().String())
  1049. }
  1050. // isRGB is the validation function for validating if the current field's value is a valid RGB color.
  1051. func isRGB(fl FieldLevel) bool {
  1052. return rgbRegex.MatchString(fl.Field().String())
  1053. }
  1054. // isHEXColor is the validation function for validating if the current field's value is a valid HEX color.
  1055. func isHEXColor(fl FieldLevel) bool {
  1056. return hexColorRegex.MatchString(fl.Field().String())
  1057. }
  1058. // isHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
  1059. func isHexadecimal(fl FieldLevel) bool {
  1060. return hexadecimalRegex.MatchString(fl.Field().String())
  1061. }
  1062. // isNumber is the validation function for validating if the current field's value is a valid number.
  1063. func isNumber(fl FieldLevel) bool {
  1064. switch fl.Field().Kind() {
  1065. 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:
  1066. return true
  1067. default:
  1068. return numberRegex.MatchString(fl.Field().String())
  1069. }
  1070. }
  1071. // isNumeric is the validation function for validating if the current field's value is a valid numeric value.
  1072. func isNumeric(fl FieldLevel) bool {
  1073. switch fl.Field().Kind() {
  1074. 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:
  1075. return true
  1076. default:
  1077. return numericRegex.MatchString(fl.Field().String())
  1078. }
  1079. }
  1080. // isAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
  1081. func isAlphanum(fl FieldLevel) bool {
  1082. return alphaNumericRegex.MatchString(fl.Field().String())
  1083. }
  1084. // isAlpha is the validation function for validating if the current field's value is a valid alpha value.
  1085. func isAlpha(fl FieldLevel) bool {
  1086. return alphaRegex.MatchString(fl.Field().String())
  1087. }
  1088. // isAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
  1089. func isAlphanumUnicode(fl FieldLevel) bool {
  1090. return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
  1091. }
  1092. // isAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
  1093. func isAlphaUnicode(fl FieldLevel) bool {
  1094. return alphaUnicodeRegex.MatchString(fl.Field().String())
  1095. }
  1096. // isBoolean is the validation function for validating if the current field's value can be safely converted to a boolean.
  1097. func isBoolean(fl FieldLevel) bool {
  1098. _, err := strconv.ParseBool(fl.Field().String())
  1099. return err == nil
  1100. }
  1101. // isDefault is the opposite of required aka hasValue
  1102. func isDefault(fl FieldLevel) bool {
  1103. return !hasValue(fl)
  1104. }
  1105. // hasValue is the validation function for validating if the current field's value is not the default static value.
  1106. func hasValue(fl FieldLevel) bool {
  1107. field := fl.Field()
  1108. switch field.Kind() {
  1109. case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
  1110. return !field.IsNil()
  1111. default:
  1112. if fl.(*validate).fldIsPointer && field.Interface() != nil {
  1113. return true
  1114. }
  1115. return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
  1116. }
  1117. }
  1118. // requireCheckField is a func for check field kind
  1119. func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue bool) bool {
  1120. field := fl.Field()
  1121. kind := field.Kind()
  1122. var nullable, found bool
  1123. if len(param) > 0 {
  1124. field, kind, nullable, found = fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
  1125. if !found {
  1126. return defaultNotFoundValue
  1127. }
  1128. }
  1129. switch kind {
  1130. case reflect.Invalid:
  1131. return defaultNotFoundValue
  1132. case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
  1133. return field.IsNil()
  1134. default:
  1135. if nullable && field.Interface() != nil {
  1136. return false
  1137. }
  1138. return field.IsValid() && field.Interface() == reflect.Zero(field.Type()).Interface()
  1139. }
  1140. }
  1141. // requireCheckFieldValue is a func for check field value
  1142. func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNotFoundValue bool) bool {
  1143. field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
  1144. if !found {
  1145. return defaultNotFoundValue
  1146. }
  1147. switch kind {
  1148. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1149. return field.Int() == asInt(value)
  1150. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1151. return field.Uint() == asUint(value)
  1152. case reflect.Float32, reflect.Float64:
  1153. return field.Float() == asFloat(value)
  1154. case reflect.Slice, reflect.Map, reflect.Array:
  1155. return int64(field.Len()) == asInt(value)
  1156. case reflect.Bool:
  1157. return field.Bool() == asBool(value)
  1158. }
  1159. // default reflect.String:
  1160. return field.String() == value
  1161. }
  1162. // requiredIf is the validation function
  1163. // The field under validation must be present and not empty only if all the other specified fields are equal to the value following with the specified field.
  1164. func requiredIf(fl FieldLevel) bool {
  1165. params := parseOneOfParam2(fl.Param())
  1166. if len(params)%2 != 0 {
  1167. panic(fmt.Sprintf("Bad param number for required_if %s", fl.FieldName()))
  1168. }
  1169. for i := 0; i < len(params); i += 2 {
  1170. if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
  1171. return true
  1172. }
  1173. }
  1174. return hasValue(fl)
  1175. }
  1176. // requiredUnless is the validation function
  1177. // The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
  1178. func requiredUnless(fl FieldLevel) bool {
  1179. params := parseOneOfParam2(fl.Param())
  1180. if len(params)%2 != 0 {
  1181. panic(fmt.Sprintf("Bad param number for required_unless %s", fl.FieldName()))
  1182. }
  1183. for i := 0; i < len(params); i += 2 {
  1184. if requireCheckFieldValue(fl, params[i], params[i+1], false) {
  1185. return true
  1186. }
  1187. }
  1188. return hasValue(fl)
  1189. }
  1190. // excludedWith is the validation function
  1191. // The field under validation must not be present or is empty if any of the other specified fields are present.
  1192. func excludedWith(fl FieldLevel) bool {
  1193. params := parseOneOfParam2(fl.Param())
  1194. for _, param := range params {
  1195. if !requireCheckFieldKind(fl, param, true) {
  1196. return !hasValue(fl)
  1197. }
  1198. }
  1199. return true
  1200. }
  1201. // requiredWith is the validation function
  1202. // The field under validation must be present and not empty only if any of the other specified fields are present.
  1203. func requiredWith(fl FieldLevel) bool {
  1204. params := parseOneOfParam2(fl.Param())
  1205. for _, param := range params {
  1206. if !requireCheckFieldKind(fl, param, true) {
  1207. return hasValue(fl)
  1208. }
  1209. }
  1210. return true
  1211. }
  1212. // excludedWithAll is the validation function
  1213. // The field under validation must not be present or is empty if all of the other specified fields are present.
  1214. func excludedWithAll(fl FieldLevel) bool {
  1215. params := parseOneOfParam2(fl.Param())
  1216. for _, param := range params {
  1217. if requireCheckFieldKind(fl, param, true) {
  1218. return true
  1219. }
  1220. }
  1221. return !hasValue(fl)
  1222. }
  1223. // requiredWithAll is the validation function
  1224. // The field under validation must be present and not empty only if all of the other specified fields are present.
  1225. func requiredWithAll(fl FieldLevel) bool {
  1226. params := parseOneOfParam2(fl.Param())
  1227. for _, param := range params {
  1228. if requireCheckFieldKind(fl, param, true) {
  1229. return true
  1230. }
  1231. }
  1232. return hasValue(fl)
  1233. }
  1234. // excludedWithout is the validation function
  1235. // The field under validation must not be present or is empty when any of the other specified fields are not present.
  1236. func excludedWithout(fl FieldLevel) bool {
  1237. if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
  1238. return !hasValue(fl)
  1239. }
  1240. return true
  1241. }
  1242. // requiredWithout is the validation function
  1243. // The field under validation must be present and not empty only when any of the other specified fields are not present.
  1244. func requiredWithout(fl FieldLevel) bool {
  1245. if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
  1246. return hasValue(fl)
  1247. }
  1248. return true
  1249. }
  1250. // excludedWithoutAll is the validation function
  1251. // The field under validation must not be present or is empty when all of the other specified fields are not present.
  1252. func excludedWithoutAll(fl FieldLevel) bool {
  1253. params := parseOneOfParam2(fl.Param())
  1254. for _, param := range params {
  1255. if !requireCheckFieldKind(fl, param, true) {
  1256. return true
  1257. }
  1258. }
  1259. return !hasValue(fl)
  1260. }
  1261. // requiredWithoutAll is the validation function
  1262. // The field under validation must be present and not empty only when all of the other specified fields are not present.
  1263. func requiredWithoutAll(fl FieldLevel) bool {
  1264. params := parseOneOfParam2(fl.Param())
  1265. for _, param := range params {
  1266. if !requireCheckFieldKind(fl, param, true) {
  1267. return true
  1268. }
  1269. }
  1270. return hasValue(fl)
  1271. }
  1272. // 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.
  1273. func isGteField(fl FieldLevel) bool {
  1274. field := fl.Field()
  1275. kind := field.Kind()
  1276. currentField, currentKind, ok := fl.GetStructFieldOK()
  1277. if !ok || currentKind != kind {
  1278. return false
  1279. }
  1280. switch kind {
  1281. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1282. return field.Int() >= currentField.Int()
  1283. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1284. return field.Uint() >= currentField.Uint()
  1285. case reflect.Float32, reflect.Float64:
  1286. return field.Float() >= currentField.Float()
  1287. case reflect.Struct:
  1288. fieldType := field.Type()
  1289. // Not Same underlying type i.e. struct and time
  1290. if fieldType != currentField.Type() {
  1291. return false
  1292. }
  1293. if fieldType == timeType {
  1294. t := currentField.Interface().(time.Time)
  1295. fieldTime := field.Interface().(time.Time)
  1296. return fieldTime.After(t) || fieldTime.Equal(t)
  1297. }
  1298. }
  1299. // default reflect.String
  1300. return len(field.String()) >= len(currentField.String())
  1301. }
  1302. // isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
  1303. func isGtField(fl FieldLevel) bool {
  1304. field := fl.Field()
  1305. kind := field.Kind()
  1306. currentField, currentKind, ok := fl.GetStructFieldOK()
  1307. if !ok || currentKind != kind {
  1308. return false
  1309. }
  1310. switch kind {
  1311. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1312. return field.Int() > currentField.Int()
  1313. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1314. return field.Uint() > currentField.Uint()
  1315. case reflect.Float32, reflect.Float64:
  1316. return field.Float() > currentField.Float()
  1317. case reflect.Struct:
  1318. fieldType := field.Type()
  1319. // Not Same underlying type i.e. struct and time
  1320. if fieldType != currentField.Type() {
  1321. return false
  1322. }
  1323. if fieldType == timeType {
  1324. t := currentField.Interface().(time.Time)
  1325. fieldTime := field.Interface().(time.Time)
  1326. return fieldTime.After(t)
  1327. }
  1328. }
  1329. // default reflect.String
  1330. return len(field.String()) > len(currentField.String())
  1331. }
  1332. // isGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
  1333. func isGte(fl FieldLevel) bool {
  1334. field := fl.Field()
  1335. param := fl.Param()
  1336. switch field.Kind() {
  1337. case reflect.String:
  1338. p := asInt(param)
  1339. return int64(utf8.RuneCountInString(field.String())) >= p
  1340. case reflect.Slice, reflect.Map, reflect.Array:
  1341. p := asInt(param)
  1342. return int64(field.Len()) >= p
  1343. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1344. p := asIntFromType(field.Type(), param)
  1345. return field.Int() >= p
  1346. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1347. p := asUint(param)
  1348. return field.Uint() >= p
  1349. case reflect.Float32, reflect.Float64:
  1350. p := asFloat(param)
  1351. return field.Float() >= p
  1352. case reflect.Struct:
  1353. if field.Type() == timeType {
  1354. now := time.Now().UTC()
  1355. t := field.Interface().(time.Time)
  1356. return t.After(now) || t.Equal(now)
  1357. }
  1358. }
  1359. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1360. }
  1361. // isGt is the validation function for validating if the current field's value is greater than the param's value.
  1362. func isGt(fl FieldLevel) bool {
  1363. field := fl.Field()
  1364. param := fl.Param()
  1365. switch field.Kind() {
  1366. case reflect.String:
  1367. p := asInt(param)
  1368. return int64(utf8.RuneCountInString(field.String())) > p
  1369. case reflect.Slice, reflect.Map, reflect.Array:
  1370. p := asInt(param)
  1371. return int64(field.Len()) > p
  1372. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1373. p := asIntFromType(field.Type(), param)
  1374. return field.Int() > p
  1375. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1376. p := asUint(param)
  1377. return field.Uint() > p
  1378. case reflect.Float32, reflect.Float64:
  1379. p := asFloat(param)
  1380. return field.Float() > p
  1381. case reflect.Struct:
  1382. if field.Type() == timeType {
  1383. return field.Interface().(time.Time).After(time.Now().UTC())
  1384. }
  1385. }
  1386. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1387. }
  1388. // hasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
  1389. func hasLengthOf(fl FieldLevel) bool {
  1390. field := fl.Field()
  1391. param := fl.Param()
  1392. switch field.Kind() {
  1393. case reflect.String:
  1394. p := asInt(param)
  1395. return int64(utf8.RuneCountInString(field.String())) == p
  1396. case reflect.Slice, reflect.Map, reflect.Array:
  1397. p := asInt(param)
  1398. return int64(field.Len()) == p
  1399. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1400. p := asIntFromType(field.Type(), param)
  1401. return field.Int() == p
  1402. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1403. p := asUint(param)
  1404. return field.Uint() == p
  1405. case reflect.Float32, reflect.Float64:
  1406. p := asFloat(param)
  1407. return field.Float() == p
  1408. }
  1409. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1410. }
  1411. // hasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
  1412. func hasMinOf(fl FieldLevel) bool {
  1413. return isGte(fl)
  1414. }
  1415. // 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.
  1416. func isLteField(fl FieldLevel) bool {
  1417. field := fl.Field()
  1418. kind := field.Kind()
  1419. currentField, currentKind, ok := fl.GetStructFieldOK()
  1420. if !ok || currentKind != kind {
  1421. return false
  1422. }
  1423. switch kind {
  1424. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1425. return field.Int() <= currentField.Int()
  1426. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1427. return field.Uint() <= currentField.Uint()
  1428. case reflect.Float32, reflect.Float64:
  1429. return field.Float() <= currentField.Float()
  1430. case reflect.Struct:
  1431. fieldType := field.Type()
  1432. // Not Same underlying type i.e. struct and time
  1433. if fieldType != currentField.Type() {
  1434. return false
  1435. }
  1436. if fieldType == timeType {
  1437. t := currentField.Interface().(time.Time)
  1438. fieldTime := field.Interface().(time.Time)
  1439. return fieldTime.Before(t) || fieldTime.Equal(t)
  1440. }
  1441. }
  1442. // default reflect.String
  1443. return len(field.String()) <= len(currentField.String())
  1444. }
  1445. // isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
  1446. func isLtField(fl FieldLevel) bool {
  1447. field := fl.Field()
  1448. kind := field.Kind()
  1449. currentField, currentKind, ok := fl.GetStructFieldOK()
  1450. if !ok || currentKind != kind {
  1451. return false
  1452. }
  1453. switch kind {
  1454. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1455. return field.Int() < currentField.Int()
  1456. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1457. return field.Uint() < currentField.Uint()
  1458. case reflect.Float32, reflect.Float64:
  1459. return field.Float() < currentField.Float()
  1460. case reflect.Struct:
  1461. fieldType := field.Type()
  1462. // Not Same underlying type i.e. struct and time
  1463. if fieldType != currentField.Type() {
  1464. return false
  1465. }
  1466. if fieldType == timeType {
  1467. t := currentField.Interface().(time.Time)
  1468. fieldTime := field.Interface().(time.Time)
  1469. return fieldTime.Before(t)
  1470. }
  1471. }
  1472. // default reflect.String
  1473. return len(field.String()) < len(currentField.String())
  1474. }
  1475. // isLte is the validation function for validating if the current field's value is less than or equal to the param's value.
  1476. func isLte(fl FieldLevel) bool {
  1477. field := fl.Field()
  1478. param := fl.Param()
  1479. switch field.Kind() {
  1480. case reflect.String:
  1481. p := asInt(param)
  1482. return int64(utf8.RuneCountInString(field.String())) <= p
  1483. case reflect.Slice, reflect.Map, reflect.Array:
  1484. p := asInt(param)
  1485. return int64(field.Len()) <= p
  1486. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1487. p := asIntFromType(field.Type(), param)
  1488. return field.Int() <= p
  1489. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1490. p := asUint(param)
  1491. return field.Uint() <= p
  1492. case reflect.Float32, reflect.Float64:
  1493. p := asFloat(param)
  1494. return field.Float() <= p
  1495. case reflect.Struct:
  1496. if field.Type() == timeType {
  1497. now := time.Now().UTC()
  1498. t := field.Interface().(time.Time)
  1499. return t.Before(now) || t.Equal(now)
  1500. }
  1501. }
  1502. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1503. }
  1504. // isLt is the validation function for validating if the current field's value is less than the param's value.
  1505. func isLt(fl FieldLevel) bool {
  1506. field := fl.Field()
  1507. param := fl.Param()
  1508. switch field.Kind() {
  1509. case reflect.String:
  1510. p := asInt(param)
  1511. return int64(utf8.RuneCountInString(field.String())) < p
  1512. case reflect.Slice, reflect.Map, reflect.Array:
  1513. p := asInt(param)
  1514. return int64(field.Len()) < p
  1515. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1516. p := asIntFromType(field.Type(), param)
  1517. return field.Int() < p
  1518. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1519. p := asUint(param)
  1520. return field.Uint() < p
  1521. case reflect.Float32, reflect.Float64:
  1522. p := asFloat(param)
  1523. return field.Float() < p
  1524. case reflect.Struct:
  1525. if field.Type() == timeType {
  1526. return field.Interface().(time.Time).Before(time.Now().UTC())
  1527. }
  1528. }
  1529. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1530. }
  1531. // hasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
  1532. func hasMaxOf(fl FieldLevel) bool {
  1533. return isLte(fl)
  1534. }
  1535. // isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
  1536. func isTCP4AddrResolvable(fl FieldLevel) bool {
  1537. if !isIP4Addr(fl) {
  1538. return false
  1539. }
  1540. _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
  1541. return err == nil
  1542. }
  1543. // isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
  1544. func isTCP6AddrResolvable(fl FieldLevel) bool {
  1545. if !isIP6Addr(fl) {
  1546. return false
  1547. }
  1548. _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
  1549. return err == nil
  1550. }
  1551. // isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
  1552. func isTCPAddrResolvable(fl FieldLevel) bool {
  1553. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  1554. return false
  1555. }
  1556. _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
  1557. return err == nil
  1558. }
  1559. // isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
  1560. func isUDP4AddrResolvable(fl FieldLevel) bool {
  1561. if !isIP4Addr(fl) {
  1562. return false
  1563. }
  1564. _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
  1565. return err == nil
  1566. }
  1567. // isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
  1568. func isUDP6AddrResolvable(fl FieldLevel) bool {
  1569. if !isIP6Addr(fl) {
  1570. return false
  1571. }
  1572. _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
  1573. return err == nil
  1574. }
  1575. // isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
  1576. func isUDPAddrResolvable(fl FieldLevel) bool {
  1577. if !isIP4Addr(fl) && !isIP6Addr(fl) {
  1578. return false
  1579. }
  1580. _, err := net.ResolveUDPAddr("udp", fl.Field().String())
  1581. return err == nil
  1582. }
  1583. // isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
  1584. func isIP4AddrResolvable(fl FieldLevel) bool {
  1585. if !isIPv4(fl) {
  1586. return false
  1587. }
  1588. _, err := net.ResolveIPAddr("ip4", fl.Field().String())
  1589. return err == nil
  1590. }
  1591. // isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
  1592. func isIP6AddrResolvable(fl FieldLevel) bool {
  1593. if !isIPv6(fl) {
  1594. return false
  1595. }
  1596. _, err := net.ResolveIPAddr("ip6", fl.Field().String())
  1597. return err == nil
  1598. }
  1599. // isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
  1600. func isIPAddrResolvable(fl FieldLevel) bool {
  1601. if !isIP(fl) {
  1602. return false
  1603. }
  1604. _, err := net.ResolveIPAddr("ip", fl.Field().String())
  1605. return err == nil
  1606. }
  1607. // isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
  1608. func isUnixAddrResolvable(fl FieldLevel) bool {
  1609. _, err := net.ResolveUnixAddr("unix", fl.Field().String())
  1610. return err == nil
  1611. }
  1612. func isIP4Addr(fl FieldLevel) bool {
  1613. val := fl.Field().String()
  1614. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1615. val = val[0:idx]
  1616. }
  1617. ip := net.ParseIP(val)
  1618. return ip != nil && ip.To4() != nil
  1619. }
  1620. func isIP6Addr(fl FieldLevel) bool {
  1621. val := fl.Field().String()
  1622. if idx := strings.LastIndex(val, ":"); idx != -1 {
  1623. if idx != 0 && val[idx-1:idx] == "]" {
  1624. val = val[1 : idx-1]
  1625. }
  1626. }
  1627. ip := net.ParseIP(val)
  1628. return ip != nil && ip.To4() == nil
  1629. }
  1630. func isHostnameRFC952(fl FieldLevel) bool {
  1631. return hostnameRegexRFC952.MatchString(fl.Field().String())
  1632. }
  1633. func isHostnameRFC1123(fl FieldLevel) bool {
  1634. return hostnameRegexRFC1123.MatchString(fl.Field().String())
  1635. }
  1636. func isFQDN(fl FieldLevel) bool {
  1637. val := fl.Field().String()
  1638. if val == "" {
  1639. return false
  1640. }
  1641. return fqdnRegexRFC1123.MatchString(val)
  1642. }
  1643. // isDir is the validation function for validating if the current field's value is a valid directory.
  1644. func isDir(fl FieldLevel) bool {
  1645. field := fl.Field()
  1646. if field.Kind() == reflect.String {
  1647. fileInfo, err := os.Stat(field.String())
  1648. if err != nil {
  1649. return false
  1650. }
  1651. return fileInfo.IsDir()
  1652. }
  1653. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1654. }
  1655. // isJSON is the validation function for validating if the current field's value is a valid json string.
  1656. func isJSON(fl FieldLevel) bool {
  1657. field := fl.Field()
  1658. if field.Kind() == reflect.String {
  1659. val := field.String()
  1660. return json.Valid([]byte(val))
  1661. }
  1662. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1663. }
  1664. // isJWT is the validation function for validating if the current field's value is a valid JWT string.
  1665. func isJWT(fl FieldLevel) bool {
  1666. return jWTRegex.MatchString(fl.Field().String())
  1667. }
  1668. // isHostnamePort validates a <dns>:<port> combination for fields typically used for socket address.
  1669. func isHostnamePort(fl FieldLevel) bool {
  1670. val := fl.Field().String()
  1671. host, port, err := net.SplitHostPort(val)
  1672. if err != nil {
  1673. return false
  1674. }
  1675. // Port must be a iny <= 65535.
  1676. if portNum, err := strconv.ParseInt(port, 10, 32); err != nil || portNum > 65535 || portNum < 1 {
  1677. return false
  1678. }
  1679. // If host is specified, it should match a DNS name
  1680. if host != "" {
  1681. return hostnameRegexRFC1123.MatchString(host)
  1682. }
  1683. return true
  1684. }
  1685. // isLowercase is the validation function for validating if the current field's value is a lowercase string.
  1686. func isLowercase(fl FieldLevel) bool {
  1687. field := fl.Field()
  1688. if field.Kind() == reflect.String {
  1689. if field.String() == "" {
  1690. return false
  1691. }
  1692. return field.String() == strings.ToLower(field.String())
  1693. }
  1694. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1695. }
  1696. // isUppercase is the validation function for validating if the current field's value is an uppercase string.
  1697. func isUppercase(fl FieldLevel) bool {
  1698. field := fl.Field()
  1699. if field.Kind() == reflect.String {
  1700. if field.String() == "" {
  1701. return false
  1702. }
  1703. return field.String() == strings.ToUpper(field.String())
  1704. }
  1705. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1706. }
  1707. // isDatetime is the validation function for validating if the current field's value is a valid datetime string.
  1708. func isDatetime(fl FieldLevel) bool {
  1709. field := fl.Field()
  1710. param := fl.Param()
  1711. if field.Kind() == reflect.String {
  1712. _, err := time.Parse(param, field.String())
  1713. return err == nil
  1714. }
  1715. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1716. }
  1717. // isTimeZone is the validation function for validating if the current field's value is a valid time zone string.
  1718. func isTimeZone(fl FieldLevel) bool {
  1719. field := fl.Field()
  1720. if field.Kind() == reflect.String {
  1721. // empty value is converted to UTC by time.LoadLocation but disallow it as it is not a valid time zone name
  1722. if field.String() == "" {
  1723. return false
  1724. }
  1725. // Local value is converted to the current system time zone by time.LoadLocation but disallow it as it is not a valid time zone name
  1726. if strings.ToLower(field.String()) == "local" {
  1727. return false
  1728. }
  1729. _, err := time.LoadLocation(field.String())
  1730. return err == nil
  1731. }
  1732. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1733. }
  1734. // isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 country code.
  1735. func isIso3166Alpha2(fl FieldLevel) bool {
  1736. val := fl.Field().String()
  1737. return iso3166_1_alpha2[val]
  1738. }
  1739. // isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
  1740. func isIso3166Alpha3(fl FieldLevel) bool {
  1741. val := fl.Field().String()
  1742. return iso3166_1_alpha3[val]
  1743. }
  1744. // isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
  1745. func isIso3166AlphaNumeric(fl FieldLevel) bool {
  1746. field := fl.Field()
  1747. var code int
  1748. switch field.Kind() {
  1749. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1750. code = int(field.Int() % 1000)
  1751. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  1752. code = int(field.Uint() % 1000)
  1753. default:
  1754. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1755. }
  1756. return iso3166_1_alpha_numeric[code]
  1757. }
  1758. // isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
  1759. func isIso31662(fl FieldLevel) bool {
  1760. val := fl.Field().String()
  1761. return iso3166_2[val]
  1762. }
  1763. // isIso4217 is the validation function for validating if the current field's value is a valid iso4217 currency code.
  1764. func isIso4217(fl FieldLevel) bool {
  1765. val := fl.Field().String()
  1766. return iso4217[val]
  1767. }
  1768. // isIso4217Numeric is the validation function for validating if the current field's value is a valid iso4217 numeric currency code.
  1769. func isIso4217Numeric(fl FieldLevel) bool {
  1770. field := fl.Field()
  1771. var code int
  1772. switch field.Kind() {
  1773. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1774. code = int(field.Int())
  1775. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  1776. code = int(field.Uint())
  1777. default:
  1778. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1779. }
  1780. return iso4217_numeric[code]
  1781. }
  1782. // isBCP47LanguageTag is the validation function for validating if the current field's value is a valid BCP 47 language tag, as parsed by language.Parse
  1783. func isBCP47LanguageTag(fl FieldLevel) bool {
  1784. field := fl.Field()
  1785. if field.Kind() == reflect.String {
  1786. _, err := language.Parse(field.String())
  1787. return err == nil
  1788. }
  1789. panic(fmt.Sprintf("Bad field type %T", field.Interface()))
  1790. }
  1791. // isIsoBicFormat is the validation function for validating if the current field's value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362
  1792. func isIsoBicFormat(fl FieldLevel) bool {
  1793. bicString := fl.Field().String()
  1794. return bicRegex.MatchString(bicString)
  1795. }