diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b79b2b4..5261ba19d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/baggage/baggage.go b/baggage/baggage.go index 9e6b3b7b5..84532cb1d 100644 --- a/baggage/baggage.go +++ b/baggage/baggage.go @@ -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) } diff --git a/baggage/baggage_test.go b/baggage/baggage_test.go index 2b98beace..4bac6707e 100644 --- a/baggage/baggage_test.go +++ b/baggage/baggage_test.go @@ -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",