Skip to content

Commit

Permalink
Packages: update to remove CVE dependencies (#2820)
Browse files Browse the repository at this point in the history
* Packages: update to remove CVE dependencies

This bumps *testing* (not the core package) to net8.0 for an easier time maintaining and updates packages outside StackExchange.Redis except for `Microsoft.Bcl.AsyncInterfaces`. `Microsoft.Bcl.AsyncInterfaces` was bumped from 5.0.0 to 6.0.0 due to deprecation warnings, still maintaining widest compatibility we can.

* Fix .NET Framework test diff

* fix enum flags rendering; involves adding a net8.0 TFM, but that's LTS *anyway*, so: fine

also added appropriate [Obsolete] to respect transient net8.0 changes

---------

Co-authored-by: Marc Gravell <[email protected]>
  • Loading branch information
NickCraver and mgravell authored Nov 27, 2024
1 parent 11ef77d commit 33358b7
Show file tree
Hide file tree
Showing 18 changed files with 149 additions and 59 deletions.
22 changes: 12 additions & 10 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
<Project>
<ItemGroup>
<!-- Packages we depend on for StackExchange.Redis, upgrades can create binding redirect pain! -->
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageVersion Include="Pipelines.Sockets.Unofficial" Version="2.2.8" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="5.0.0" />
<PackageVersion Include="System.Threading.Channels" Version="5.0.0" />
<PackageVersion Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
<PackageVersion Include="System.IO.Compression" Version="4.3.0" />

<!-- Packages only used in the solution, upgrade at will -->
<PackageVersion Include="BenchmarkDotNet" Version="0.13.1" />
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Nerdbank.GitVersioning" Version="3.6.141" />
<PackageVersion Include="Nerdbank.GitVersioning" Version="3.6.146" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="StackExchange.Redis" Version="2.6.96" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="System.Collections.Immutable" Version="9.0.0" />
<PackageVersion Include="System.Reflection.Metadata" Version="9.0.0" />
<!-- For binding redirect testing, main package gets this transitively -->
<PackageVersion Include="System.IO.Pipelines" Version="5.0.1" />
<PackageVersion Include="System.Runtime.Caching" Version="5.0.0" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="System.IO.Pipelines" Version="9.0.0" />
<PackageVersion Include="System.Runtime.Caching" Version="9.0.0" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
</Project>
14 changes: 9 additions & 5 deletions src/StackExchange.Redis/ConfigurationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,17 @@ private static bool CheckTrustedIssuer(X509Certificate2 certificateToValidate, X
byte[] authorityData = authority.RawData;
foreach (var chainElement in chain.ChainElements)
{
#if NET8_0_OR_GREATER
#error TODO: use RawDataMemory (needs testing)
#endif
using var chainCert = chainElement.Certificate;
if (!found && chainCert.RawData.SequenceEqual(authorityData))
if (!found)
{
found = true;
#if NET8_0_OR_GREATER
if (chainCert.RawDataMemory.Span.SequenceEqual(authorityData))
#else
if (chainCert.RawData.SequenceEqual(authorityData))
#endif
{
found = true;
}
}
}
return found;
Expand Down
23 changes: 23 additions & 0 deletions src/StackExchange.Redis/Enums/CommandFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,59 @@ public enum CommandFlags
/// </summary>
PreferMaster = 0,

#if NET8_0_OR_GREATER
/// <summary>
/// This operation should be performed on the replica if it is available, but will be performed on
/// a primary if no replicas are available. Suitable for read operations only.
/// </summary>
[Obsolete("Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use " + nameof(PreferReplica) + " instead, this will be removed in 3.0.")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
PreferSlave = 8,
#endif

/// <summary>
/// This operation should only be performed on the primary.
/// </summary>
DemandMaster = 4,

#if !NET8_0_OR_GREATER
/// <summary>
/// This operation should be performed on the replica if it is available, but will be performed on
/// a primary if no replicas are available. Suitable for read operations only.
/// </summary>
[Obsolete("Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use " + nameof(PreferReplica) + " instead, this will be removed in 3.0.")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
PreferSlave = 8,
#endif

/// <summary>
/// This operation should be performed on the replica if it is available, but will be performed on
/// a primary if no replicas are available. Suitable for read operations only.
/// </summary>
PreferReplica = 8, // note: we're using a 2-bit set here, which [Flags] formatting hates; position is doing the best we can for reasonable outcomes here

#if NET8_0_OR_GREATER
/// <summary>
/// This operation should only be performed on a replica. Suitable for read operations only.
/// </summary>
[Obsolete("Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use " + nameof(DemandReplica) + " instead, this will be removed in 3.0.")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
DemandSlave = 12,
#endif

/// <summary>
/// This operation should only be performed on a replica. Suitable for read operations only.
/// </summary>
DemandReplica = 12, // note: we're using a 2-bit set here, which [Flags] formatting hates; position is doing the best we can for reasonable outcomes here

#if !NET8_0_OR_GREATER
/// <summary>
/// This operation should only be performed on a replica. Suitable for read operations only.
/// </summary>
[Obsolete("Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use " + nameof(DemandReplica) + " instead, this will be removed in 3.0.")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
DemandSlave = 12,
#endif

// 16: reserved for additional "demand/prefer" options

Expand Down
29 changes: 29 additions & 0 deletions src/StackExchange.Redis/Exceptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace StackExchange.Redis
Expand All @@ -22,6 +23,10 @@ public RedisCommandException(string message) : base(message) { }
/// <param name="innerException">The inner exception.</param>
public RedisCommandException(string message, Exception innerException) : base(message, innerException) { }

#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
private RedisCommandException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}

Expand All @@ -46,6 +51,10 @@ public RedisTimeoutException(string message, CommandStatus commandStatus) : base
/// </summary>
public CommandStatus Commandstatus { get; }

#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
private RedisTimeoutException(SerializationInfo info, StreamingContext ctx) : base(info, ctx)
{
Commandstatus = info.GetValue("commandStatus", typeof(CommandStatus)) as CommandStatus? ?? CommandStatus.Unknown;
Expand All @@ -56,6 +65,10 @@ private RedisTimeoutException(SerializationInfo info, StreamingContext ctx) : ba
/// </summary>
/// <param name="info">Serialization info.</param>
/// <param name="context">Serialization context.</param>
#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
Expand Down Expand Up @@ -107,6 +120,10 @@ public RedisConnectionException(ConnectionFailureType failureType, string messag
/// </summary>
public CommandStatus CommandStatus { get; }

#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
private RedisConnectionException(SerializationInfo info, StreamingContext ctx) : base(info, ctx)
{
FailureType = (ConnectionFailureType)info.GetInt32("failureType");
Expand All @@ -118,6 +135,10 @@ private RedisConnectionException(SerializationInfo info, StreamingContext ctx) :
/// </summary>
/// <param name="info">Serialization info.</param>
/// <param name="context">Serialization context.</param>
#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
Expand Down Expand Up @@ -150,6 +171,10 @@ public RedisException(string message, Exception? innerException) : base(message,
/// </summary>
/// <param name="info">Serialization info.</param>
/// <param name="ctx">Serialization context.</param>
#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
protected RedisException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}

Expand All @@ -165,6 +190,10 @@ public sealed partial class RedisServerException : RedisException
/// <param name="message">The message for the exception.</param>
public RedisServerException(string message) : base(message) { }

#if NET8_0_OR_GREATER
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId)]
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
private RedisServerException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
}
7 changes: 7 additions & 0 deletions src/StackExchange.Redis/Obsoletions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace StackExchange.Redis;

internal static class Obsoletions
{
public const string LegacyFormatterImplMessage = "This API supports obsolete formatter-based serialization. It should not be called or extended by application code.";
public const string LegacyFormatterImplDiagId = "SYSLIB0051";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
StackExchange.Redis.ConfigurationOptions.SslClientAuthenticationOptions.get -> System.Func<string!, System.Net.Security.SslClientAuthenticationOptions!>?
StackExchange.Redis.ConfigurationOptions.SslClientAuthenticationOptions.set -> void
System.Runtime.CompilerServices.IsExternalInit (forwarded, contained in System.Runtime)
2 changes: 1 addition & 1 deletion src/StackExchange.Redis/StackExchange.Redis.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Nullable>enable</Nullable>
<!-- extend the default lib targets for the main lib; mostly because of "vectors" -->
<TargetFrameworks>net461;netstandard2.0;net472;netcoreapp3.1;net6.0</TargetFrameworks>
<TargetFrameworks>net461;netstandard2.0;net472;netcoreapp3.1;net6.0;net8.0</TargetFrameworks>
<Description>High performance Redis client, incorporating both synchronous and asynchronous usage.</Description>
<AssemblyName>StackExchange.Redis</AssemblyName>
<AssemblyTitle>StackExchange.Redis</AssemblyTitle>
Expand Down
5 changes: 4 additions & 1 deletion tests/BasicTest/BasicTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Description>StackExchange.Redis.BasicTest .NET Core</Description>
<TargetFrameworks>net472;net6.0</TargetFrameworks>
<TargetFrameworks>net472;net8.0</TargetFrameworks>
<AssemblyName>BasicTest</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>BasicTest</PackageId>
Expand All @@ -11,6 +11,9 @@

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" />
<PackageReference Include="System.Collections.Immutable" />
<PackageReference Include="System.Reflection.Metadata" />

<ProjectReference Include="..\..\src\StackExchange.Redis\StackExchange.Redis.csproj" />
</ItemGroup>

Expand Down
4 changes: 3 additions & 1 deletion tests/BasicTestBaseline/BasicTestBaseline.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Description>StackExchange.Redis.BasicTest .NET Core</Description>
<TargetFrameworks>net472;net6.0</TargetFrameworks>
<TargetFrameworks>net472;net8.0</TargetFrameworks>
<AssemblyName>BasicTestBaseline</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>BasicTestBaseline</PackageId>
Expand All @@ -17,6 +17,8 @@
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" />
<PackageReference Include="StackExchange.Redis" />
<PackageReference Include="System.Collections.Immutable" />
<PackageReference Include="System.Reflection.Metadata" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion tests/ConsoleTest/ConsoleTest.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand Down
2 changes: 1 addition & 1 deletion tests/ConsoleTestBaseline/ConsoleTestBaseline.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand Down
16 changes: 8 additions & 8 deletions tests/StackExchange.Redis.Tests/ConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ public void ExpectedFields()
[Fact]
public void SslProtocols_SingleValue()
{
var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls11");
Assert.Equal(SslProtocols.Tls11, options.SslProtocols.GetValueOrDefault());
var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls12");
Assert.Equal(SslProtocols.Tls12, options.SslProtocols.GetValueOrDefault());
}

[Fact]
public void SslProtocols_MultipleValues()
{
var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls11|Tls12");
Assert.Equal(SslProtocols.Tls11 | SslProtocols.Tls12, options.SslProtocols.GetValueOrDefault());
var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls12|Tls13");
Assert.Equal(SslProtocols.Tls12 | SslProtocols.Tls13, options.SslProtocols.GetValueOrDefault());
}

[Theory]
Expand All @@ -121,9 +121,9 @@ public void SslProtocols_UsingIntegerValue()
// The below scenario is for cases where the *targeted*
// .NET framework version (e.g. .NET 4.0) doesn't define an enum value (e.g. Tls11)
// but the OS has been patched with support
const int integerValue = (int)(SslProtocols.Tls11 | SslProtocols.Tls12);
const int integerValue = (int)(SslProtocols.Tls12 | SslProtocols.Tls13);
var options = ConfigurationOptions.Parse("myhost,sslProtocols=" + integerValue);
Assert.Equal(SslProtocols.Tls11 | SslProtocols.Tls12, options.SslProtocols.GetValueOrDefault());
Assert.Equal(SslProtocols.Tls12 | SslProtocols.Tls13, options.SslProtocols.GetValueOrDefault());
}

[Fact]
Expand Down Expand Up @@ -203,7 +203,7 @@ public void ConfigurationOptionsIPv6Parsing(string configString, AddressFamily f
public void CanParseAndFormatUnixDomainSocket()
{
const string ConfigString = "!/some/path,allowAdmin=True";
#if NET472
#if NETFRAMEWORK
var ex = Assert.Throws<PlatformNotSupportedException>(() => ConfigurationOptions.Parse(ConfigString));
Assert.Equal("Unix domain sockets require .NET Core 3 or above", ex.Message);
#else
Expand Down Expand Up @@ -793,6 +793,6 @@ public void CheckHighIntegrity(bool? assigned, bool expected, string cs)
Assert.Equal(cs, clone.ToString());

var parsed = ConfigurationOptions.Parse(cs);
Assert.Equal(expected, options.HighIntegrity);
Assert.Equal(expected, parsed.HighIntegrity);
}
}
8 changes: 7 additions & 1 deletion tests/StackExchange.Redis.Tests/FormatTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,21 @@ public void ParseEndPoint(string data, EndPoint expected, string? expectedFormat

[Theory]
[InlineData(CommandFlags.None, "None")]
#if NET472
#if NETFRAMEWORK
[InlineData(CommandFlags.PreferReplica, "PreferMaster, PreferReplica")] // 2-bit flag is hit-and-miss
[InlineData(CommandFlags.DemandReplica, "PreferMaster, DemandReplica")] // 2-bit flag is hit-and-miss
#else
[InlineData(CommandFlags.PreferReplica, "PreferReplica")] // 2-bit flag is hit-and-miss
[InlineData(CommandFlags.DemandReplica, "DemandReplica")] // 2-bit flag is hit-and-miss
#endif

#if NET8_0_OR_GREATER
[InlineData(CommandFlags.PreferReplica | CommandFlags.FireAndForget, "FireAndForget, PreferReplica")] // 2-bit flag is hit-and-miss
[InlineData(CommandFlags.DemandReplica | CommandFlags.FireAndForget, "FireAndForget, DemandReplica")] // 2-bit flag is hit-and-miss
#else
[InlineData(CommandFlags.PreferReplica | CommandFlags.FireAndForget, "PreferMaster, FireAndForget, PreferReplica")] // 2-bit flag is hit-and-miss
[InlineData(CommandFlags.DemandReplica | CommandFlags.FireAndForget, "PreferMaster, FireAndForget, DemandReplica")] // 2-bit flag is hit-and-miss
#endif
public void CommandFlagsFormatting(CommandFlags value, string expected)
=> Assert.Equal(expected, value.ToString());

Expand Down
Loading

0 comments on commit 33358b7

Please sign in to comment.