VYPR
Medium severity5.3GHSA Advisory· Published May 6, 2026· Updated May 15, 2026

CVE-2026-41484

CVE-2026-41484

Description

OpenTelemetry.Exporter.OneCollector is a .NET exporter that sends telemetry to a OneCollector back-end over HTTP. In versions 1.15.0 and earlier, when a request to the configured back-end or collector results in an unsuccessful HTTP 4xx or 5xx response, the HttpJsonPostTransport class reads the entire response body into memory with no upper bound on the number of bytes consumed in order to include the error response in operator logs.

An attacker who controls the configured endpoint, or who can intercept traffic to it via a man-in-the-middle attack, can return an arbitrarily large response body. This causes unbounded heap allocation in the consuming process, leading to high transient memory pressure, garbage-collection stalls, or an OutOfMemoryException that terminates the process. As a workaround, use network-level controls such as firewall rules, mTLS, or a service mesh to prevent man-in-the-middle attacks on the configured back-end or collector endpoint. This issue is fixed in version 1.15.1, which limits the number of bytes read from the response body in an error condition to 4 MiB.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
OpenTelemetry.Exporter.OneCollectorNuGet
< 1.15.11.15.1

Affected products

1

Patches

1
77dc5d14fcdf

[OneCollector] Limit response body size read (#4117)

7 files changed · +651 13
  • src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md+4 0 modified
    @@ -5,6 +5,10 @@
     * Updated OpenTelemetry core component version(s) to `1.15.2`.
       ([#4080](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4080))
     
    +* Limit how much of the response body is read when export fails using the HTTP
    +  JSON transport and informational logging is enabled.
    +  ([#4117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4117))
    +
     ## 1.15.0
     
     Released 2026-Jan-21
    
  • src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs+11 8 modified
    @@ -103,10 +103,10 @@ public bool Send(in TransportSendRequest sendRequest)
                     request.Headers.TryAddWithoutValidation("NoResponseBody", "true");
                 }
     
    -            using var response = this.httpClient.Send(
    -                request,
    -                infoLoggingEnabled ? HttpCompletionOption.ResponseContentRead : HttpCompletionOption.ResponseHeadersRead,
    -                CancellationToken.None);
    +            var cancellationToken = CancellationToken.None;
    +            var completionOption = HttpCompletionOption.ResponseHeadersRead;
    +
    +            using var response = this.httpClient.Send(request, completionOption, cancellationToken);
     
                 if (response.IsSuccessStatusCode)
                 {
    @@ -130,11 +130,14 @@ public bool Send(in TransportSendRequest sendRequest)
                 }
                 else
                 {
    -                response.Headers.TryGetValues("Collector-Error", out var collectorErrors);
    +                _ = response.Headers.TryGetValues("Collector-Error", out var collectorErrors);
    +
    +                string? errorDetails = null;
     
    -                var errorDetails = infoLoggingEnabled
    -                    ? response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
    -                    : null;
    +                if (infoLoggingEnabled)
    +                {
    +                    errorDetails = HttpClientHelpers.TryGetResponseBodyAsString(response, cancellationToken);
    +                }
     
                     OneCollectorExporterEventSource.Log.WriteHttpTransportErrorResponseReceivedEventIfEnabled(
                         this.Description,
    
  • src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs+3 5 modified
    @@ -38,14 +38,12 @@ public HttpClientWrapper(HttpClient httpClient)
         public HttpResponseMessage Send(
             HttpRequestMessage request,
             HttpCompletionOption completionOption,
    -        CancellationToken cancellationToken)
    -    {
    +        CancellationToken cancellationToken) =>
     #if NET
    -        return this.synchronousSendSupportedByCurrentPlatform
    +        this.synchronousSendSupportedByCurrentPlatform
                 ? this.httpClient.Send(request, completionOption, cancellationToken)
                 : this.httpClient.SendAsync(request, completionOption, cancellationToken).GetAwaiter().GetResult();
     #else
    -        return this.httpClient.SendAsync(request, completionOption, cancellationToken).GetAwaiter().GetResult();
    +        this.httpClient.SendAsync(request, completionOption, cancellationToken).GetAwaiter().GetResult();
     #endif
    -    }
     }
    
  • src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj+1 0 modified
    @@ -41,6 +41,7 @@
       <ItemGroup>
         <Compile Include="$(RepoRoot)\src\Shared\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
    +    <Compile Include="$(RepoRoot)\src\Shared\HttpClientHelpers.cs" Link="Includes\HttpClientHelpers.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\IsExternalInit.cs" Link="Includes\IsExternalInit.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\Lock.cs" Link="Includes\Lock.cs" />
       </ItemGroup>
    
  • src/Shared/HttpClientHelpers.cs+151 0 added
    @@ -0,0 +1,151 @@
    +// Copyright The OpenTelemetry Authors
    +// SPDX-License-Identifier: Apache-2.0
    +
    +#if NET
    +using System.Buffers;
    +#endif
    +using System.Text;
    +
    +namespace System.Net.Http;
    +
    +internal static class HttpClientHelpers
    +{
    +    private const int DefaultMessageSizeLimit = 4 * 1024 * 1024; // 4MiB
    +
    +    internal static string? TryGetResponseBodyAsString(HttpResponseMessage? httpResponse, CancellationToken cancellationToken)
    +        => GetResponseBodyAsString(allowTruncation: true, DefaultMessageSizeLimit, httpResponse, cancellationToken);
    +
    +    internal static string? GetResponseBodyAsString(HttpResponseMessage? httpResponse, CancellationToken cancellationToken)
    +        => GetResponseBodyAsString(allowTruncation: false, DefaultMessageSizeLimit, httpResponse, cancellationToken);
    +
    +    private static string? GetResponseBodyAsString(
    +        bool allowTruncation,
    +        int limit,
    +        HttpResponseMessage? httpResponse,
    +        CancellationToken cancellationToken)
    +    {
    +        if (httpResponse?.Content is null)
    +        {
    +            return null;
    +        }
    +
    +        if (cancellationToken.IsCancellationRequested)
    +        {
    +            if (allowTruncation)
    +            {
    +                return null;
    +            }
    +
    +            cancellationToken.ThrowIfCancellationRequested();
    +        }
    +
    +        try
    +        {
    +#if NET
    +            var stream = httpResponse.Content.ReadAsStream(cancellationToken);
    +#else
    +            var stream = httpResponse.Content.ReadAsStreamAsync().GetAwaiter().GetResult();
    +#endif
    +
    +            var length = GetBufferLength(stream, limit);
    +
    +#if NET
    +            var buffer = ArrayPool<byte>.Shared.Rent(length);
    +#else
    +            var buffer = new byte[length];
    +#endif
    +
    +            try
    +            {
    +                var totalRead = 0;
    +
    +                // Read raw bytes so the size limit applies to bytes rather than characters
    +                while (totalRead < limit && !cancellationToken.IsCancellationRequested)
    +                {
    +                    var bytesRead = stream.Read(buffer, totalRead, length - totalRead);
    +
    +                    if (bytesRead is 0)
    +                    {
    +                        break;
    +                    }
    +
    +                    totalRead += bytesRead;
    +                }
    +
    +                // We've read exactly limit bytes. Check if there's more data.
    +                var probe = new byte[1];
    +
    +#if NETFRAMEWORK || NETSTANDARD
    +                var extra = stream.Read(probe, 0, 1);
    +#else
    +                var extra = stream.Read(probe);
    +#endif
    +
    +                if (extra > 0 && !allowTruncation)
    +                {
    +                    // + 1: we read exactly MaxMessageSize bytes and confirmed at least one more byte exists.
    +                    throw new InvalidOperationException($"Response body exceeded the size limit of {limit} bytes.");
    +                }
    +
    +                if (!allowTruncation)
    +                {
    +                    cancellationToken.ThrowIfCancellationRequested();
    +                }
    +
    +                // Decode using the charset from the response content headers, if available
    +                var encoding = GetEncoding(httpResponse.Content.Headers.ContentType?.CharSet);
    +                var result = encoding.GetString(buffer, 0, totalRead);
    +
    +                if (extra > 0)
    +                {
    +                    result += "[TRUNCATED]";
    +                }
    +
    +                return result;
    +            }
    +            finally
    +            {
    +#if NET
    +                ArrayPool<byte>.Shared.Return(buffer, clearArray: true);
    +#endif
    +            }
    +        }
    +        catch (Exception) when (allowTruncation)
    +        {
    +            return null;
    +        }
    +    }
    +
    +    private static int GetBufferLength(Stream stream, int limit)
    +    {
    +        try
    +        {
    +            // Avoid allocating an overly large buffer if the stream is smaller than the size limit
    +            return stream.Length < limit ? (int)stream.Length : limit;
    +        }
    +        catch (Exception)
    +        {
    +            // Not all Stream types support Length, so default to the maximum
    +            return limit;
    +        }
    +    }
    +
    +    private static Encoding GetEncoding(string? name)
    +    {
    +        Encoding encoding = Encoding.UTF8;
    +
    +        if (!string.IsNullOrWhiteSpace(name))
    +        {
    +            try
    +            {
    +                encoding = Encoding.GetEncoding(name);
    +            }
    +            catch (Exception)
    +            {
    +                // Invalid encoding name
    +            }
    +        }
    +
    +        return encoding;
    +    }
    +}
    
  • test/OpenTelemetry.Contrib.Shared.Tests/HttpClientHelpersTests.cs+480 0 added
    @@ -0,0 +1,480 @@
    +// Copyright The OpenTelemetry Authors
    +// SPDX-License-Identifier: Apache-2.0
    +
    +#if NETFRAMEWORK
    +using System.Net.Http;
    +#endif
    +using System.IO.Compression;
    +using System.Net;
    +using System.Text;
    +using Xunit;
    +
    +namespace OpenTelemetry.Instrumentation.Tests;
    +
    +public class HttpClientHelpersTests
    +{
    +    private const int MessageSizeLimit = 4 * 1024 * 1024;
    +    private const string TruncationSuffix = "[TRUNCATED]";
    +
    +    [Fact]
    +    public void GetResponseBodyAsString_HttpResponseWithoutContent_ReturnsCorrectResult()
    +    {
    +        // Arrange
    +        using var httpResponse = new HttpResponseMessage() { Content = null };
    +        var cancellationToken = CancellationToken.None;
    +
    +        // Act
    +        var actual = HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +#if NETFRAMEWORK
    +        Assert.Null(actual);
    +#else
    +        Assert.Equal(string.Empty, actual);
    +#endif
    +    }
    +
    +    [Theory]
    +    [InlineData(0)]
    +    [InlineData(1)]
    +    [InlineData(256)]
    +    [InlineData(1024)]
    +    [InlineData((30 * 1024) - 1)]
    +    [InlineData(30 * 1024)]
    +    public void GetResponseBodyAsString_SmallContent_ReturnsFullContent(int length)
    +    {
    +        // Arrange
    +        var expected = new string('A', length);
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(expected),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(expected, actual);
    +    }
    +
    +    [Theory]
    +    [InlineData(1)]
    +    [InlineData(1024)]
    +    [InlineData(2048)]
    +    public void GetResponseBodyAsString_ContentExceedsLimit_Throws(int excess)
    +    {
    +        // Arrange
    +        var content = new string('C', MessageSizeLimit + excess);
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(content),
    +        };
    +
    +        // Act and Assert
    +        Assert.Throws<InvalidOperationException>(() => HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken));
    +    }
    +
    +    [Theory]
    +    [InlineData(1)]
    +    [InlineData(1024)]
    +    [InlineData(2048)]
    +    public void TryGetResponseBodyAsString_DecompressedContentExceedsLimit_Throws(int excess)
    +    {
    +        // Arrange
    +        var content = new string('G', MessageSizeLimit + excess);
    +        var rawBytes = Encoding.UTF8.GetBytes(content);
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var memoryStream = new MemoryStream();
    +
    +        using (var compressor = new GZipStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
    +        {
    +            compressor.Write(rawBytes, 0, rawBytes.Length);
    +        }
    +
    +        memoryStream.Seek(0, SeekOrigin.Begin);
    +
    +        Assert.True(
    +            memoryStream.Length < MessageSizeLimit,
    +            $"The compressed message length {memoryStream.Length} is not less than {MessageSizeLimit}.");
    +
    +        using var compressed = new GZipStream(memoryStream, CompressionMode.Decompress, leaveOpen: true);
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StreamContent(compressed),
    +        };
    +
    +        // Act and Assert
    +        Assert.Throws<InvalidOperationException>(() => HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken));
    +    }
    +
    +    [Fact]
    +    public void GetResponseBodyAsString_EmptyContent_ReturnsEmptyString()
    +    {
    +        // Arrange
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(string.Empty),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(string.Empty, actual);
    +    }
    +
    +    [Fact]
    +    public void GetResponseBodyAsString_ExceptionDuringRead_Throws()
    +    {
    +        // Arrange
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new ThrowingHttpContent(),
    +        };
    +
    +        // Act and Assert
    +        Assert.Throws<InvalidOperationException>(() => HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken));
    +    }
    +
    +    [Fact]
    +    public void GetResponseBodyAsString_CancellationTokenSignalled_Throws()
    +    {
    +        // Arrange
    +        var cancellationToken = new CancellationToken(canceled: true);
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent("foo"),
    +        };
    +
    +        // Act and Assert
    +        Assert.Throws<OperationCanceledException>(() => HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken));
    +    }
    +
    +    [Fact]
    +    public void GetResponseBodyAsString_NonSeekableStream_ReturnsContent()
    +    {
    +        // Arrange
    +        var expected = "non-seekable response body";
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new NonSeekableStreamContent(Encoding.UTF8.GetBytes(expected)),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(expected, actual);
    +    }
    +
    +    [Fact]
    +    public void GetResponseBodyAsString_NonUtf8Charset_ReturnsCorrectlyDecodedContent()
    +    {
    +        // Arrange
    +        var expected = "iso-8859-1 response body: caf\u00e9";
    +        var cancellationToken = CancellationToken.None;
    +        var iso8859 = Encoding.GetEncoding("iso-8859-1");
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(expected, iso8859),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.GetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(expected, actual);
    +    }
    +
    +    [Fact]
    +    public void TryGetResponseBodyAsString_HttpResponseWithoutContent_ReturnsCorrectResult()
    +    {
    +        // Arrange
    +        using var httpResponse = new HttpResponseMessage() { Content = null };
    +        var cancellationToken = CancellationToken.None;
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +#if NETFRAMEWORK
    +        Assert.Null(actual);
    +#else
    +        Assert.Equal(string.Empty, actual);
    +#endif
    +    }
    +
    +    [Theory]
    +    [InlineData(0)]
    +    [InlineData(1)]
    +    [InlineData(256)]
    +    [InlineData(1024)]
    +    [InlineData((30 * 1024) - 1)]
    +    [InlineData(30 * 1024)]
    +    public void TryGetResponseBodyAsString_SmallContent_ReturnsFullContent(int length)
    +    {
    +        // Arrange
    +        var expected = new string('A', length);
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(expected),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(expected, actual);
    +    }
    +
    +    [Theory]
    +    [InlineData(1)]
    +    [InlineData(1024)]
    +    [InlineData(2048)]
    +    public void TryGetResponseBodyAsString_ContentExceedsLimit_ReturnsTruncatedContent(int excess)
    +    {
    +        // Arrange
    +        var content = new string('C', MessageSizeLimit + excess);
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(content),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.NotNull(actual);
    +        Assert.Equal(MessageSizeLimit + TruncationSuffix.Length, actual.Length);
    +        Assert.Equal(new string('C', MessageSizeLimit) + TruncationSuffix, actual);
    +    }
    +
    +    [Theory]
    +    [InlineData(1)]
    +    [InlineData(1024)]
    +    [InlineData(2048)]
    +    public void TryGetResponseBodyAsString_DecompressedContentExceedsLimit_ReturnsTruncatedContent(int excess)
    +    {
    +        // Arrange
    +        var content = new string('G', MessageSizeLimit + excess);
    +        var rawBytes = Encoding.UTF8.GetBytes(content);
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var memoryStream = new MemoryStream();
    +
    +        using (var compressor = new GZipStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
    +        {
    +            compressor.Write(rawBytes, 0, rawBytes.Length);
    +        }
    +
    +        memoryStream.Seek(0, SeekOrigin.Begin);
    +
    +        Assert.True(
    +            memoryStream.Length < MessageSizeLimit,
    +            $"The compressed message length {memoryStream.Length} is not less than {MessageSizeLimit}.");
    +
    +        using var compressed = new GZipStream(memoryStream, CompressionMode.Decompress, leaveOpen: true);
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StreamContent(compressed),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.NotNull(actual);
    +        Assert.Equal(MessageSizeLimit + TruncationSuffix.Length, actual.Length);
    +        Assert.Equal(new string('G', MessageSizeLimit) + TruncationSuffix, actual);
    +    }
    +
    +    [Fact]
    +    public void TryGetResponseBodyAsString_EmptyContent_ReturnsEmptyString()
    +    {
    +        // Arrange
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(string.Empty),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(string.Empty, actual);
    +    }
    +
    +    [Fact]
    +    public void TryGetResponseBodyAsString_ExceptionDuringRead_ReturnsNull()
    +    {
    +        // Arrange
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new ThrowingHttpContent(),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Null(actual);
    +    }
    +
    +    [Fact]
    +    public void TryGetResponseBodyAsString_CancellationTokenSignalled_ReturnsNull()
    +    {
    +        // Arrange
    +        var cancellationToken = new CancellationToken(canceled: true);
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent("foo"),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Null(actual);
    +    }
    +
    +    [Fact]
    +    public void TryGetResponseBodyAsString_NonSeekableStream_ReturnsContent()
    +    {
    +        // Arrange
    +        var expected = "non-seekable response body";
    +        var cancellationToken = CancellationToken.None;
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new NonSeekableStreamContent(Encoding.UTF8.GetBytes(expected)),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(expected, actual);
    +    }
    +
    +    [Fact]
    +    public void TryGetResponseBodyAsString_NonUtf8Charset_ReturnsCorrectlyDecodedContent()
    +    {
    +        // Arrange
    +        var expected = "iso-8859-1 response body: caf\u00e9";
    +        var cancellationToken = CancellationToken.None;
    +        var iso8859 = Encoding.GetEncoding("iso-8859-1");
    +
    +        using var httpResponse = new HttpResponseMessage()
    +        {
    +            Content = new StringContent(expected, iso8859),
    +        };
    +
    +        // Act
    +        var actual = HttpClientHelpers.TryGetResponseBodyAsString(httpResponse, cancellationToken);
    +
    +        // Assert
    +        Assert.Equal(expected, actual);
    +    }
    +
    +    private sealed class ThrowingHttpContent : HttpContent
    +    {
    +        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context)
    +            => throw new InvalidOperationException("Test exception");
    +
    +#if NET
    +        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken)
    +            => throw new InvalidOperationException("Test exception");
    +
    +        protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken)
    +            => throw new InvalidOperationException("Test exception");
    +#endif
    +
    +        protected override bool TryComputeLength(out long length)
    +        {
    +            length = 0;
    +            return false;
    +        }
    +    }
    +
    +    private sealed class NonSeekableStreamContent : HttpContent
    +    {
    +        private readonly byte[] data;
    +
    +        public NonSeekableStreamContent(byte[] data)
    +        {
    +            this.data = data;
    +            this.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain") { CharSet = "utf-8" };
    +        }
    +
    +        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context)
    +            => stream.WriteAsync(this.data, 0, this.data.Length);
    +
    +#if NET
    +        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken)
    +            => stream.WriteAsync(this.data, cancellationToken).AsTask();
    +
    +        protected override Stream CreateContentReadStream(CancellationToken cancellationToken)
    +            => new NonSeekableStream(new MemoryStream(this.data));
    +#endif
    +
    +        protected override Task<Stream> CreateContentReadStreamAsync()
    +            => Task.FromResult<Stream>(new NonSeekableStream(new MemoryStream(this.data)));
    +
    +        protected override bool TryComputeLength(out long length)
    +        {
    +            length = 0;
    +            return false;
    +        }
    +    }
    +
    +    private sealed class NonSeekableStream(Stream inner) : Stream
    +    {
    +        public override bool CanRead => true;
    +
    +        public override bool CanSeek => false;
    +
    +        public override bool CanWrite => false;
    +
    +        public override long Length => throw new NotSupportedException();
    +
    +        public override long Position
    +        {
    +            get => throw new NotSupportedException();
    +            set => throw new NotSupportedException();
    +        }
    +
    +        public override void Flush() => inner.Flush();
    +
    +        public override int Read(byte[] buffer, int offset, int count) => inner.Read(buffer, offset, count);
    +
    +        public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
    +
    +        public override void SetLength(long value) => throw new NotSupportedException();
    +
    +        public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
    +    }
    +}
    
  • test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj+1 0 modified
    @@ -23,6 +23,7 @@
         <Compile Include="$(RepoRoot)\src\Shared\GrpcTagHelper.cs" Link="Includes\GrpcTagHelper.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\GrpcStatusCanonicalCode.cs" Link="Includes\GrpcStatusCanonicalCode.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
    +    <Compile Include="$(RepoRoot)\src\Shared\HttpClientHelpers.cs" Link="Includes\HttpClientHelpers.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\MeterFactory.cs" Link="Includes\MeterFactory.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\NullableAttributes.cs" Link="Includes\NullableAttributes.cs" />
         <Compile Include="$(RepoRoot)\src\Shared\PropertyFetcher.cs" Link="Includes\PropertyFetcher.cs" />
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.