0
1
mirror of https://github.com/golang/go synced 2025-08-15 02:26:40 +00:00

Revert "net/url: consider an empty base Path as equivalent to / in JoinPath"

This reverts commit a46285f8c2 (CL 469935).

Reason for revert: This breaks a variety of code inside Google
that seem representative of possible external real-world usage.

If we roll this forward again we should include a GODEBUG like
urljoinpathslash=0 to go back to the old behavior.

Change-Id: I6cd8e9888a0c088669dc5634418372252289e074
Reviewed-on: https://go-review.googlesource.com/c/go/+/571655
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
This commit is contained in:
Russ Cox
2024-03-14 13:50:37 +00:00
committed by Gopher Robot
parent be58fd0070
commit 4a1038fa52
2 changed files with 73 additions and 114 deletions

View File

@@ -1200,12 +1200,7 @@ func (u *URL) UnmarshalBinary(text []byte) error {
func (u *URL) JoinPath(elem ...string) *URL {
elem = append([]string{u.EscapedPath()}, elem...)
var p string
if elem[0] == "" {
// RequestURI converts an empty Path to /, so do the same
// here for consistency. See #58605.
elem[0] = "/"
p = path.Join(elem...)
} else if !strings.HasPrefix(elem[0], "/") {
if !strings.HasPrefix(elem[0], "/") {
// Return a relative path if u is relative,
// but ensure that it contains no ../ elements.
elem[0] = "/" + elem[0]

View File

@@ -2066,155 +2066,128 @@ func BenchmarkPathUnescape(b *testing.B) {
func TestJoinPath(t *testing.T) {
tests := []struct {
base string
elem []string
out string
wantPath string
wantRawPath string
base string
elem []string
out string
}{
{
base: "https://go.googlesource.com",
elem: []string{"go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com",
elem: []string{"go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com/a/b/c",
elem: []string{"../../../go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com/a/b/c",
elem: []string{"../../../go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com/",
elem: []string{"../go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com/",
elem: []string{"../go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com",
elem: []string{"../go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com",
elem: []string{"../go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com",
elem: []string{"../go", "../../go", "../../../go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com",
elem: []string{"../go", "../../go", "../../../go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com/../go",
elem: nil,
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com/../go",
elem: nil,
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com/",
elem: []string{"./go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com/",
elem: []string{"./go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com//",
elem: []string{"/go"},
out: "https://go.googlesource.com/go",
wantPath: "/go",
base: "https://go.googlesource.com//",
elem: []string{"/go"},
out: "https://go.googlesource.com/go",
},
{
base: "https://go.googlesource.com//",
elem: []string{"/go", "a", "b", "c"},
out: "https://go.googlesource.com/go/a/b/c",
wantPath: "/go/a/b/c",
base: "https://go.googlesource.com//",
elem: []string{"/go", "a", "b", "c"},
out: "https://go.googlesource.com/go/a/b/c",
},
{
base: "http://[fe80::1%en0]:8080/",
elem: []string{"/go"},
},
{
base: "https://go.googlesource.com",
elem: []string{"go/"},
out: "https://go.googlesource.com/go/",
wantPath: "/go/",
base: "https://go.googlesource.com",
elem: []string{"go/"},
out: "https://go.googlesource.com/go/",
},
{
base: "https://go.googlesource.com",
elem: []string{"go//"},
out: "https://go.googlesource.com/go/",
wantPath: "/go/",
base: "https://go.googlesource.com",
elem: []string{"go//"},
out: "https://go.googlesource.com/go/",
},
{
base: "https://go.googlesource.com",
elem: nil,
out: "https://go.googlesource.com/",
wantPath: "/",
base: "https://go.googlesource.com",
elem: nil,
out: "https://go.googlesource.com/",
},
{
base: "https://go.googlesource.com/",
elem: nil,
out: "https://go.googlesource.com/",
wantPath: "/",
base: "https://go.googlesource.com/",
elem: nil,
out: "https://go.googlesource.com/",
},
{
base: "https://go.googlesource.com/a%2fb",
elem: []string{"c"},
out: "https://go.googlesource.com/a%2fb/c",
wantPath: "/a/b/c",
wantRawPath: "/a%2fb/c",
base: "https://go.googlesource.com/a%2fb",
elem: []string{"c"},
out: "https://go.googlesource.com/a%2fb/c",
},
{
base: "https://go.googlesource.com/a%2fb",
elem: []string{"c%2fd"},
out: "https://go.googlesource.com/a%2fb/c%2fd",
wantPath: "/a/b/c/d",
wantRawPath: "/a%2fb/c%2fd",
base: "https://go.googlesource.com/a%2fb",
elem: []string{"c%2fd"},
out: "https://go.googlesource.com/a%2fb/c%2fd",
},
{
base: "https://go.googlesource.com/a/b",
elem: []string{"/go"},
out: "https://go.googlesource.com/a/b/go",
wantPath: "/a/b/go",
base: "https://go.googlesource.com/a/b",
elem: []string{"/go"},
out: "https://go.googlesource.com/a/b/go",
},
{
base: "/",
elem: nil,
out: "/",
wantPath: "/",
base: "/",
elem: nil,
out: "/",
},
{
base: "a",
elem: nil,
out: "a",
wantPath: "a",
base: "a",
elem: nil,
out: "a",
},
{
base: "a",
elem: []string{"b"},
out: "a/b",
wantPath: "a/b",
base: "a",
elem: []string{"b"},
out: "a/b",
},
{
base: "a",
elem: []string{"../b"},
out: "b",
wantPath: "b",
base: "a",
elem: []string{"../b"},
out: "b",
},
{
base: "a",
elem: []string{"../../b"},
out: "b",
wantPath: "b",
base: "a",
elem: []string{"../../b"},
out: "b",
},
{
base: "",
elem: []string{"a"},
out: "/a",
wantPath: "/a",
base: "",
elem: []string{"a"},
out: "a",
},
{
base: "",
elem: []string{"../a"},
out: "/a",
wantPath: "/a",
base: "",
elem: []string{"../a"},
out: "a",
},
}
for _, tt := range tests {
@@ -2234,14 +2207,5 @@ func TestJoinPath(t *testing.T) {
if out != tt.out || (err == nil) != (tt.out != "") {
t.Errorf("Parse(%q).JoinPath(%q) = %q, %v, want %q, %v", tt.base, tt.elem, out, err, tt.out, wantErr)
}
if u == nil {
continue
}
if got, want := u.Path, tt.wantPath; got != want {
t.Errorf("Parse(%q).JoinPath(%q).Path = %q, want %q", tt.base, tt.elem, got, want)
}
if got, want := u.RawPath, tt.wantRawPath; got != want {
t.Errorf("Parse(%q).JoinPath(%q).RawPath = %q, want %q", tt.base, tt.elem, got, want)
}
}
}