pldmtool: platform: check for circular references

Avoid endless loops with:

pldmtool platform getpdr -a

by detecting circular references between records in the event of a
buggy/broken PLDM terminus implementation.

Change-Id: I2299c4d709fa0b8861956e55ada38da8fffb2d6e
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/pldmtool/pldm_platform_cmd.cpp b/pldmtool/pldm_platform_cmd.cpp
index 7949d45..aac669a 100644
--- a/pldmtool/pldm_platform_cmd.cpp
+++ b/pldmtool/pldm_platform_cmd.cpp
@@ -4,6 +4,9 @@
 #include "common/types.hpp"
 #include "pldm_cmd_helper.hpp"
 
+#include <cstddef>
+#include <map>
+
 #ifdef OEM_IBM
 #include "oem/ibm/oem_ibm_state_set.hpp"
 #endif
@@ -99,6 +102,7 @@
             // Retrieve all PDR records starting from the first
             recordHandle = 0;
             uint32_t prevRecordHandle = 0;
+            std::map<uint32_t, uint32_t> recordsSeen;
             do
             {
                 CommandInterface::exec();
@@ -109,6 +113,18 @@
                 {
                     return;
                 }
+
+                // check for circular references.
+                auto result =
+                    recordsSeen.emplace(recordHandle, prevRecordHandle);
+                if (!result.second)
+                {
+                    std::cerr
+                        << "Record handle " << recordHandle
+                        << " has multiple references: " << result.first->second
+                        << ", " << prevRecordHandle << "\n";
+                    return;
+                }
                 prevRecordHandle = recordHandle;
             } while (recordHandle != 0);
         }