Skip to content

Commit 5e36f55

Browse files
dmathieucarsoniprockdabootChrsMark
authored
[exporter/elasticsearch] [chore] fix lint issues with golangci-lint 1.62 (#36798)
#### Description The golangci-lint upgrades causes a lot gosec issues due to a new check for integer conversion overflow. This PR checks for integer overflows within the elasticsearch exporter package. #### Link to tracking issue Related: #36638 --------- Co-authored-by: Carson Ip <[email protected]> Co-authored-by: Tim Rühsen <[email protected]> Co-authored-by: Christos Markou <[email protected]>
1 parent 179d5bb commit 5e36f55

File tree

5 files changed

+53
-24
lines changed

5 files changed

+53
-24
lines changed

exporter/elasticsearchexporter/internal/exphistogram/exphistogram.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ func ToTDigest(dp pmetric.ExponentialHistogramDataPoint) (counts []int64, values
4141
}
4242
lb := -LowerBoundary(offset+i+1, scale)
4343
ub := -LowerBoundary(offset+i, scale)
44-
counts = append(counts, int64(count))
44+
counts = append(counts, safeUint64ToInt64(count))
4545
values = append(values, lb+(ub-lb)/2)
4646
}
4747

4848
if zeroCount := dp.ZeroCount(); zeroCount != 0 {
49-
counts = append(counts, int64(zeroCount))
49+
counts = append(counts, safeUint64ToInt64(zeroCount))
5050
values = append(values, 0)
5151
}
5252

@@ -59,8 +59,16 @@ func ToTDigest(dp pmetric.ExponentialHistogramDataPoint) (counts []int64, values
5959
}
6060
lb := LowerBoundary(offset+i, scale)
6161
ub := LowerBoundary(offset+i+1, scale)
62-
counts = append(counts, int64(count))
62+
counts = append(counts, safeUint64ToInt64(count))
6363
values = append(values, lb+(ub-lb)/2)
6464
}
6565
return
6666
}
67+
68+
func safeUint64ToInt64(v uint64) int64 {
69+
if v > math.MaxInt64 {
70+
return math.MaxInt64
71+
} else {
72+
return int64(v) // nolint:goset // overflow checked
73+
}
74+
}

exporter/elasticsearchexporter/internal/objmodel/objmodel.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@ type field struct {
6060

6161
// Value type that can be added to a Document.
6262
type Value struct {
63-
kind Kind
64-
primitive uint64
65-
dbl float64
66-
str string
67-
arr []Value
68-
doc Document
69-
ts time.Time
63+
kind Kind
64+
ui uint64
65+
i int64
66+
dbl float64
67+
str string
68+
arr []Value
69+
doc Document
70+
ts time.Time
7071
}
7172

7273
// Kind represent the internal kind of a value stored in a Document.
@@ -77,6 +78,7 @@ const (
7778
KindNil Kind = iota
7879
KindBool
7980
KindInt
81+
KindUInt
8082
KindDouble
8183
KindString
8284
KindArr
@@ -168,6 +170,11 @@ func (doc *Document) AddInt(key string, value int64) {
168170
doc.Add(key, IntValue(value))
169171
}
170172

173+
// AddUInt adds an unsigned integer value to the document.
174+
func (doc *Document) AddUInt(key string, value uint64) {
175+
doc.Add(key, UIntValue(value))
176+
}
177+
171178
// AddAttributes expands and flattens all key-value pairs from the input attribute map into
172179
// the document.
173180
func (doc *Document) AddAttributes(key string, attributes pcommon.Map) {
@@ -424,7 +431,10 @@ func (doc *Document) iterJSONDedot(w *json.Visitor, otel bool) error {
424431
func StringValue(str string) Value { return Value{kind: KindString, str: str} }
425432

426433
// IntValue creates a new value from an integer.
427-
func IntValue(i int64) Value { return Value{kind: KindInt, primitive: uint64(i)} }
434+
func IntValue(i int64) Value { return Value{kind: KindInt, i: i} }
435+
436+
// UIntValue creates a new value from an unsigned integer.
437+
func UIntValue(i uint64) Value { return Value{kind: KindUInt, ui: i} }
428438

429439
// DoubleValue creates a new value from a double value..
430440
func DoubleValue(d float64) Value { return Value{kind: KindDouble, dbl: d} }
@@ -435,7 +445,7 @@ func BoolValue(b bool) Value {
435445
if b {
436446
v = 1
437447
}
438-
return Value{kind: KindBool, primitive: v}
448+
return Value{kind: KindBool, ui: v}
439449
}
440450

441451
// ArrValue combines multiple values into an array value.
@@ -519,9 +529,11 @@ func (v *Value) iterJSON(w *json.Visitor, dedot bool, otel bool) error {
519529
case KindNil:
520530
return w.OnNil()
521531
case KindBool:
522-
return w.OnBool(v.primitive == 1)
532+
return w.OnBool(v.ui == 1)
523533
case KindInt:
524-
return w.OnInt64(int64(v.primitive))
534+
return w.OnInt64(v.i)
535+
case KindUInt:
536+
return w.OnUint64(v.ui)
525537
case KindDouble:
526538
if math.IsNaN(v.dbl) || math.IsInf(v.dbl, 0) {
527539
// NaN and Inf are undefined for JSON. Let's serialize to "null"

exporter/elasticsearchexporter/internal/objmodel/objmodel_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ func TestValue_Serialize(t *testing.T) {
379379
"bool value: true": {value: BoolValue(true), want: "true"},
380380
"bool value: false": {value: BoolValue(false), want: "false"},
381381
"int value": {value: IntValue(42), want: "42"},
382+
"uint value": {value: UIntValue(42), want: "42"},
382383
"double value: 3.14": {value: DoubleValue(3.14), want: "3.14"},
383384
"double value: 1.0": {value: DoubleValue(1.0), want: "1.0"},
384385
"NaN is undefined": {value: DoubleValue(math.NaN()), want: "null"},

exporter/elasticsearchexporter/model.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ func (m *encodeModel) upsertMetricDataPointValueOTelMode(documents map[uint32]ob
349349

350350
if dp.HasMappingHint(hintDocCount) {
351351
docCount := dp.DocCount()
352-
document.AddInt("_doc_count", int64(docCount))
352+
document.AddUInt("_doc_count", docCount)
353353
}
354354

355355
switch value.Type() {
@@ -387,7 +387,7 @@ func (dp summaryDataPoint) Value() (pcommon.Value, error) {
387387
vm := pcommon.NewValueMap()
388388
m := vm.Map()
389389
m.PutDouble("sum", dp.Sum())
390-
m.PutInt("value_count", int64(dp.Count()))
390+
m.PutInt("value_count", safeUint64ToInt64(dp.Count()))
391391
return vm, nil
392392
}
393393

@@ -413,7 +413,7 @@ func (dp exponentialHistogramDataPoint) Value() (pcommon.Value, error) {
413413
vm := pcommon.NewValueMap()
414414
m := vm.Map()
415415
m.PutDouble("sum", dp.Sum())
416-
m.PutInt("value_count", int64(dp.Count()))
416+
m.PutInt("value_count", safeUint64ToInt64(dp.Count()))
417417
return vm, nil
418418
}
419419

@@ -460,7 +460,7 @@ func (dp histogramDataPoint) Value() (pcommon.Value, error) {
460460
vm := pcommon.NewValueMap()
461461
m := vm.Map()
462462
m.PutDouble("sum", dp.Sum())
463-
m.PutInt("value_count", int64(dp.Count()))
463+
m.PutInt("value_count", safeUint64ToInt64(dp.Count()))
464464
return vm, nil
465465
}
466466
return histogramToValue(dp.HistogramDataPoint)
@@ -518,7 +518,7 @@ func histogramToValue(dp pmetric.HistogramDataPoint) (pcommon.Value, error) {
518518
value = explicitBounds.At(i-1) + (explicitBounds.At(i)-explicitBounds.At(i-1))/2.0
519519
}
520520

521-
counts.AppendEmpty().SetInt(int64(count))
521+
counts.AppendEmpty().SetInt(safeUint64ToInt64(count))
522522
values.AppendEmpty().SetDouble(value)
523523
}
524524

@@ -674,7 +674,7 @@ func (m *encodeModel) encodeSpanOTelMode(resource pcommon.Resource, resourceSche
674674
document.AddSpanID("parent_span_id", span.ParentSpanID())
675675
document.AddString("name", span.Name())
676676
document.AddString("kind", span.Kind().String())
677-
document.AddInt("duration", int64(span.EndTimestamp()-span.StartTimestamp()))
677+
document.AddUInt("duration", uint64(span.EndTimestamp()-span.StartTimestamp()))
678678

679679
m.encodeAttributesOTelMode(&document, span.Attributes())
680680

@@ -985,7 +985,7 @@ func valueHash(h hash.Hash, v pcommon.Value) {
985985
h.Write(buf)
986986
case pcommon.ValueTypeInt:
987987
buf := make([]byte, 8)
988-
binary.LittleEndian.PutUint64(buf, uint64(v.Int()))
988+
binary.LittleEndian.PutUint64(buf, uint64(v.Int())) // nolint:gosec // Overflow assumed. We prefer having high integers over zero.
989989
h.Write(buf)
990990
case pcommon.ValueTypeBytes:
991991
h.Write(v.Bytes().AsRaw())
@@ -1074,3 +1074,11 @@ func mergeGeolocation(attributes pcommon.Map) {
10741074
}
10751075
}
10761076
}
1077+
1078+
func safeUint64ToInt64(v uint64) int64 {
1079+
if v > math.MaxInt64 {
1080+
return math.MaxInt64
1081+
} else {
1082+
return int64(v) // nolint:goset // overflow checked
1083+
}
1084+
}

exporter/elasticsearchexporter/model_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,8 +1109,8 @@ func TestEncodeLogOtelMode(t *testing.T) {
11091109
// helper function that creates the OTel LogRecord from the test structure
11101110
func createTestOTelLogRecord(t *testing.T, rec OTelRecord) (plog.LogRecord, pcommon.InstrumentationScope, pcommon.Resource) {
11111111
record := plog.NewLogRecord()
1112-
record.SetTimestamp(pcommon.Timestamp(uint64(rec.Timestamp.UnixNano())))
1113-
record.SetObservedTimestamp(pcommon.Timestamp(uint64(rec.ObservedTimestamp.UnixNano())))
1112+
record.SetTimestamp(pcommon.Timestamp(uint64(rec.Timestamp.UnixNano()))) //nolint:gosec // this input is controlled by tests
1113+
record.SetObservedTimestamp(pcommon.Timestamp(uint64(rec.ObservedTimestamp.UnixNano()))) //nolint:gosec // this input is controlled by tests
11141114

11151115
record.SetTraceID(pcommon.TraceID(rec.TraceID))
11161116
record.SetSpanID(pcommon.SpanID(rec.SpanID))
@@ -1245,7 +1245,7 @@ func TestEncodeLogBodyMapMode(t *testing.T) {
12451245
resourceLogs := logs.ResourceLogs().AppendEmpty()
12461246
scopeLogs := resourceLogs.ScopeLogs().AppendEmpty()
12471247
logRecords := scopeLogs.LogRecords()
1248-
observedTimestamp := pcommon.Timestamp(time.Now().UnixNano())
1248+
observedTimestamp := pcommon.Timestamp(time.Now().UnixNano()) // nolint:gosec // UnixNano is positive and thus safe to convert to signed integer.
12491249

12501250
logRecord := logRecords.AppendEmpty()
12511251
logRecord.SetObservedTimestamp(observedTimestamp)

0 commit comments

Comments
 (0)