1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-03 18:35:08 +02:00

Fix baggage.NewMember to decode the accepted value (#3226)

* Fix baggage.NewMember to decode the accepted value

`value` is decoded and stored after validating the input parameters.

Corresponding test cases are modified so that we can make sure `value` is properly encoded before creating Member.

* fix md lint

* add function document to NewMember for value encoding and decoding

* remove redundant comments and fix CHANGELOG.md

* fix wrong PR number in the changelog

* fix wrong PR number

* fix md-lint

Co-authored-by: Chester Cheung <cheung.zhy.csu@gmail.com>
This commit is contained in:
ReStartercc
2022-10-19 03:45:04 +08:00
committed by GitHub
parent 1cbd4c2b77
commit 0963f59955
4 changed files with 42 additions and 7 deletions
+1
View File
@@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Fixed
- Fix function `baggage.NewMember` to decode the `value` parameter instead of directly use it according to the W3C specification. (#3226)
- Slice attributes of `attribute` package are now comparable based on their value, not instance. (#3108 #3252)
- Prometheus exporter will now cumulatively sum histogram buckets. (#3281)
- Export the sum of each histogram datapoint uniquely with the `go.opentelemetry.io/otel/exporters/otlpmetric` exporters. (#3284, #3293)
+11 -5
View File
@@ -250,8 +250,9 @@ type Member struct {
hasData bool
}
// NewMember returns a new Member from the passed arguments. An error is
// returned if the created Member would be invalid according to the W3C
// NewMember returns a new Member from the passed arguments. The key will be
// used directly while the value will be url decoded after validation. An error
// is returned if the created Member would be invalid according to the W3C
// Baggage specification.
func NewMember(key, value string, props ...Property) (Member, error) {
m := Member{
@@ -263,7 +264,11 @@ func NewMember(key, value string, props ...Property) (Member, error) {
if err := m.validate(); err != nil {
return newInvalidMember(), err
}
decodedValue, err := url.QueryUnescape(value)
if err != nil {
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
}
m.value = decodedValue
return m, nil
}
@@ -328,8 +333,9 @@ func parseMember(member string) (Member, error) {
return Member{key: key, value: value, properties: props, hasData: true}, nil
}
// validate ensures m conforms to the W3C Baggage specification, returning an
// error otherwise.
// validate ensures m conforms to the W3C Baggage specification.
// A key is just an ASCII string, but a value must be URL encoded UTF-8,
// returning an error otherwise.
func (m Member) validate() error {
if !m.hasData {
return fmt.Errorf("%w: %q", errInvalidMember, m)
+28
View File
@@ -768,6 +768,23 @@ func TestNewMember(t *testing.T) {
}
assert.Equal(t, expected, m)
// wrong value with wrong decoding
val = "%zzzzz"
_, err = NewMember(key, val, p)
assert.ErrorIs(t, err, errInvalidValue)
// value should be decoded
val = "%3B"
m, err = NewMember(key, val, p)
expected = Member{
key: key,
value: ";",
properties: properties{{key: "foo", hasData: true}},
hasData: true,
}
assert.NoError(t, err)
assert.Equal(t, expected, m)
// Ensure new member is immutable.
p.key = "bar"
assert.Equal(t, expected, m)
@@ -784,6 +801,17 @@ func TestPropertiesValidate(t *testing.T) {
assert.NoError(t, p.validate())
}
func TestMemberString(t *testing.T) {
// normal key value pair
member, _ := NewMember("key", "value")
memberStr := member.String()
assert.Equal(t, memberStr, "key=value")
// encoded key
member, _ = NewMember("key", "%3B")
memberStr = member.String()
assert.Equal(t, memberStr, "key=%3B")
}
var benchBaggage Baggage
func BenchmarkNew(b *testing.B) {
+2 -2
View File
@@ -17,6 +17,7 @@ package propagation_test
import (
"context"
"net/http"
"net/url"
"strings"
"testing"
@@ -46,8 +47,7 @@ func (m member) Member(t *testing.T) baggage.Member {
}
props = append(props, p)
}
bMember, err := baggage.NewMember(m.Key, m.Value, props...)
bMember, err := baggage.NewMember(m.Key, url.QueryEscape(m.Value), props...)
if err != nil {
t.Fatal(err)
}