gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.28k stars 7.99k forks source link

Bug in "binding" parsing algorithm #3444

Open neopoleones opened 1 year ago

neopoleones commented 1 year ago

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?
rnotorni commented 1 year ago

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

jialechan commented 1 year ago

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