Fix: AddWarnings panics on non-slice WarningsAttribute (fixes #8002)#8176
Fix: AddWarnings panics on non-slice WarningsAttribute (fixes #8002)#8176shivamtiwari3 wants to merge 2 commits intojaegertracing:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a potential nil-pointer dereference bug in the AddWarnings function that occurs when the WarningsAttribute already exists but is stored as a non-slice type (e.g., a plain string from Elasticsearch or another backend).
Changes:
- Added a type check in
AddWarningsto verify the attribute is a slice before attempting to use it - Added a comprehensive test case that verifies
AddWarningshandles malformed non-slice attributes without panicking
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| internal/jptrace/warning.go | Added type check to handle non-slice WarningsAttribute values |
| internal/jptrace/warning_test.go | Added test case for malformed non-slice attribute handling |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jaegertracing#8002) Root cause: Value.Slice() on a non-slice pcommon.Value returns an uninitialised pcommon.Slice with a nil internal state. Calling AppendEmpty() on it triggers AssertMutable() on the nil state, causing the nil-pointer dereference panic. This happens when Elasticsearch (or another backend) stores the WarningsAttribute as a plain string rather than a slice. Fix: mirror the type check already present in GetWarnings — only reuse the existing slice if currWarnings.Type() == pcommon.ValueTypeSlice; otherwise overwrite the attribute with a fresh empty slice via PutEmptySlice. Signed-off-by: shivamtiwari3 <33183708+shivamtiwari3@users.noreply.github.com>
c3f890b to
daaccd5
Compare
|
Re-pushed with |
| if currWarnings, ok := span.Attributes().Get(WarningsAttribute); ok && currWarnings.Type() == pcommon.ValueTypeSlice { | ||
| w = currWarnings.Slice() | ||
| } else { | ||
| w = span.Attributes().PutEmptySlice(WarningsAttribute) |
There was a problem hiding this comment.
What happens to existing attribute with WarningsAttribute key when you do this? Doesn't this override it? The solution might be to upgrade the type from a plain string to a slice, not to override.
… value Root cause: when WarningsAttribute exists as a non-slice type the previous fix silently dropped its value by overwriting with PutEmptySlice. Fix: read the existing string via AsString(), create the new slice, prepend the old value as the first element, then append the new warnings.
|
Applied — when |
There was a problem hiding this comment.
Pull request overview
This PR adds defensive handling to the AddWarnings function to gracefully handle cases where the WarningsAttribute already exists but is stored as a non-slice type (e.g., a plain string from Elasticsearch or other backends). Previously, the code would panic when calling .Slice() on a non-slice value. The fix detects the attribute type and upgrades non-slice values to slices while preserving the existing value.
Changes:
- Added type checking in
AddWarningsto detect non-slice attributes - When a non-slice attribute is found, it's upgraded to a slice with the existing value preserved as the first element
- Added comprehensive test case
TestAddWarning_NonSliceAttributeto verify the behavior
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| internal/jptrace/warning.go | Added type check and upgrade logic for non-slice warning attributes |
| internal/jptrace/warning_test.go | Added test to verify AddWarnings handles malformed (non-slice) attributes without panicking |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Fixes #8002.
AddWarningsininternal/jptrace/warning.gopanics with a nil-pointer dereference whenWarningsAttributealready exists in a span's attributes but is stored as a non-slice type (e.g. a plain string written by Elasticsearch or another backend).Root Cause
In
warning.go:13-14, the code callscurrWarnings.Slice()unconditionally after confirming the attribute is present:pcommon.Value.Slice()on a non-ValueTypeSlicevalue returns an uninitialisedpcommon.Slicewhose internal*Statefield is nil. WhenAppendEmpty()is subsequently called on that empty Slice, it invokes(*State).AssertMutable()on a nil pointer, producing the panic seen in the stack trace:The same function family already handles this correctly:
GetWarningsuses aswitch wa.Type()check before accessingwa.Slice().AddWarningswas missing an equivalent guard.Solution
Add
&& currWarnings.Type() == pcommon.ValueTypeSliceto the existing condition. When the attribute exists but is not a slice, the code falls through toPutEmptySlice, which atomically overwrites the malformed attribute with a fresh, mutable slice — matching the behaviour when the attribute is absent entirely.Testing
TestAddWarning_NonSliceAttributeinwarning_test.gothat reproduces the exact failure: it setsWarningsAttributeas a plain string, then callsAddWarningsand assertsrequire.NotPanics+ correct slice content.internal/jptrace/...continue to pass.go test ./internal/jptrace/... -vChecklist