Description

Gin has a problem with parsing complex structural tags like a:"b, c". It takes into account gaps in the validation name, which leads to "undefined validation function" panic.

Method: parseFieldTagsRecursive (or upper)

How to reproduce

  1. Pick the code from https://gin-gonic.com/docs/examples/bind-uri/
  2. Add a gap
package main

import "github.com/gin-gonic/gin"

type Person struct {
    ID   string `uri:"id" binding:"required, uuid"` // "required,uuid" by default
    Name string `uri:"name" binding:"required"`
}

func main() {
    route := gin.Default()
    route.GET("/:name/:id", func(c *gin.Context) {
        var person Person
        if err := c.ShouldBindUri(&person); err != nil {
            c.JSON(400, gin.H{"msg": err})
            return
        }
        c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
    })
    route.Run(":8088")
}

Expectations

Gap is handled correctly and removed

$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
....

// other screen
[GIN] 2022/12/20 - 16:27:41 | 200 |         152µs |       127.0.0.1 | GET      "/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3"

Actual result

$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
...

// other screen
2022/12/20 16:28:08 [Recovery] 2022/12/20 - 16:28:08 panic recovered:
GET /thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3 HTTP/1.1
Host: localhost:8088
Accept: */*
User-Agent: curl/7.84.0

Undefined validation function ' uuid' on field 'ID'

Environment

  • go version: go1.18.5 darwin/arm64
  • gin version (or commit ref): gin v1.8.1
  • operating system: darwin

Possible fix:

trim spaces?

Comment From: rnotorni

I think there is a problem with the validator package

gin binding uses validator.

https://github.com/gin-gonic/gin/blob/51aea73ba0f125f6cacc3b4b695efdf21d9c634f/binding/default_validator.go#L95

If we want to allow it, I think we need to trim spaces below.

https://github.com/go-playground/validator/blob/v10.10.0/cache.go#L172

Comment From: jialechan

I think the original design is more in line with the principle of Fail-fast