summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2022-01-11 21:50:23 +0300
committerNan Zhou <nanzhoumails@gmail.com>2022-01-25 06:12:38 +0300
commit22ce5458073055db03e4288187116486eaaa64dc (patch)
treed751884e36e3f1c2ee672f6b871c6dc2f36f264b
parent8d4c4875dd530064319bbee9e2b7ad08fcde099a (diff)
downloadbmcweb-22ce5458073055db03e4288187116486eaaa64dc.tar.xz
Fix Boost exceptions in GetDateTime series
In cases when the input time is too large, we return the maximum supported date in the ISO Extended format. Tested: Unit tests pass Signed-off-by: Nan Zhou <nanzhoumails@gmail.com> Change-Id: I0dcd60d10d4357bd8700f0dbc1ef86d94bcc82bb
-rw-r--r--http/ut/utility_test.cpp53
-rw-r--r--http/utility.hpp24
2 files changed, 45 insertions, 32 deletions
diff --git a/http/ut/utility_test.cpp b/http/ut/utility_test.cpp
index 4748c25712..5dafdce446 100644
--- a/http/ut/utility_test.cpp
+++ b/http/ut/utility_test.cpp
@@ -2,11 +2,16 @@
#include "gmock/gmock.h"
+namespace crow::utility
+{
+namespace
+{
+
TEST(Utility, Base64DecodeAuthString)
{
std::string authString("dXNlcm40bWU6cGFzc3cwcmQ=");
std::string result;
- EXPECT_TRUE(crow::utility::base64Decode(authString, result));
+ EXPECT_TRUE(base64Decode(authString, result));
EXPECT_EQ(result, "usern4me:passw0rd");
}
@@ -14,7 +19,7 @@ TEST(Utility, Base64DecodeNonAscii)
{
std::string junkString("\xff\xee\xdd\xcc\x01\x11\x22\x33");
std::string result;
- EXPECT_FALSE(crow::utility::base64Decode(junkString, result));
+ EXPECT_FALSE(base64Decode(junkString, result));
}
TEST(Utility, Base64EncodeString)
@@ -22,28 +27,28 @@ TEST(Utility, Base64EncodeString)
using namespace std::string_literals;
std::string encoded;
- encoded = crow::utility::base64encode("");
+ encoded = base64encode("");
EXPECT_EQ(encoded, "");
- encoded = crow::utility::base64encode("f");
+ encoded = base64encode("f");
EXPECT_EQ(encoded, "Zg==");
- encoded = crow::utility::base64encode("f0");
+ encoded = base64encode("f0");
EXPECT_EQ(encoded, "ZjA=");
- encoded = crow::utility::base64encode("f0\0"s);
+ encoded = base64encode("f0\0"s);
EXPECT_EQ(encoded, "ZjAA");
- encoded = crow::utility::base64encode("f0\0 "s);
+ encoded = base64encode("f0\0 "s);
EXPECT_EQ(encoded, "ZjAAIA==");
- encoded = crow::utility::base64encode("f0\0 B"s);
+ encoded = base64encode("f0\0 B"s);
EXPECT_EQ(encoded, "ZjAAIEI=");
- encoded = crow::utility::base64encode("f0\0 Ba"s);
+ encoded = base64encode("f0\0 Ba"s);
EXPECT_EQ(encoded, "ZjAAIEJh");
- encoded = crow::utility::base64encode("f0\0 Bar"s);
+ encoded = base64encode("f0\0 Bar"s);
EXPECT_EQ(encoded, "ZjAAIEJhcg==");
}
@@ -51,9 +56,9 @@ TEST(Utility, Base64EncodeDecodeString)
{
using namespace std::string_literals;
std::string data("Data fr\0m 90 reading a \nFile"s);
- std::string encoded = crow::utility::base64encode(data);
+ std::string encoded = base64encode(data);
std::string decoded;
- EXPECT_TRUE(crow::utility::base64Decode(encoded, decoded));
+ EXPECT_TRUE(base64Decode(encoded, decoded));
EXPECT_EQ(data, decoded);
}
@@ -67,19 +72,16 @@ TEST(Utility, GetDateTimeStdtime)
// epoch
EXPECT_EQ(getDateTimeStdtime(std::time_t{0}), "1970-01-01T00:00:00+00:00");
- // some time in the past after the epoch
// Limits
EXPECT_EQ(getDateTimeStdtime(std::numeric_limits<std::time_t>::max()),
- "1969-12-31T23:59:59+00:00");
+ "9999-12-31T23:59:59+00:00");
EXPECT_EQ(getDateTimeStdtime(std::numeric_limits<std::time_t>::min()),
"1970-01-01T00:00:00+00:00");
}
-TEST(Utility, getDateTimeUint)
+TEST(Utility, GetDateTimeUint)
{
- using crow::utility::getDateTimeUint;
-
EXPECT_EQ(getDateTimeUint(uint64_t{1638312095}),
"2021-11-30T22:41:35+00:00");
// some time in the future, beyond 2038
@@ -89,22 +91,21 @@ TEST(Utility, getDateTimeUint)
EXPECT_EQ(getDateTimeUint(uint64_t{253402300799}),
"9999-12-31T23:59:59+00:00");
- // This test currently throws an exception
- // EXPECT_EQ(getDateTimeUint(std::numeric_limits<uint64_t>::max()), "");
+ // returns the maximum Redfish date
+ EXPECT_EQ(getDateTimeUint(std::numeric_limits<uint64_t>::max()),
+ "9999-12-31T23:59:59+00:00");
EXPECT_EQ(getDateTimeUint(std::numeric_limits<uint64_t>::min()),
"1970-01-01T00:00:00+00:00");
}
-TEST(Utility, getDateTimeUintMs)
+TEST(Utility, GetDateTimeUintMs)
{
- using crow::utility::getDateTimeUintMs;
-
- // Note, this is the wrong result, but is here to make sure that we don't
- // have worse behavior (ie seg faults, exceptions) when this happens
+ // returns the maximum Redfish date
EXPECT_EQ(getDateTimeUintMs(std::numeric_limits<uint64_t>::max()),
- "1969-12-31T23:59:59.999000+00:00");
-
+ "9999-12-31T23:59:59.999000+00:00");
EXPECT_EQ(getDateTimeUintMs(std::numeric_limits<uint64_t>::min()),
"1970-01-01T00:00:00+00:00");
}
+} // namespace
+} // namespace crow::utility
diff --git a/http/utility.hpp b/http/utility.hpp
index 41182e4eb4..557926761c 100644
--- a/http/utility.hpp
+++ b/http/utility.hpp
@@ -577,6 +577,8 @@ inline bool base64Decode(const std::string_view input, std::string& output)
namespace details
{
+constexpr uint64_t maxMilliSeconds = 253402300799999;
+constexpr uint64_t maxSeconds = 253402300799;
inline std::string getDateTime(boost::posix_time::milliseconds timeSinceEpoch)
{
boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
@@ -586,23 +588,33 @@ inline std::string getDateTime(boost::posix_time::milliseconds timeSinceEpoch)
}
} // namespace details
+// Returns the formatted date time string.
+// Note that the maximum supported date is 9999-12-31T23:59:59+00:00, if
+// the given |secondsSinceEpoch| is too large, we return the maximum supported
+// date. This behavior is to avoid exceptions throwed by Boost.
inline std::string getDateTimeUint(uint64_t secondsSinceEpoch)
{
- boost::posix_time::seconds boostSeconds(secondsSinceEpoch);
+
+ boost::posix_time::seconds boostSeconds(
+ std::min(secondsSinceEpoch, details::maxSeconds));
return details::getDateTime(
boost::posix_time::milliseconds(boostSeconds.total_milliseconds()));
}
-inline std::string getDateTimeUintMs(uint64_t millisSecondsSinceEpoch)
+// Returns the formatted date time string.
+// Note that the maximum supported date is 9999-12-31T23:59:59.999+00:00, if
+// the given |millisSecondsSinceEpoch| is too large, we return the maximum
+// supported date.
+inline std::string getDateTimeUintMs(uint64_t milliSecondsSinceEpoch)
{
- return details::getDateTime(
- boost::posix_time::milliseconds(millisSecondsSinceEpoch));
+ return details::getDateTime(boost::posix_time::milliseconds(
+ std::min(details::maxMilliSeconds, milliSecondsSinceEpoch)));
}
inline std::string getDateTimeStdtime(std::time_t secondsSinceEpoch)
{
- boost::posix_time::ptime time =
- boost::posix_time::from_time_t(secondsSinceEpoch);
+ boost::posix_time::ptime time = boost::posix_time::from_time_t(
+ std::min(secondsSinceEpoch, std::time_t{details::maxSeconds}));
return boost::posix_time::to_iso_extended_string(time) + "+00:00";
}