Fix for restoreFromFile cereal exception

This commit provides a fix for an issue in which the cereal
restoreFromFile() would crash the host software updater in the event
that a priority persistence file is empty.

Resolves openbmc/openbmc#2091

Change-Id: Icca5d68ef250e2662cd02075c6ba731e4ab768b0
Signed-off-by: Michael Tritz <mtritz@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index d022c96..0f583ed 100755
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -194,23 +194,18 @@
             // If Active, create RedundancyPriority instance for this version.
             if (activationState == server::Activation::Activations::Active)
             {
-                if(fs::is_regular_file(PERSIST_DIR + id))
+                uint8_t priority = std::numeric_limits<uint8_t>::max();
+                if (!restoreFromFile(id, priority))
                 {
-                    uint8_t priority;
-                    restoreFromFile(id, &priority);
-                    activations.find(id)->second->redundancyPriority =
-                             std::make_unique<RedundancyPriority>(
-                                 bus,
-                                 path,
-                                 *(activations.find(id)->second),
-                                 priority);
+                    log<level::ERR>("Unable to restore priority from file.",
+                            entry("VERSIONID=%s", id));
                 }
-                else
-                {
-                    activations.find(id)->second->activation(
-                            server::Activation::Activations::Invalid);
-                }
-
+                activations.find(id)->second->redundancyPriority =
+                         std::make_unique<RedundancyPriority>(
+                             bus,
+                             path,
+                             *(activations.find(id)->second),
+                             priority);
             }
 
             // Create Version instance for this version.
diff --git a/serialize.cpp b/serialize.cpp
index 8e95727..a499798 100644
--- a/serialize.cpp
+++ b/serialize.cpp
@@ -26,15 +26,24 @@
     oarchive(cereal::make_nvp("priority", priority));
 }
 
-void restoreFromFile(std::string versionId, uint8_t *priority)
+bool restoreFromFile(std::string versionId, uint8_t& priority)
 {
     std::string path = PERSIST_DIR + versionId;
     if (fs::exists(path))
     {
         std::ifstream is(path.c_str(), std::ios::in);
-        cereal::JSONInputArchive iarchive(is);
-        iarchive(cereal::make_nvp("priority", *priority));
+        try
+        {
+            cereal::JSONInputArchive iarchive(is);
+            iarchive(cereal::make_nvp("priority", priority));
+            return true;
+        }
+        catch(cereal::RapidJSONException& e)
+        {
+            fs::remove(path);
+        }
     }
+    return false;
 }
 
 void removeFile(std::string versionId)
diff --git a/serialize.hpp b/serialize.hpp
index 90210a5..4e6e99f 100644
--- a/serialize.hpp
+++ b/serialize.hpp
@@ -21,8 +21,9 @@
 /** @brief Serialization function - restores activation information from file
  *  @param[in] versionId - The version for which to retrieve information.
  *  @param[in] priority - RedundancyPriority pointer for that version.
+ *  @return true if restore was successful, false if not
  */
-void restoreFromFile(std::string versionId, uint8_t *priority);
+bool restoreFromFile(std::string versionId, uint8_t& priority);
 
 /** @brief Removes the serial file for a given version.
  *  @param[in] versionId - The version for which to remove a file, if it exists.