1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-28 21:09:17 +02:00

Use url.PathUnescape rather than url.QueryUnescape in baggage parsing (#4667)

* Use url.PathUnescape rather than url.QueryUnescape

I believe this addresses the majority of the cases described in
https://github.com/open-telemetry/opentelemetry-go/issues/3601

Golang's url.QueryUnescape will render url _path_ elements (e.g. /, +)
as spaces: `foo+bar` is rendered as `foo bar`.  Path elements are (as I
read the spec) legal W3C baggage values, and replacing them with spaces
fails the value validation regex.

url.PathEscape allows path elements through unmolested.

Signed-off-by: Nathan J. Mehl <n@oden.io>

* Update CHANGELOG.md

address comments

Co-authored-by: Robert Pająk <pellared@hotmail.com>

---------

Signed-off-by: Nathan J. Mehl <n@oden.io>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
This commit is contained in:
Nathan J Mehl 2023-10-31 18:02:17 -04:00 committed by GitHub
parent ce7b40afa9
commit bdb9322ebd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 2 deletions

View File

@ -57,6 +57,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Fixed
- Fix improper parsing of characters such us `+`, `\` by `Parse` in `go.opentelemetry.io/otel/baggage` as they were rendered as a whitespace. (#4667)
- In `go.opentelemetry.op/otel/exporters/prometheus`, the exporter no longer `Collect`s metrics after `Shutdown` is invoked. (#4648)
## [1.19.0/0.42.0/0.0.7] 2023-09-28

View File

@ -254,7 +254,7 @@ func NewMember(key, value string, props ...Property) (Member, error) {
if err := m.validate(); err != nil {
return newInvalidMember(), err
}
decodedValue, err := url.QueryUnescape(value)
decodedValue, err := url.PathUnescape(value)
if err != nil {
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
}
@ -301,7 +301,7 @@ func parseMember(member string) (Member, error) {
// when converting the header into a data structure."
key = strings.TrimSpace(k)
var err error
value, err = url.QueryUnescape(strings.TrimSpace(v))
value, err = url.PathUnescape(strings.TrimSpace(v))
if err != nil {
return newInvalidMember(), fmt.Errorf("%w: %q", err, value)
}

View File

@ -275,6 +275,48 @@ func TestBaggageParse(t *testing.T) {
"foo": {Value: "1"},
},
},
{
name: "single member no properties plus",
in: "foo=1+1",
want: baggage.List{
"foo": {Value: "1+1"},
},
},
{
name: "single member no properties plus encoded",
in: "foo=1%2B1",
want: baggage.List{
"foo": {Value: "1+1"},
},
},
{
name: "single member no properties slash",
in: "foo=1/1",
want: baggage.List{
"foo": {Value: "1/1"},
},
},
{
name: "single member no properties slash encoded",
in: "foo=1%2F1",
want: baggage.List{
"foo": {Value: "1/1"},
},
},
{
name: "single member no properties equals",
in: "foo=1=1",
want: baggage.List{
"foo": {Value: "1=1"},
},
},
{
name: "single member no properties equals encoded",
in: "foo=1%3D1",
want: baggage.List{
"foo": {Value: "1=1"},
},
},
{
name: "single member with spaces",
in: " foo \t= 1\t\t ",
@ -440,6 +482,13 @@ func TestBaggageString(t *testing.T) {
"foo": {Value: "1=1"},
},
},
{
name: "plus",
out: "foo=1%2B1",
baggage: baggage.List{
"foo": {Value: "1+1"},
},
},
{
name: "single member empty value with properties",
out: "foo=;red;state=on",