gin
gin copied to clipboard
Bind recursion struct param fatal exit
Description
use c.Bind() for recursion struct param, output fatal.
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
"net/http"
"net/http/httptest"
)
type ParamA struct {
B *ParamB
}
type ParamB struct {
A *ParamA
}
func setupRouter() *gin.Engine {
r := gin.Default()
r.GET("/test", func(c *gin.Context) {
param := new(ParamA)
if err := c.Bind(param); err != nil {
panic(err)
}
c.JSON(http.StatusOK, param)
})
return r
}
func main() {
router := setupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/test", nil)
router.ServeHTTP(w, req)
}
output:
gc 1 @0.021s 2%: 0+4.7+0 ms clock, 0+0/5.3/2.3+0 ms cpu, 3->3->1 MB, 4 MB goal, 8 MB stacks, 0 MB globals, 8 P
gc 2 @0.689s 3%: 0+209+0 ms clock, 0+0/218/21+0 ms cpu, 11->11->6 MB, 12 MB goal, 465 MB stacks, 0 MB globals, 8 P
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc0203c1418 stack=[0xc0203c0000, 0xc0403c0000]
fatal error: stack overflow
runtime stack:
runtime.throw({0x1384d2a?, 0x17d69ff7f0?})
C:/Program Files/Go/src/runtime/panic.go:1023 +0x65 fp=0x17d69ff7b0 sp=0x17d69ff780 pc=0xfdc025
runtime.newstack()
C:/Program Files/Go/src/runtime/stack.go:1103 +0x5cc fp=0x17d69ff960 sp=0x17d69ff7b0 pc=0xff5e2c
runtime.morestack()
C:/Program Files/Go/src/runtime/asm_amd64.s:616 +0x79 fp=0x17d69ff968 sp=0x17d69ff960 pc=0x10131b9
goroutine 1 gp=0xc00004e000 m=3 mp=0xc00005b008 [running]:
github.com/gin-gonic/gin/binding.setByForm({0x131d7e0?, 0xc000e7bb08?, 0x199?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:167 +0x47b fp=0xc0203c1428 sp=0xc0203c1420 pc=0x12b4cbb
github.com/gin-gonic/gin/binding.formSource.TrySet(0x0?, {0x131d7e0?, 0xc000e7bb08?, 0x0?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:73 +0x87 fp=0xc0203c14e8 sp=0xc0203c1428 pc=0x12b3e27
github.com/gin-gonic/gin/binding.tryToSetValue({0x131d7e0?, 0xc000e7bb08?, 0x0?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:164 +0x265 fp=0xc0203c15f8 sp=0xc0203c14e8 pc=0x12b47c5
github.com/gin-gonic/gin/binding.mapping({0x131d7e0?, 0xc000e7bb08?, 0x103b14f?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:106 +0x148 fp=0xc0203c1768 sp=0xc0203c15f8 pc=0x12b4168
github.com/gin-gonic/gin/binding.mapping({0x12ec700?, 0xc000e7bb00?, 0x0?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:95 +0x2e5 fp=0xc0203c18d8 sp=0xc0203c1768 pc=0x12b4305
github.com/gin-gonic/gin/binding.mapping({0x131d860?, 0xc000e7bb00?, 0x103b14f?}, {{0x12cf004, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec6c0}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:124 +0x498 fp=0xc0203c1a48 sp=0xc0203c18d8 pc=0x12b44b8
github.com/gin-gonic/gin/binding.mapping({0x12ec6c0?, 0xc000e7baf8?, 0x0?}, {{0x12cf004, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec6c0}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:95 +0x2e5 fp=0xc0203c1bb8 sp=0xc0203c1a48 pc=0x12b4305
github.com/gin-gonic/gin/binding.mapping({0x131d7e0?, 0xc000e7baf8?, 0x103b14f?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:124 +0x498 fp=0xc0203c1d28 sp=0xc0203c1bb8 pc=0x12b44b8
github.com/gin-gonic/gin/binding.mapping({0x12ec700?, 0xc000e7baf0?, 0x0?}, {{0x12cf007, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec700}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:95 +0x2e5 fp=0xc0203c1e98 sp=0xc0203c1d28 pc=0x12b4305
github.com/gin-gonic/gin/binding.mapping({0x131d860?, 0xc000e7baf0?, 0x103b14f?}, {{0x12cf004, 0x1}, {0x0, 0x0}, {0x142f9c0, 0x12ec6c0}, {0x0, ...}, ...}, ...)
D:/var/GOPATH/pkg/mod/github.com/gin-gonic/[email protected]/binding/form_mapping.go:124 +0x498 fp=0xc0203c2008 sp=0xc0203c1e98 pc=0x12b44b8
...
Expectations
Don't fatal exit, limit recursion deep number.
Environment
- go version: 1.22.1
- gin version (or commit ref): v1.9.1
- operating system: Windows/Linux
You should not have structs with circular dependencies. You don't conform to the Single Responsibility Principle.