json utility: fixed core dump during sensor load
bmcweb replaces underscores with spaces in sensor names for better
readability. The existing objectKeyCmp function did not handle this
case, leading to core dumps in the sensor load path.
Error details are provided below.
```
bmcwebd[1368]: [DEBUG sensors.hpp:507] Added sensor P0_NS_VR_FAN_2
bmcwebd[1368]: terminate called after throwing an instance of
'boost::detail::with_throw_location<boost::system::system_error>'
bmcwebd[1368]: what(): leftover [boost.url.grammar:4]
```
Implemented a new algorithm that alphabetically sorts non-URL keys
and retains the existing logic for URL-type keys.
Tested: Updated and verified the test cases.
Change-Id: I39c3f7cc54dec5e7cf9658977e1078acb827afb2
Signed-off-by: Jayanth Othayoth <ojayanth@gmail.com>
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index 9748b7b..24c82ea 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -22,6 +22,9 @@
#include "human_sort.hpp"
#include "logging.hpp"
+#include <boost/system/result.hpp>
+#include <boost/url/parse.hpp>
+#include <boost/url/url_view.hpp>
#include <nlohmann/json.hpp>
#include <algorithm>
@@ -791,22 +794,42 @@
{
return 1;
}
- boost::urls::url_view aUrl(*nameA);
- boost::urls::url_view bUrl(*nameB);
- auto segmentsAIt = aUrl.segments().begin();
- auto segmentsBIt = bUrl.segments().begin();
+ if (key != "@odata.id")
+ {
+ return alphanumComp(*nameA, *nameB);
+ }
+
+ boost::system::result<boost::urls::url_view> aUrl =
+ boost::urls::parse_relative_ref(*nameA);
+ boost::system::result<boost::urls::url_view> bUrl =
+ boost::urls::parse_relative_ref(*nameB);
+ if (!aUrl)
+ {
+ if (!bUrl)
+ {
+ return 0;
+ }
+ return -1;
+ }
+ if (!bUrl)
+ {
+ return 1;
+ }
+
+ auto segmentsAIt = aUrl->segments().begin();
+ auto segmentsBIt = bUrl->segments().begin();
while (true)
{
- if (segmentsAIt == aUrl.segments().end())
+ if (segmentsAIt == aUrl->segments().end())
{
- if (segmentsBIt == bUrl.segments().end())
+ if (segmentsBIt == bUrl->segments().end())
{
return 0;
}
return -1;
}
- if (segmentsBIt == bUrl.segments().end())
+ if (segmentsBIt == bUrl->segments().end())
{
return 1;
}
@@ -819,6 +842,7 @@
segmentsAIt++;
segmentsBIt++;
}
+ return 0;
};
// kept for backward compatibility
diff --git a/test/redfish-core/include/utils/json_utils_test.cpp b/test/redfish-core/include/utils/json_utils_test.cpp
index 3daa479..93671cc 100644
--- a/test/redfish-core/include/utils/json_utils_test.cpp
+++ b/test/redfish-core/include/utils/json_utils_test.cpp
@@ -484,6 +484,14 @@
0, objectKeyCmp("Name",
R"({"@odata.id": "/redfish/v1/1", "Name": "a"})"_json,
R"({"@odata.id": "/redfish/v1/1", "Name": "b"})"_json));
+ EXPECT_EQ(0, objectKeyCmp(
+ "Name",
+ R"({"@odata.id": "/redfish/v1/1", "Name": "a 45"})"_json,
+ R"({"@odata.id": "/redfish/v1/1", "Name": "a 45"})"_json));
+ EXPECT_GT(0, objectKeyCmp(
+ "Name",
+ R"({"@odata.id": "/redfish/v1/1", "Name": "a 45"})"_json,
+ R"({"@odata.id": "/redfish/v1/1", "Name": "b 45"})"_json));
EXPECT_GT(
0, objectKeyCmp("@odata.id",