Fix `TraceContextPropagator` behavior when trace parent flags contain… (#4893)

This commit is contained in:
Piotr Kiełkowicz 2023-10-07 01:37:44 +02:00 committed by GitHub
parent eaf1d88021
commit 3c2bb7c93d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 11 deletions

View File

@ -10,6 +10,10 @@
`GetTracer` from leaking memory.
([#4906](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4906))
* Fix `TraceContextPropagator` by validating the first digit of the hex-encoded
`trace-flags` field of the `traceparent` header.
([#4893](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4893))
## 1.6.0
Released 2023-Sep-05

View File

@ -195,11 +195,12 @@ public class TraceContextPropagator : TextMapPropagator
return false;
}
byte options1;
byte optionsLowByte;
try
{
spanId = ActivitySpanId.CreateFromString(traceparent.AsSpan().Slice(VersionAndTraceIdLength, SpanIdLength));
options1 = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength + 1]);
_ = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength]); // to verify if there is no bad chars on options position
optionsLowByte = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength + 1]);
}
catch (ArgumentOutOfRangeException)
{
@ -207,7 +208,7 @@ public class TraceContextPropagator : TextMapPropagator
return false;
}
if ((options1 & 1) == 1)
if ((optionsLowByte & 1) == 1)
{
traceOptions |= ActivityTraceFlags.Recorded;
}

View File

@ -35,7 +35,7 @@ public class W3CTraceContextTests : IDisposable
*/
private const string W3cTraceContextEnvVarName = "OTEL_W3CTRACECONTEXT";
private static readonly Version AspNetCoreHostingVersion = typeof(Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory).Assembly.GetName().Version;
private readonly HttpClient httpClient = new HttpClient();
private readonly HttpClient httpClient = new();
private readonly ITestOutputHelper output;
public W3CTraceContextTests(ITestOutputHelper output)
@ -107,7 +107,7 @@ public class W3CTraceContextTests : IDisposable
}
else
{
Assert.StartsWith("FAILED (failures=3)", lastLine);
Assert.StartsWith("FAILED (failures=2)", lastLine);
}
}

View File

@ -103,12 +103,16 @@ public class TraceContextPropagatorTest
Assert.False(ctx.ActivityContext.IsValid());
}
[Fact]
public void IsBlankIfInvalid()
[Theory]
[InlineData($"00-xyz7651916cd43dd8448eb211c80319c-{SpanId}-01")]
[InlineData($"00-{TraceId}-xyz7c989f97918e1-01")]
[InlineData($"00-{TraceId}-{SpanId}-x1")]
[InlineData($"00-{TraceId}-{SpanId}-1x")]
public void IsBlankIfInvalid(string invalidTraceParent)
{
var headers = new Dictionary<string, string>
{
{ TraceParent, $"00-xyz7651916cd43dd8448eb211c80319c-{SpanId}-01" },
{ TraceParent, invalidTraceParent },
};
var f = new TraceContextPropagator();
@ -191,8 +195,8 @@ public class TraceContextPropagatorTest
// test_tracestate_duplicated_keys
Assert.Empty(CallTraceContextPropagator("foo=1,foo=1"));
Assert.Empty(CallTraceContextPropagator("foo=1,foo=2"));
Assert.Empty(CallTraceContextPropagator(new string[] { "foo=1", "foo=1" }));
Assert.Empty(CallTraceContextPropagator(new string[] { "foo=1", "foo=2" }));
Assert.Empty(CallTraceContextPropagator(new[] { "foo=1", "foo=1" }));
Assert.Empty(CallTraceContextPropagator(new[] { "foo=1", "foo=2" }));
}
[Fact]
@ -318,7 +322,7 @@ public class TraceContextPropagatorTest
{
var headers = new Dictionary<string, string[]>
{
{ TraceParent, new string[] { $"00-{TraceId}-{SpanId}-01" } },
{ TraceParent, new[] { $"00-{TraceId}-{SpanId}-01" } },
{ TraceState, tracestate },
};
var f = new TraceContextPropagator();