• With issues:
  • Use the search tool before opening a new issue.
  • Please provide source code and commit sha if you found a bug.
  • Review existing issues and provide feedback or react to them.

Description

https://github.com/gin-gonic/gin/pull/2755 only fixes the slice bounds out of range panic. Route params are not be handled correctly in test context. I can explain what happened.

When call CreateTestContext, it will call New function to create a Engine. The maxParams will be the default value 0.

https://github.com/gin-gonic/gin/blob/9c27053243cb24ecc90d01c8ff379bd98fed9c8e/test_helpers.go#L9-L16

Then allocateContext init the Params. The cap and len are both 0. params is the reference of Params.

https://github.com/gin-gonic/gin/blob/9c27053243cb24ecc90d01c8ff379bd98fed9c8e/gin.go#L202-L205

Even if we add a route, it only incrs the maxParams value, it has not effect on the Context we created by CreateTestContext before. The condition will always be false.

https://github.com/gin-gonic/gin/blob/9c27053243cb24ecc90d01c8ff379bd98fed9c8e/tree.go#L462-L479

How to reproduce

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"

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

func main() {
    w := httptest.NewRecorder()
    ctx, engine := gin.CreateTestContext(w)
    engine.GET("/hello/:name", func(ctx *gin.Context) {
        fmt.Printf("Param name is %s\n", ctx.Param("name"))
        ctx.String(http.StatusOK, "Hello %s", ctx.Param("name"))
    })
    var err error
    ctx.Request, err = http.NewRequest(http.MethodGet, "/hello/world", nil)
    if err != nil {
        panic(err)
    }
    engine.HandleContext(ctx)
}

Expectations

Get following output after running the code.

[GIN-debug] GET    /hello/:name              --> main.main.func1 (1 handlers)
Param name is world

Actual result

[GIN-debug] GET    /hello/:name              --> main.main.func1 (1 handlers)
Param name is 

ctx.Param("name") returns a empty string.

Environment

  • go version: go version go1.16 darwin/amd64
  • gin version (or commit ref): v1.7.2-0.20210704023713-9c27053243cb
  • operating system: macOs Big Sur 11.4, Darwin Kernel Version 20.5.0

Comment From: Hanaasagi

One way to fix this problem is check the cap of params everytime when we use.

图片

Comment From: Hanaasagi

Hello, Any thoughts on this?

Comment From: RoCry

Hello, Any thoughts on this?

@Hanaasagi We met the same issue and fixed it https://github.com/gin-gonic/gin/pull/2803, please feel free to leave suggestions.

Comment From: alochym01

@Hanaasagi i have same issue, is there any work around https://github.com/gin-gonic/gin/issues/2833

Comment From: jlaneve

Here's a workaround for now:

gin.SetMode(gin.TestMode)

w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)

c.Params = []gin.Param{gin.Param{Key: "k", Value: "v"}}

foo(c)

if w.Code != 200 {
    b, _ := ioutil.ReadAll(w.Body)
    t.Error(w.Code, string(b))
}

Comment From: appleboy

fixed in #2803 and released in v1.8.2