Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/OpenTelemetry.Api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Notes](../../RELEASENOTES.md).
* Reduced allocations when constructing `SpanAttributes` from an array.
([#7698](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7698))

* Fixed parsing of an inbound `tracestate` header whose member value trimmed
to an empty value that previously threw an `IndexOutOfRangeException`
internally and could silently truncate the tracestate.
([#7756](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7756))

## 1.18.0

Released 2026-Aug-21
Expand Down
15 changes: 6 additions & 9 deletions src/OpenTelemetry.Api/Context/Propagation/TraceStateUtils.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;
using System.Runtime.CompilerServices;
using OpenTelemetry.Internal;

Expand All @@ -26,9 +25,7 @@ internal static class TraceStateUtils
/// <returns>True if string was parsed successfully and tracestate was recognized, false otherwise.</returns>
internal static bool AppendTraceState(string traceStateString, List<KeyValuePair<string, string>> tracestate)
{
Debug.Assert(tracestate != null, "tracestate list cannot be null");

if (string.IsNullOrEmpty(traceStateString))
if (tracestate is null || string.IsNullOrEmpty(traceStateString))
{
return false;
}
Expand Down Expand Up @@ -88,11 +85,7 @@ internal static bool AppendTraceState(string traceStateString, List<KeyValuePair

if (!isValid)
{
#if NET
tracestate.Clear();
#else
tracestate!.Clear();
#endif
return false;
}

Expand All @@ -101,6 +94,10 @@ internal static bool AppendTraceState(string traceStateString, List<KeyValuePair
catch (Exception ex)
{
OpenTelemetryApiEventSource.Log.TracestateExtractException(ex);

// Never hand back a partially-parsed tracestate: an unexpected failure mid-parse must
// not leave the caller with a silently truncated subset of the members.
tracestate.Clear();
}

return false;
Expand Down Expand Up @@ -235,7 +232,7 @@ private static bool ValidateValue(ReadOnlySpan<char> value)
// Value is opaque string up to 256 characters printable ASCII RFC0020 characters (i.e., the range
// 0x20 to 0x7E) except comma , and =.

if (value.Length > ValueMaxSize || value[value.Length - 1] == ' ' /* '\u0020' */)
if (value.Length == 0 || value.Length > ValueMaxSize || value[value.Length - 1] == ' ' /* '\u0020' */)
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public void EmptyTracestate(string tracestate)
[InlineData("k\t=v")]
[InlineData("k=v,k=v")]
[InlineData("k1=v1,,,k2=v2")]
[InlineData("k=\t")]
[InlineData("k=\u000B")]
[InlineData("b=1,a=\t,c=2")]
[InlineData("k=morethan256......................................................................................................................................................................................................................................................")]
[InlineData("v=morethan256......................................................................................................................................................................................................................................................")]
public void InvalidTracestate(string tracestate)
Expand Down
Loading