mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-02-09 13:37:12 +02:00
baggage: Fix Parse to validate member value before percent-decoding (#4755)
This commit is contained in:
parent
15f0ab964c
commit
43bd47de6e
@ -26,6 +26,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- Improve `go.opentelemetry.io/otel/propagation.TraceContext`'s performance. (#4721)
|
- Improve `go.opentelemetry.io/otel/propagation.TraceContext`'s performance. (#4721)
|
||||||
- Improve `go.opentelemetry.io/otel/baggage` performance. (#4743)
|
- Improve `go.opentelemetry.io/otel/baggage` performance. (#4743)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix `Parse` in `go.opentelemetry.io/otel/baggage` to validate member value before percent-decoding. (#4755)
|
||||||
|
|
||||||
## [1.21.0/0.44.0] 2023-11-16
|
## [1.21.0/0.44.0] 2023-11-16
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
@ -254,11 +254,7 @@ func parseMember(member string) (Member, error) {
|
|||||||
return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n)
|
return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var props properties
|
||||||
key, value string
|
|
||||||
props properties
|
|
||||||
)
|
|
||||||
|
|
||||||
keyValue, properties, found := strings.Cut(member, propertyDelimiter)
|
keyValue, properties, found := strings.Cut(member, propertyDelimiter)
|
||||||
if found {
|
if found {
|
||||||
// Parse the member properties.
|
// Parse the member properties.
|
||||||
@ -279,19 +275,19 @@ func parseMember(member string) (Member, error) {
|
|||||||
}
|
}
|
||||||
// "Leading and trailing whitespaces are allowed but MUST be trimmed
|
// "Leading and trailing whitespaces are allowed but MUST be trimmed
|
||||||
// when converting the header into a data structure."
|
// when converting the header into a data structure."
|
||||||
key = strings.TrimSpace(k)
|
key := strings.TrimSpace(k)
|
||||||
var err error
|
|
||||||
value, err = url.PathUnescape(strings.TrimSpace(v))
|
|
||||||
if err != nil {
|
|
||||||
return newInvalidMember(), fmt.Errorf("%w: %q", err, value)
|
|
||||||
}
|
|
||||||
if !validateKey(key) {
|
if !validateKey(key) {
|
||||||
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key)
|
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key)
|
||||||
}
|
}
|
||||||
if !validateValue(value) {
|
|
||||||
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
val := strings.TrimSpace(v)
|
||||||
|
if !validateValue(val) {
|
||||||
|
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, v)
|
||||||
|
}
|
||||||
|
value, err := url.PathUnescape(val)
|
||||||
|
if err != nil {
|
||||||
|
return newInvalidMember(), fmt.Errorf("%w: %v", errInvalidValue, err)
|
||||||
|
}
|
||||||
return Member{key: key, value: value, properties: props, hasData: true}, nil
|
return Member{key: key, value: value, properties: props, hasData: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,9 +384,9 @@ func TestBaggageParse(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "url encoded value",
|
name: "url encoded value",
|
||||||
in: "key1=val%252",
|
in: "key1=val%252%2C",
|
||||||
want: baggage.List{
|
want: baggage.List{
|
||||||
"key1": {Value: "val%2"},
|
"key1": {Value: "val%2,"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -414,6 +414,11 @@ func TestBaggageParse(t *testing.T) {
|
|||||||
in: "foo=\\",
|
in: "foo=\\",
|
||||||
err: errInvalidValue,
|
err: errInvalidValue,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid member: improper url encoded value",
|
||||||
|
in: "key1=val%",
|
||||||
|
err: errInvalidValue,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "invalid property: no key",
|
name: "invalid property: no key",
|
||||||
in: "foo=1;=v",
|
in: "foo=1;=v",
|
||||||
|
@ -47,7 +47,7 @@ func (m member) Member(t *testing.T) baggage.Member {
|
|||||||
}
|
}
|
||||||
props = append(props, p)
|
props = append(props, p)
|
||||||
}
|
}
|
||||||
bMember, err := baggage.NewMember(m.Key, url.QueryEscape(m.Value), props...)
|
bMember, err := baggage.NewMember(m.Key, url.PathEscape(m.Value), props...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -248,6 +248,55 @@ func TestInjectBaggageToHTTPReq(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBaggageInjectExtractRoundtrip(t *testing.T) {
|
||||||
|
propagator := propagation.Baggage{}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mems members
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "two simple values",
|
||||||
|
mems: members{
|
||||||
|
{Key: "key1", Value: "val1"},
|
||||||
|
{Key: "key2", Value: "val2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "values with escaped chars",
|
||||||
|
mems: members{
|
||||||
|
{Key: "key1", Value: "val3=4"},
|
||||||
|
{Key: "key2", Value: "mess,me%up"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with properties",
|
||||||
|
mems: members{
|
||||||
|
{Key: "key1", Value: "val1"},
|
||||||
|
{
|
||||||
|
Key: "key2",
|
||||||
|
Value: "val2",
|
||||||
|
Properties: []property{
|
||||||
|
{Key: "prop", Value: "1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
b := tt.mems.Baggage(t)
|
||||||
|
req, _ := http.NewRequest("GET", "http://example.com", nil)
|
||||||
|
ctx := baggage.ContextWithBaggage(context.Background(), b)
|
||||||
|
propagator.Inject(ctx, propagation.HeaderCarrier(req.Header))
|
||||||
|
|
||||||
|
ctx = propagator.Extract(context.Background(), propagation.HeaderCarrier(req.Header))
|
||||||
|
got := baggage.FromContext(ctx)
|
||||||
|
|
||||||
|
assert.Equal(t, b, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBaggagePropagatorGetAllKeys(t *testing.T) {
|
func TestBaggagePropagatorGetAllKeys(t *testing.T) {
|
||||||
var propagator propagation.Baggage
|
var propagator propagation.Baggage
|
||||||
want := []string{"baggage"}
|
want := []string{"baggage"}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user