From 1cd4caee22fe945a2a1bb425e451e63df81c8223 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Wed, 12 Jul 2023 12:59:22 +0800 Subject: [PATCH] fix(Context.Bind): should escape special char in path Other famous frameworks, such as expressjs or rails, will unescape the path params. We should follow the industry convention too. --- bind.go | 8 +++++++- bind_test.go | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/bind.go b/bind.go index 374a2aec5..8009877b4 100644 --- a/bind.go +++ b/bind.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net/http" + "net/url" "reflect" "strconv" "strings" @@ -35,7 +36,12 @@ func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error { values := c.ParamValues() params := map[string][]string{} for i, name := range names { - params[name] = []string{values[i]} + escaped, err := url.QueryUnescape(values[i]) + if err != nil { + return err + } + + params[name] = []string{escaped} } if err := b.bindData(i, params, "param"); err != nil { return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) diff --git a/bind_test.go b/bind_test.go index c35283dcf..6ea2a9734 100644 --- a/bind_test.go +++ b/bind_test.go @@ -468,6 +468,19 @@ func TestBindParam(t *testing.T) { assert.Equal(t, "Jon Snow", u.Name) } + // Bind param with escaped characters + { + c := e.NewContext(req, rec) + c.SetPath("/users/:name") + c.SetParamNames("name") + c.SetParamValues("John%2FSnow") + + err := c.Bind(u) + if assert.NoError(t, err) { + assert.Equal(t, "John/Snow", u.Name) + } + } + // Second test for the absence of a param c2 := e.NewContext(req, rec) c2.SetPath("/users/:id")