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;
         }
     }