Skip to content

Commit b7dbb42

Browse files
authored
fix(attrs): use base-10 only for int parsing - prevent hex/octal coercion (#24)
strconv.ParseInt with base 0 auto-detects hex (0x), octal (0o), and binary (0b) prefixes, causing attribute values like "0x0" and "0xFF" to silently parse as integers instead of remaining strings. Users passing hex strings as attribute values got unexpected type coercion. Fixes #373 🤖 Claude <claude@anthropic.com>
1 parent 7cfc3c1 commit b7dbb42

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

otlpclient/protobuf_span.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ func StringMapAttrsToProtobuf(attributes map[string]string) []*commonpb.KeyValue
164164
for k, v := range attributes {
165165
av := new(commonpb.AnyValue)
166166

167-
// try to parse as numbers, and fall through to string
168-
if i, err := strconv.ParseInt(v, 0, 64); err == nil {
167+
// try to parse as decimal numbers, and fall through to string
168+
// base 10 only: base 0 would auto-detect hex/octal prefixes (#373)
169+
if i, err := strconv.ParseInt(v, 10, 64); err == nil {
169170
av.Value = &commonpb.AnyValue_IntValue{IntValue: i}
170171
} else if f, err := strconv.ParseFloat(v, 64); err == nil {
171172
av.Value = &commonpb.AnyValue_DoubleValue{DoubleValue: f}

otlpclient/protobuf_span_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ func TestCliAttrsToOtel(t *testing.T) {
192192
"test 5 - bool, false": "false",
193193
"test 6 - bool, True": "True",
194194
"test 7 - bool, False": "False",
195+
"test 8 - hex string": "0x0",
196+
"test 9 - hex string2": "0xFF",
197+
"test 10 - octal str": "0o777",
195198
}
196199

197200
otelAttrs := StringMapAttrsToProtobuf(testAttrs)
@@ -228,6 +231,21 @@ func TestCliAttrsToOtel(t *testing.T) {
228231
if attr.Value.GetBoolValue() != false {
229232
t.Errorf("expected value '%s' for key '%s' but got %t", testAttrs[key], key, attr.Value.GetBoolValue())
230233
}
234+
case "test 8 - hex string":
235+
// #373: 0x0 should be treated as a string, not parsed as hex int
236+
if attr.Value.GetStringValue() != "0x0" {
237+
t.Errorf("expected string value '0x0' for key '%s' but got parsed as different type", key)
238+
}
239+
case "test 9 - hex string2":
240+
// #373: 0xFF should be treated as a string, not parsed as hex int
241+
if attr.Value.GetStringValue() != "0xFF" {
242+
t.Errorf("expected string value '0xFF' for key '%s' but got parsed as different type", key)
243+
}
244+
case "test 10 - octal str":
245+
// 0o777 should be treated as a string, not parsed as octal int
246+
if attr.Value.GetStringValue() != "0o777" {
247+
t.Errorf("expected string value '0o777' for key '%s' but got parsed as different type", key)
248+
}
231249
}
232250
}
233251
}

0 commit comments

Comments
 (0)