From d29c0ee50a606bf1f4510ea427aef257870c17c0 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Tue, 4 Oct 2016 12:20:00 +0200
Subject: Handle boost::bad_lexical_cast exception in StatusCache

Modernised code to C++11 lambdas and range-based for loops,
and cleaned up includes in the process.

Test-Information:

All unit tests pass with ASAN-enabled built on macOS 10.12.
Verified recent status list is still loaded in Swift UI.

Change-Id: I44fe09a079cfae15ed9fb2860e7352badedf6c1c

diff --git a/Swift/Controllers/StatusCache.cpp b/Swift/Controllers/StatusCache.cpp
index ce4391d..3c6baed 100644
--- a/Swift/Controllers/StatusCache.cpp
+++ b/Swift/Controllers/StatusCache.cpp
@@ -8,17 +8,13 @@
 
 #include <boost/algorithm/string.hpp>
 #include <boost/filesystem/fstream.hpp>
-#include <boost/lambda/bind.hpp>
-#include <boost/lambda/lambda.hpp>
 #include <boost/lexical_cast.hpp>
 
 #include <Swiften/Base/ByteArray.h>
-#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/Log.h>
 
 #include <SwifTools/Application/ApplicationPathProvider.h>
 
-namespace lambda = boost::lambda;
-
 namespace Swift {
 
 static const size_t MAX_ENTRIES = 200;
@@ -35,7 +31,7 @@ StatusCache::~StatusCache() {
 
 std::vector<StatusCache::PreviousStatus> StatusCache::getMatches(const std::string& substring, size_t maxCount) const {
     std::vector<PreviousStatus> matches;
-    foreach (const PreviousStatus& status, previousStatuses_) {
+    for (const auto& status : previousStatuses_) {
         if (substring.empty() || (boost::algorithm::ifind_first(status.first, substring) && substring != status.first)) {
             matches.push_back(status);
             if (matches.size() == maxCount) {
@@ -50,7 +46,9 @@ void StatusCache::addRecent(const std::string& text, StatusShow::Type type) {
     if (text.empty()) {
         return;
     }
-    previousStatuses_.remove_if(lambda::bind(&PreviousStatus::first, lambda::_1) == text && lambda::bind(&PreviousStatus::second, lambda::_1) == type);
+    previousStatuses_.remove_if([&](const PreviousStatus& previousStatus) {
+        return previousStatus.first == text && previousStatus.second == type;
+    });
     previousStatuses_.push_front(PreviousStatus(text, type));
     for (size_t i = previousStatuses_.size(); i > MAX_ENTRIES; i--) {
         previousStatuses_.pop_back();
@@ -66,20 +64,25 @@ void StatusCache::loadRecents() {
             std::string stringData = byteArrayToString(data);
             std::vector<std::string> lines;
             boost::split(lines, stringData, boost::is_any_of("\n"));
-            foreach (const std::string& line, lines) {
+            for (const auto& line : lines) {
                 std::vector<std::string> bits;
                 boost::split(bits, line, boost::is_any_of("\t"));
                 if (bits.size() < 2) {
                     continue;
                 }
                 StatusShow::Type type;
-                type = static_cast<StatusShow::Type>(boost::lexical_cast<size_t>(bits[0]));
-                previousStatuses_.push_back(PreviousStatus(boost::trim_copy(bits[1]), type));
+                try {
+                    type = static_cast<StatusShow::Type>(boost::lexical_cast<size_t>(bits[0]));
+                    previousStatuses_.push_back(PreviousStatus(boost::trim_copy(bits[1]), type));
+                }
+                catch (const boost::bad_lexical_cast& e) {
+                    SWIFT_LOG(error) << "Failed to load recent status cache entry: " << e.what() << std::endl;
+                }
             }
         }
     }
     catch (const boost::filesystem::filesystem_error& e) {
-        std::cerr << "ERROR: " << e.what() << std::endl;
+        SWIFT_LOG(error) << "Failed to load recents: " << e.what() << std::endl;
     }
 }
 
@@ -89,7 +92,7 @@ void StatusCache::saveRecents() {
             boost::filesystem::create_directories(path_.parent_path());
         }
         boost::filesystem::ofstream file(path_);
-        foreach (const PreviousStatus& recent, previousStatuses_) {
+        for (const auto& recent : previousStatuses_) {
             std::string message = recent.first;
             boost::replace_all(message, "\t", " ");
             file << recent.second << "\t" << message << std::endl;
@@ -97,7 +100,7 @@ void StatusCache::saveRecents() {
         file.close();
     }
     catch (const boost::filesystem::filesystem_error& e) {
-        std::cerr << "ERROR: " << e.what() << std::endl;
+        SWIFT_LOG(error) << "Failed to save recents: " << e.what() << std::endl;
     }
 }
 
diff --git a/Swift/Controllers/StatusCache.h b/Swift/Controllers/StatusCache.h
index 033cde0..83fd17a 100644
--- a/Swift/Controllers/StatusCache.h
+++ b/Swift/Controllers/StatusCache.h
@@ -6,11 +6,9 @@
 
 #pragma once
 
-#include <iostream>
 #include <list>
 #include <string>
 #include <utility>
-#include <vector>
 
 #include <boost/filesystem/path.hpp>
 
@@ -18,6 +16,7 @@
 
 namespace Swift {
     class ApplicationPathProvider;
+
     class StatusCache {
         public:
             typedef std::pair<std::string, StatusShow::Type> PreviousStatus;
@@ -27,9 +26,11 @@ namespace Swift {
 
             std::vector<PreviousStatus> getMatches(const std::string& substring, size_t maxCount) const;
             void addRecent(const std::string& text, StatusShow::Type type);
+
         private:
             void saveRecents();
             void loadRecents();
+
         private:
             boost::filesystem::path path_;
             std::list<PreviousStatus> previousStatuses_;
-- 
cgit v0.10.2-6-g49f6