Skip to content

Commit 6fdbc88

Browse files
authored
fix: RedisValue/RedisResult: cast to double should respect special values (#2950)
* RedisValue/RedisResult: cast to double should respect NaN/[+/-]Inf from raw/string * release notes
1 parent a1e4853 commit 6fdbc88

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Current package versions:
88

99
## Unreleased
1010

11+
- 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))
12+
1113
## 2.9.11
1214

1315
- Add `HGETDEL`, `HGETEX` and `HSETEX` support ([#2863 by atakavci](https://github.com/StackExchange/StackExchange.Redis/pull/2863))

src/StackExchange.Redis/RedisValue.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,10 @@ public static explicit operator double(RedisValue value)
656656
StorageType.Int64 => value.OverlappedValueInt64,
657657
StorageType.UInt64 => value.OverlappedValueUInt64,
658658
StorageType.Double => value.OverlappedValueDouble,
659+
// special values like NaN/Inf are deliberately not handled by Simplify, but need to be considered for casting
660+
StorageType.String when Format.TryParseDouble((string)value._objectOrSentinel!, out var d) => d,
661+
StorageType.Raw when TryParseDouble(value._memory.Span, out var d) => d,
662+
// anything else: fail
659663
_ => throw new InvalidCastException($"Unable to cast from {value.Type} to double: '{value}'"),
660664
};
661665
}

tests/StackExchange.Redis.Tests/RedisResultTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,48 @@ public void SingleResultConvertibleDirectViaChangeType_TypeCode()
150150
Assert.StrictEqual(123f, Convert.ChangeType(value, TypeCode.Single));
151151
Assert.StrictEqual(123d, Convert.ChangeType(value, TypeCode.Double));
152152
}
153+
154+
[Theory]
155+
[InlineData(ResultType.Double)]
156+
[InlineData(ResultType.BulkString)]
157+
[InlineData(ResultType.SimpleString)]
158+
public void RedisResultParseNaN(ResultType resultType)
159+
{
160+
// https://github.com/redis/NRedisStack/issues/439
161+
var value = RedisResult.Create("NaN", resultType);
162+
Assert.True(double.IsNaN(value.AsDouble()));
163+
}
164+
165+
[Theory]
166+
[InlineData(ResultType.Double)]
167+
[InlineData(ResultType.BulkString)]
168+
[InlineData(ResultType.SimpleString)]
169+
public void RedisResultParseInf(ResultType resultType)
170+
{
171+
// https://github.com/redis/NRedisStack/issues/439
172+
var value = RedisResult.Create("inf", resultType);
173+
Assert.True(double.IsPositiveInfinity(value.AsDouble()));
174+
}
175+
176+
[Theory]
177+
[InlineData(ResultType.Double)]
178+
[InlineData(ResultType.BulkString)]
179+
[InlineData(ResultType.SimpleString)]
180+
public void RedisResultParsePlusInf(ResultType resultType)
181+
{
182+
// https://github.com/redis/NRedisStack/issues/439
183+
var value = RedisResult.Create("+inf", resultType);
184+
Assert.True(double.IsPositiveInfinity(value.AsDouble()));
185+
}
186+
187+
[Theory]
188+
[InlineData(ResultType.Double)]
189+
[InlineData(ResultType.BulkString)]
190+
[InlineData(ResultType.SimpleString)]
191+
public void RedisResultParseMinusInf(ResultType resultType)
192+
{
193+
// https://github.com/redis/NRedisStack/issues/439
194+
var value = RedisResult.Create("-inf", resultType);
195+
Assert.True(double.IsNegativeInfinity(value.AsDouble()));
196+
}
153197
}

0 commit comments

Comments
 (0)