@@ -11,6 +11,7 @@ import (
1111 "context"
1212 "debug/elf"
1313 "encoding/binary"
14+ "encoding/hex"
1415 "errors"
1516 "fmt"
1617 "io"
@@ -19,6 +20,7 @@ import (
1920 "strings"
2021 "sync"
2122 "time"
23+ "unicode/utf8"
2224
2325 debuginfogrpc "buf.build/gen/go/parca-dev/parca/grpc/go/parca/debuginfo/v1alpha1/debuginfov1alpha1grpc"
2426 profilestoregrpc "buf.build/gen/go/parca-dev/parca/grpc/go/parca/profilestore/v1alpha1/profilestorev1alpha1grpc"
@@ -167,6 +169,39 @@ func hashString(s string) uint32 {
167169
168170func (r * ParcaReporter ) SupportsReportTraceEvent () bool { return true }
169171
172+ // maybeFixTruncation fixes string truncation done at the byte level
173+ // (at maxLen) to be done at the rune level instead.
174+ //
175+ // It returns the correctly truncated utf-8 string if possible;
176+ // otherwise "", false.
177+ func maybeFixTruncation (s string , maxLen int ) (string , bool ) {
178+ if utf8 .ValidString (s ) {
179+ return s , true
180+ }
181+ // maybe we truncated in the middle of a rune -- if that's the case,
182+ // truncate the entire rune.
183+ plausibleTruncatedRuneBegin := - 1
184+ if len (s ) == maxLen {
185+ i := 0
186+ for ; i < 2 ; i += 1 {
187+ idx := maxLen - i - 1
188+ if s [idx ]& 0xC0 != 0x80 {
189+ plausibleTruncatedRuneBegin = idx
190+ break
191+ }
192+ }
193+ }
194+ if plausibleTruncatedRuneBegin != - 1 {
195+ s = s [0 :plausibleTruncatedRuneBegin ]
196+ if ! utf8 .ValidString (s ) {
197+ return "" , false
198+ }
199+ } else {
200+ return "" , false
201+ }
202+ return s , true
203+ }
204+
170205// ReportTraceEvent enqueues reported trace events for the OTLP reporter.
171206func (r * ParcaReporter ) ReportTraceEvent (trace * libpf.Trace ,
172207 meta * samples.TraceEventMeta ) error {
@@ -196,6 +231,15 @@ func (r *ParcaReporter) ReportTraceEvent(trace *libpf.Trace,
196231 }
197232
198233 for k , v := range trace .CustomLabels {
234+ if ! utf8 .ValidString (k ) {
235+ log .Warnf ("ignoring non-UTF8 label: %s" , hex .EncodeToString ([]byte (k )))
236+ continue
237+ }
238+ v , ok := maybeFixTruncation (v , support .CustomLabelMaxValLen - 1 )
239+ if ! ok {
240+ log .Warnf ("ignoring non-UTF8 value for label %s: %s" , k , hex .EncodeToString ([]byte (v )))
241+ continue
242+ }
199243 r .sampleWriter .Label (k ).AppendString (v )
200244 }
201245
0 commit comments