-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Open
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Description
go version: go1.24, go1.25, dev
What did you do?
// Go Playground - https://go.dev/play/p/joiLsJ4cjNh?v=gotip
func main() {
u, err := url.JoinPath("/qwerty", "a", "b", "100%")
if err != nil {
panic(err)
}
fmt.Println(u)
// Expected: /qwerty/a/b/100%25
// Got: /qwerty
}
This behavior is caused by (*URL).JoinPath
ignoring an error returned by (*URL).setPath
- invalid URL escape "%"
in this case.
func (u *URL) JoinPath(elem ...string) *URL {
...
url := *u
url.setPath(p) // <--
return &url
}
Potential fix
I have a potential fix for this bug:
func (u *URL) JoinPath(elem ...string) *URL {
+ for i := range elem {
+ if _, err := unescape(elem[i], encodePath); err != nil {
+ elem[i] = escape(elem[i], encodePath)
+ }
+ }
+
elem = append([]string{u.EscapedPath()}, elem...)
...
return &url
}
It passes all existing tests in TestJoinPath
, plus a new ones:
{
base: "/",
elem: []string{"a", "b", "100%"},
out: "/a/b/100%25",
},
{
base: "/",
elem: []string{"/a/b/100%"},
out: "/a/b/100%25",
},
Though, I am not sure whether this fix breaks any existing code or has any side-effects.
Metadata
Metadata
Assignees
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.