Change readJson from is_object to get_ptr
While is_object is useful in contexts where we don't need the underlying
value, in cases where we do, nlohmann::json::begin() can throw when
generating the nlohmann::iterator_proxy object. This causes unwind
tables to be generated, so as a general rule, we should be prefering
get_ptr in these cases.
Tested: Good unit test coverage for readJson. Unit tests only.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I5ecb2dca95cc06246e983f9e4190b2dd46d1a6b9
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index a7a27ff..26b9a8a 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -404,13 +404,15 @@
std::span<PerUnpack> toUnpack)
{
bool result = true;
- if (!jsonRequest.is_object())
+ nlohmann::json::object_t* obj =
+ jsonRequest.get_ptr<nlohmann::json::object_t*>();
+ if (obj == nullptr)
{
BMCWEB_LOG_DEBUG << "Json value is not an object";
messages::unrecognizedRequestBody(res);
return false;
}
- for (const auto& item : jsonRequest.items())
+ for (auto& item : *obj)
{
size_t unpackIndex = 0;
for (; unpackIndex < toUnpack.size(); unpackIndex++)
@@ -425,7 +427,7 @@
key = key.substr(0, keysplitIndex);
}
- if (key != item.key() || unpackSpec.complete)
+ if (key != item.first || unpackSpec.complete)
{
continue;
}
@@ -436,7 +438,7 @@
// Include the slash in the key so we can compare later
key = unpackSpec.key.substr(0, keysplitIndex + 1);
nlohmann::json j;
- result = details::unpackValue<nlohmann::json>(item.value(), key,
+ result = details::unpackValue<nlohmann::json>(item.second, key,
res, j) &&
result;
if (!result)
@@ -465,7 +467,7 @@
using ContainedT =
std::remove_pointer_t<std::decay_t<decltype(val)>>;
return details::unpackValue<ContainedT>(
- item.value(), unpackSpec.key, res, *val);
+ item.second, unpackSpec.key, res, *val);
},
unpackSpec.value) &&
result;
@@ -476,7 +478,7 @@
if (unpackIndex == toUnpack.size())
{
- messages::propertyUnknown(res, item.key());
+ messages::propertyUnknown(res, item.first);
result = false;
}
}