From 4df63be4d6d641bc670e8e5feec1fd3789df193f Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Fri, 11 Jun 2021 00:35:15 -0400
Subject: [PATCH] Add error handling to boost::filesystem usage

---
 indra/llfilesystem/lldiskcache.cpp  | 41 ++++++++++++++++++++++-------
 indra/llfilesystem/llfilesystem.cpp | 14 ++++++++--
 indra/newview/lllocalbitmaps.cpp    | 12 ++++++---
 indra/newview/llviewerwindow.cpp    | 19 ++++++++++---
 4 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index 43dca2f345f..3166a515481 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -80,16 +80,28 @@ void LLDiskCache::purge()
 #else
     std::string cache_path(sCacheDir);
 #endif
-    if (boost::filesystem::is_directory(cache_path))
+    boost::system::error_code ec;
+    if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
     {
         for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path), {}))
         {
-            if (boost::filesystem::is_regular_file(entry))
+            ec.clear();
+            if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
             {
                 if (entry.path().string().rfind(sCacheFilenameExt) != std::string::npos)
                 {
-                    uintmax_t file_size = boost::filesystem::file_size(entry);
-                    const std::time_t file_time = boost::filesystem::last_write_time(entry);
+                    const uintmax_t file_size = boost::filesystem::file_size(entry, ec);
+                    if (ec.failed())
+                    {
+                        LL_WARNS() << "Failed to read file size for cache file " << entry.path().string() << ": " << ec.message() << LL_ENDL;
+                        continue;
+                    }
+                    const std::time_t file_time = boost::filesystem::last_write_time(entry, ec);
+					if (ec.failed())
+					{
+						LL_WARNS() << "Failed to read last write time for cache file " << entry.path().string() << ": " << ec.message() << LL_ENDL;
+                        continue;
+					}
 
                     file_info.push_back(file_info_t(file_time, { file_size, entry.path() }));
                 }
@@ -118,6 +130,7 @@ void LLDiskCache::purge()
             if (ec.failed())
             {
                 LL_WARNS() << "Failed to delete cached file " << entry.second.second << ": " << ec.message() << LL_ENDL;
+                continue;
             }
         }
 
@@ -223,13 +236,13 @@ void LLDiskCache::clearCache()
 #else
     boost::filesystem::path cache_path(sCacheDir);
 #endif
-    if (boost::filesystem::is_directory(cache_path))
+    boost::system::error_code ec;
+    if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
     {
-        boost::system::error_code ec;
         boost::filesystem::remove_all(cache_path, ec);
         if (ec.failed())
         {
-            LL_WARNS() << "Failed to delete cached files " << cache_path << ": " << ec.message() << LL_ENDL;
+            LL_WARNS() << "Failed to delete cached files " << cache_path << " : " << ec.message() << LL_ENDL;
         }
 
         createCache();
@@ -254,15 +267,23 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir)
 #else
     boost::filesystem::path dir_path(dir);
 #endif
-    if (boost::filesystem::is_directory(dir_path))
+    boost::system::error_code ec;
+    if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed())
     {
         for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(dir_path), {}))
         {
-            if (boost::filesystem::is_regular_file(entry))
+            ec.clear();
+            if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
             {
                 if (entry.path().string().rfind(sCacheFilenameExt) != std::string::npos)
                 {
-                    total_file_size += boost::filesystem::file_size(entry);
+                    uintmax_t file_size = boost::filesystem::file_size(entry, ec);
+                    if (ec.failed())
+                    {
+                        LL_WARNS() << "Failed to get file size for cache file " << entry.path().string() << " : " << ec.message() << LL_ENDL;
+                        continue;
+                    }
+                    total_file_size += file_size;
                 }
             }
         }
diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp
index 72024ba3e2f..55eb9233c66 100644
--- a/indra/llfilesystem/llfilesystem.cpp
+++ b/indra/llfilesystem/llfilesystem.cpp
@@ -311,6 +311,7 @@ BOOL LLFileSystem::exists()
 
 void LLFileSystem::updateFileAccessTime()
 {
+    boost::system::error_code ec;
     /**
      * Threshold in time_t units that is used to decide if the last access time
      * time of the file is updated or not. Added as a precaution for the concern
@@ -326,7 +327,12 @@ void LLFileSystem::updateFileAccessTime()
     const std::time_t cur_time = std::time(nullptr);
 
     // file last write time
-    const std::time_t last_write_time = boost::filesystem::last_write_time(mFilePath);
+    const std::time_t last_write_time = boost::filesystem::last_write_time(mFilePath, ec);
+    if (ec.failed())
+    {
+        LL_WARNS() << "Failed to read last write time for cache file " << mFilePath << ": " << ec.message() << LL_ENDL;
+        return;
+    }
 
     // delta between cur time and last time the file was written
     const std::time_t delta_time = cur_time - last_write_time;
@@ -335,7 +341,11 @@ void LLFileSystem::updateFileAccessTime()
     // before the last one
     if (delta_time > time_threshold)
     {
-        boost::filesystem::last_write_time(mFilePath, cur_time);
+        boost::filesystem::last_write_time(mFilePath, cur_time, ec);
+		if (ec.failed())
+		{
+			LL_WARNS() << "Failed to update last write time for cache file " << mFilePath << ": " << ec.message() << LL_ENDL;
+		}
     }
 }
 
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index f07259e7b0d..07ffef8aa08 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -183,12 +183,18 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
 		if (LLFile::isfile(mFilename))
 		{
 			// verifying that the file has indeed been modified
-
+			boost::system::error_code ec;
 #ifndef LL_WINDOWS
-			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
+			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename), ec);
 #else
-			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(ll_convert_string_to_wide(mFilename)));
+			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(ll_convert_string_to_wide(mFilename)), ec);
 #endif
+			if (ec.failed())
+			{
+				LL_WARNS() << "Failed to get last write time for filesystem path " << mFilename << " : " << ec.message() << LL_ENDL;
+				return false;
+			}
+
 			LLSD new_last_modified = asctime(localtime(&temp_time));
 
 			if (mLastModified.asString() != new_last_modified.asString())
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d08d1462983..c9c64c02417 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4856,13 +4856,20 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save
 		return;
 	}
 
-// Check if there is enough free space to save snapshot
+	// Check if there is enough free space to save snapshot
+	boost::system::error_code ec;
 #ifdef LL_WINDOWS
 	boost::filesystem::path b_path(ll_convert_string_to_wide(lastSnapshotDir));
 #else
 	boost::filesystem::path b_path(lastSnapshotDir);
 #endif
-	if (!boost::filesystem::is_directory(b_path))
+	bool is_dir = boost::filesystem::is_directory(b_path, ec);
+	if (ec.failed())
+	{
+		LL_WARNS() << "Failed check for is directory for filesystem path " << lastSnapshotDir << " : " << ec.message() << LL_ENDL;
+		return;
+	}
+	if (!is_dir)
 	{
 		LLSD args;
 		args["PATH"] = lastSnapshotDir;
@@ -4871,7 +4878,12 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save
 		failure_cb();
 		return;
 	}
-	boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
+	boost::filesystem::space_info b_space = boost::filesystem::space(b_path, ec);
+	if (ec.failed())
+	{
+		LL_WARNS() << "Failed to read disk space for filesystem path " << lastSnapshotDir << " : " << ec.message() << LL_ENDL;
+		return;
+	}
 	if (b_space.free < image->getDataSize())
 	{
 		LLSD args;
@@ -4888,6 +4900,7 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save
 		LLNotificationsUtil::add("SnapshotToComputerFailed", args);
 
 		failure_cb();
+		return;
 	}
 	
 	// Look for an unused file name
-- 
GitLab