From 8e502ff3c84226c2b5db605413eca3c962c4c5e8 Mon Sep 17 00:00:00 2001 From: Kartik Kenchi Date: Tue, 14 Jul 2026 13:50:15 +0530 Subject: [PATCH] use FromString for double values in redis reply parser --- redis/src/storages/redis/parse_reply.cpp | 2 +- redis/src/storages/redis/parse_reply_test.cpp | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 redis/src/storages/redis/parse_reply_test.cpp diff --git a/redis/src/storages/redis/parse_reply.cpp b/redis/src/storages/redis/parse_reply.cpp index 6afc9c34a46c..be084c4599a0 100644 --- a/redis/src/storages/redis/parse_reply.cpp +++ b/redis/src/storages/redis/parse_reply.cpp @@ -263,7 +263,7 @@ std::string Parse(ReplyData&& reply_data, const std::string& request_description double Parse(ReplyData&& reply_data, const std::string& request_description, To) { reply_data.ExpectString(request_description); try { - return std::stod(reply_data.GetString()); + return utils::FromString(reply_data.GetString()); } catch (const std::exception& ex) { throw ParseReplyException( "Can't parse value from reply to '" + request_description + "' request (" + reply_data.ToDebugString() + diff --git a/redis/src/storages/redis/parse_reply_test.cpp b/redis/src/storages/redis/parse_reply_test.cpp new file mode 100644 index 000000000000..ada68ab512d5 --- /dev/null +++ b/redis/src/storages/redis/parse_reply_test.cpp @@ -0,0 +1,43 @@ +#include + +#include + +#include + +#include +#include + +USERVER_NAMESPACE_BEGIN + +namespace { + +double ParseDouble(std::string value) { + return storages::redis::Parse( + storages::redis::ReplyData{std::move(value)}, "test_request", storages::redis::To{} + ); +} + +} // namespace + +TEST(ParseReply, DoubleValid) { + EXPECT_DOUBLE_EQ(ParseDouble("3.14"), 3.14); + EXPECT_DOUBLE_EQ(ParseDouble("-2.5"), -2.5); + EXPECT_DOUBLE_EQ(ParseDouble("1e3"), 1000.0); +} + +TEST(ParseReply, DoubleInfinity) { + // ZSCORE and friends report infinite scores as "inf"/"-inf". + EXPECT_TRUE(std::isinf(ParseDouble("inf"))); + EXPECT_TRUE(std::isinf(ParseDouble("-inf"))); +} + +TEST(ParseReply, DoubleTrailingJunk) { + // A compromised, misbehaving, or MITM'd server can return a bulk string with + // a valid numeric prefix followed by junk. std::stod silently accepted the + // prefix and dropped the rest; the strict parser rejects the whole reply. + EXPECT_THROW(ParseDouble("3.14garbage"), storages::redis::ParseReplyException); + EXPECT_THROW(ParseDouble("nonsense"), storages::redis::ParseReplyException); + EXPECT_THROW(ParseDouble(""), storages::redis::ParseReplyException); +} + +USERVER_NAMESPACE_END