From a633a3c24ca3960deeb88b59498e0ca84dfef812 Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Tue, 9 Sep 2025 11:02:22 +0100 Subject: [PATCH 1/2] RedisValue/RedisResult: cast to double should respect NaN/[+/-]Inf from raw/string --- src/StackExchange.Redis/RedisValue.cs | 4 ++ .../RedisResultTests.cs | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/StackExchange.Redis/RedisValue.cs b/src/StackExchange.Redis/RedisValue.cs index f198f3d08..08d65519c 100644 --- a/src/StackExchange.Redis/RedisValue.cs +++ b/src/StackExchange.Redis/RedisValue.cs @@ -656,6 +656,10 @@ public static explicit operator double(RedisValue value) StorageType.Int64 => value.OverlappedValueInt64, StorageType.UInt64 => value.OverlappedValueUInt64, StorageType.Double => value.OverlappedValueDouble, + // special values like NaN/Inf are deliberately not handled by Simplify, but need to be considered for casting + StorageType.String when Format.TryParseDouble((string)value._objectOrSentinel!, out var d) => d, + StorageType.Raw when TryParseDouble(value._memory.Span, out var d) => d, + // anything else: fail _ => throw new InvalidCastException($"Unable to cast from {value.Type} to double: '{value}'"), }; } diff --git a/tests/StackExchange.Redis.Tests/RedisResultTests.cs b/tests/StackExchange.Redis.Tests/RedisResultTests.cs index 1f58ceecf..e63e00dc8 100644 --- a/tests/StackExchange.Redis.Tests/RedisResultTests.cs +++ b/tests/StackExchange.Redis.Tests/RedisResultTests.cs @@ -150,4 +150,48 @@ public void SingleResultConvertibleDirectViaChangeType_TypeCode() Assert.StrictEqual(123f, Convert.ChangeType(value, TypeCode.Single)); Assert.StrictEqual(123d, Convert.ChangeType(value, TypeCode.Double)); } + + [Theory] + [InlineData(ResultType.Double)] + [InlineData(ResultType.BulkString)] + [InlineData(ResultType.SimpleString)] + public void RedisResultParseNaN(ResultType resultType) + { + // https://github.com/redis/NRedisStack/issues/439 + var value = RedisResult.Create("NaN", resultType); + Assert.True(double.IsNaN(value.AsDouble())); + } + + [Theory] + [InlineData(ResultType.Double)] + [InlineData(ResultType.BulkString)] + [InlineData(ResultType.SimpleString)] + public void RedisResultParseInf(ResultType resultType) + { + // https://github.com/redis/NRedisStack/issues/439 + var value = RedisResult.Create("inf", resultType); + Assert.True(double.IsPositiveInfinity(value.AsDouble())); + } + + [Theory] + [InlineData(ResultType.Double)] + [InlineData(ResultType.BulkString)] + [InlineData(ResultType.SimpleString)] + public void RedisResultParsePlusInf(ResultType resultType) + { + // https://github.com/redis/NRedisStack/issues/439 + var value = RedisResult.Create("+inf", resultType); + Assert.True(double.IsPositiveInfinity(value.AsDouble())); + } + + [Theory] + [InlineData(ResultType.Double)] + [InlineData(ResultType.BulkString)] + [InlineData(ResultType.SimpleString)] + public void RedisResultParseMinusInf(ResultType resultType) + { + // https://github.com/redis/NRedisStack/issues/439 + var value = RedisResult.Create("-inf", resultType); + Assert.True(double.IsNegativeInfinity(value.AsDouble())); + } } From ad360449169beaf8f0cf4d7f53c22d2d24738692 Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Tue, 9 Sep 2025 11:06:15 +0100 Subject: [PATCH 2/2] release notes --- docs/ReleaseNotes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 4621190d2..c0d061044 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -8,6 +8,8 @@ Current package versions: ## Unreleased +- Fix `RedisValue` special-value (NaN, Inf, etc) handling when casting from raw/string values to `double` ([#2950 by mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/2950)) + ## 2.9.11 - Add `HGETDEL`, `HGETEX` and `HSETEX` support ([#2863 by atakavci](https://github.com/StackExchange/StackExchange.Redis/pull/2863))