PEL: Sanitize D-Bus fields that come from PELs

The Resolution D-Bus property is filled with values from the PEL callout
fields like the serial and part numbers.  These fields usually come from
EEPROMs, and may not necessarily be valid printable values if the code
that creates the PEL doesn't sanitize the values first.  If any of the
characters were invalid, the daemon would crash when D-Bus broker
disconnects it from D-Bus since it doesn't allow invalid values on
D-Bus.

Prevent this crash by converting any non printable characters in the
Resolution property to spaces.  This also sanitizes the EventId property
which contains the SRC ASCII string and hex words just to be safe.

This is really just a concern for non-BMC created PELs, since the BMC
code that reads EEPROMs already sanitizes the values when it reads them,
but PELs have come in from other subsystems that don't.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: If0e80fd9db27446f5367ed046e4bca2eb62e3fb2
diff --git a/extensions/openpower-pels/manager.cpp b/extensions/openpower-pels/manager.cpp
index 3b1e118..ee5919d 100644
--- a/extensions/openpower-pels/manager.cpp
+++ b/extensions/openpower-pels/manager.cpp
@@ -27,6 +27,7 @@
 
 #include <filesystem>
 #include <fstream>
+#include <locale>
 #include <xyz/openbmc_project/Common/error.hpp>
 #include <xyz/openbmc_project/Logging/Create/server.hpp>
 
@@ -735,7 +736,7 @@
             str += getNumberString("%08X", value);
         }
     }
-    return str;
+    return sanitizeFieldForDBus(str);
 }
 
 void Manager::updateEventId(std::unique_ptr<openpower::pels::PEL>& pel)
@@ -749,6 +750,17 @@
     }
 }
 
+std::string Manager::sanitizeFieldForDBus(std::string field)
+{
+    std::for_each(field.begin(), field.end(), [](char& ch) {
+        if (((ch < ' ') || (ch > '~')) && (ch != '\n') && (ch != '\t'))
+        {
+            ch = ' ';
+        }
+    });
+    return field;
+}
+
 std::string Manager::getResolution(const openpower::pels::PEL& pel) const
 {
     std::string str;
@@ -812,7 +824,7 @@
             }
         }
     }
-    return resolution;
+    return sanitizeFieldForDBus(resolution);
 }
 
 bool Manager::updateResolution(const openpower::pels::PEL& pel)
diff --git a/extensions/openpower-pels/manager.hpp b/extensions/openpower-pels/manager.hpp
index 4432634..fa8ac0f 100644
--- a/extensions/openpower-pels/manager.hpp
+++ b/extensions/openpower-pels/manager.hpp
@@ -273,6 +273,17 @@
      */
     void updateProgressSRC(std::unique_ptr<openpower::pels::PEL>& pel) const;
 
+    /**
+     * @brief Converts unprintable characters from the passed
+     *        in string to spaces so they won't crash D-Bus when
+     *        used as a property value.
+     *
+     * @param[in] field - The field to fix
+     *
+     * @return std::string - The string without non printable characters.
+     */
+    static std::string sanitizeFieldForDBus(std::string field);
+
   private:
     /**
      * @brief Adds a received raw PEL to the PEL repository