Skip to content

[Bug] UnescapePathValues = false still unescapes path values #4033

@ALX99

Description

@ALX99

Description

Even despite setting

UnescapePathValues = false
UseRawPath = true

the URL path value is still unescaped.

This is probably related to that gin sometimes routes request based on either URL.Path or URL.RawPath when UseRawPath is true. URL.RawPath is not always populated (See golang/go#33596), so when it is missing, it falls back to route on URL.Path instead. To me, gin should not fall back to using URL.Path since this path is unescaped, and not raw when UseRawPath is enabled.

Reference:

gin/gin.go

Lines 650 to 653 in cc4e114

if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
rPath = c.Request.URL.RawPath
unescape = engine.UnescapePathValues
}

To fix this issue, gin should use URL.EscapedPath() which should return URL.RawPath if it is non empty, or compute an escaped path if it is empty.

It is possible to work around this issue by ensuring that URL.RawPath always exists when the gin router handles the request.

Example Workaround

package main

import (
	"net/http"

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

func main() {
	r := gin.Default()

	r.GET("/testy/:name", func(c *gin.Context) {
		n := c.Param("name")
		c.Writer.Write([]byte(n))
	})

	r.UnescapePathValues = false
	r.UseRawPath = true

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		req.URL.RawPath = req.URL.EscapedPath()
		r.Handler().ServeHTTP(w, req)
	})

	http.ListenAndServe(":8181", mux)
}

How to reproduce

package main

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

func main() {
	r := gin.Default()

	r.GET("/testy/:name", func(c *gin.Context) {
		n := c.Param("name")
		c.Writer.Write([]byte(n))
	})

	r.UnescapePathValues = false
	r.UseRawPath = true
	r.Run(":8181")
}

Expectations

$ curl 'localhost:8181/testy/hi%2Fworld'
hi%2Fworld
$ curl 'localhost:8181/testy/%E3%81%82'
%E3%81%82

Actual result

$ curl 'localhost:8181/testy/hi%2Fworld'
hi%2Fworld
$ curl 'localhost:8181/testy/%E3%81%82'
あ

Environment

  • go version: 1.23.0
  • gin version (or commit ref): v1.10.0
  • operating system: macOS Sequoia

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions