Skip to content

net/url: roundtripping url which contains certain special characters (<>{} ") fails #73549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JakeChampion opened this issue Apr 30, 2025 · 4 comments

Comments

@JakeChampion
Copy link

Go version

go version go1.24.0 darwin/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/re2/lib'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/jakechampion/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/jakechampion/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/8c/21q0xn6s5d34rp637j4s10f40000gn/T/go-build2305439960=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/jakechampion/code/netlify/stargate/go.mod'
GOMODCACHE='/Users/jakechampion/go/pkg/mod'
GONOPROXY='github.com/netlify'
GONOSUMDB='github.com/netlify'
GOOS='darwin'
GOPATH='/Users/jakechampion/go'
GOPRIVATE='github.com/netlify'
GOPROXY='https://proxy.golang.org/,direct'
GOROOT='/Users/jakechampion/go/pkg/mod/golang.org/[email protected]'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/jakechampion/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/jakechampion/go/pkg/mod/golang.org/[email protected]/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.24.0'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

https://go.dev/play/p/aFC9TP6bWBI

What did you see happen?

The output from the playground application:

http://www.google.com/foo<FOO/BAR%2Fbar.txt /foo%3CFOO/BAR/bar.txt http://www.google.com/foo%3CFOO/BAR/bar.txt
http://www.google.com/foo>FOO/BAR%2Fbar.txt /foo%3EFOO/BAR/bar.txt http://www.google.com/foo%3EFOO/BAR/bar.txt
http://www.google.com/foo{FOO/BAR%2Fbar.txt /foo%7BFOO/BAR/bar.txt http://www.google.com/foo%7BFOO/BAR/bar.txt
http://www.google.com/foo}FOO/BAR%2Fbar.txt /foo%7DFOO/BAR/bar.txt http://www.google.com/foo%7DFOO/BAR/bar.txt
http://www.google.com/foo FOO/BAR%2Fbar.txt /foo%20FOO/BAR/bar.txt http://www.google.com/foo%20FOO/BAR/bar.txt
http://www.google.com/foo"FOO/BAR%2Fbar.txt /foo%22FOO/BAR/bar.txt http://www.google.com/foo%22FOO/BAR/bar.txt

What did you expect to see?

I expected to see

http://www.google.com/foo<FOO/BAR%2Fbar.txt /foo%3CFOO/BAR%2Fbar.txt http://www.google.com/foo%3CFOO/BAR%2Fbar.txt
http://www.google.com/foo>FOO/BAR%2Fbar.txt /foo%3EFOO/BAR%2Fbar.txt http://www.google.com/foo%3EFOO/BAR%2Fbar.txt
http://www.google.com/foo{FOO/BAR%2Fbar.txt /foo%7BFOO/BAR%2Fbar.txt http://www.google.com/foo%7BFOO/BAR%2Fbar.txt
http://www.google.com/foo}FOO/BAR%2Fbar.txt /foo%7DFOO/BAR%2Fbar.txt http://www.google.com/foo%7DFOO/BAR%2Fbar.txt
http://www.google.com/foo FOO/BAR%2Fbar.txt /foo%20FOO/BAR%2Fbar.txt http://www.google.com/foo%20FOO/BAR%2Fbar.txt
http://www.google.com/foo"FOO/BAR%2Fbar.txt /foo%22FOO/BAR%2Fbar.txt http://www.google.com/foo%22FOO/BAR%2Fbar.txt
@seankhliao
Copy link
Member

I believe this is working as intended. We only guarantee that the output is a valid encoding of the url, not that the exact input will be returned.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Apr 30, 2025
@JakeChampion
Copy link
Author

@seankhliao I understand, however the returned encoding is semantically different to the input encoding, due to the path segment BAR%2Fbar.txt being transformed into two path segments BAR/bar.txt, this incorrect transformation is also true for the EscapedPath() method, which the Go Playground link in the original issue comment shows. The documentation states that:

This distinction is rarely important, but when it is, the code should use the [URL.EscapedPath] method, which preserves the original encoding of Path`

@seankhliao
Copy link
Member

According to RFC 3986, we consider them semantically equivalent https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2

Our position remains unchanged from #14815 (comment) , use RawPath if you wish to use some half decoded form, otherwise Path / EscapedPath will produce fully unescaped or escaped forms.

@JakeChampion
Copy link
Author

From datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2:

These URIs should be normalized by decoding any percent-encoded octet that corresponds to an unreserved character, as described in Section 2.3.

The character in question here is / (percent encoded as %2F) which is not within the unreserved charactes and so should not be getting percent decoded here - however we can see that EscapedPath() may sometimes decode the %2F as shown by the example application

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants