From 1368a94f014884588b343802eef5fd2c7888390a Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 12 Nov 2010 12:23:30 -0800
Subject: [PATCH] do not resume or install if current viewer version doesn't
 match the recorded version which started the process.

---
 .../updater/llupdatedownloader.cpp            |  2 +
 .../updater/llupdaterservice.cpp              | 71 ++++++++++++++++---
 .../updater/llupdaterservice.h                |  3 +
 3 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 21555dc3ff4..ab441aa7479 100644
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -35,6 +35,7 @@
 #include "llsdserialize.h"
 #include "llthread.h"
 #include "llupdatedownloader.h"
+#include "llupdaterservice.h"
 
 
 class LLUpdateDownloader::Implementation:
@@ -360,6 +361,7 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std
 {
 	mDownloadData["url"] = uri.asString();
 	mDownloadData["hash"] = hash;
+	mDownloadData["current_version"] = ll_get_version();
 	LLSD path = uri.pathArray();
 	if(path.size() == 0) throw DownloadError("no file path");
 	std::string fileName = path[path.size() - 1].asString();
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 43551d6cea8..6cc872f2ca9 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -31,6 +31,7 @@
 #include "llupdaterservice.h"
 #include "llupdatechecker.h"
 #include "llupdateinstaller.h"
+#include "llversionviewer.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/weak_ptr.hpp>
@@ -237,7 +238,23 @@ bool LLUpdaterServiceImpl::checkForInstall()
 
 		// Get the path to the installer file.
 		LLSD path = update_info.get("path");
-		if(path.isDefined() && !path.asString().empty())
+		if(update_info["current_version"].asString() != ll_get_version())
+		{
+			// This viewer is not the same version as the one that downloaded
+			// the update.  Do not install this update.
+			if(!path.asString().empty())
+			{
+				llinfos << "ignoring update dowloaded by different client version" << llendl;
+				LLFile::remove(path.asString());
+			}
+			else
+			{
+				; // Nothing to clean up.
+			}
+			
+			result = false;
+		} 
+		else if(path.isDefined() && !path.asString().empty())
 		{
 			int result = ll_install_update(install_script_path(),
 										   update_info["path"].asString(),
@@ -251,9 +268,9 @@ bool LLUpdaterServiceImpl::checkForInstall()
 			} else {
 				; // No op.
 			}
+			
+			result = true;
 		}
-
-		result = true;
 	}
 	return result;
 }
@@ -261,14 +278,33 @@ bool LLUpdaterServiceImpl::checkForInstall()
 bool LLUpdaterServiceImpl::checkForResume()
 {
 	bool result = false;
-	llstat stat_info;
-	if(0 == LLFile::stat(mUpdateDownloader.downloadMarkerPath(), &stat_info))
+	std::string download_marker_path = mUpdateDownloader.downloadMarkerPath();
+	if(LLFile::isfile(download_marker_path))
 	{
-		mIsDownloading = true;
-		mUpdateDownloader.resume();
-		result = true;
+		llifstream download_marker_stream(download_marker_path, 
+								 std::ios::in | std::ios::binary);
+		if(download_marker_stream.is_open())
+		{
+			LLSD download_info;
+			LLSDSerialize::fromXMLDocument(download_info, download_marker_stream);
+			download_marker_stream.close();
+			if(download_info["current_version"].asString() == ll_get_version())
+			{
+				mIsDownloading = true;
+				mUpdateDownloader.resume();
+				result = true;
+			}
+			else 
+			{
+				// The viewer that started this download is not the same as this viewer; ignore.
+				llinfos << "ignoring partial download from different viewer version" << llendl;
+				std::string path = download_info["path"].asString();
+				if(!path.empty()) LLFile::remove(path);
+				LLFile::remove(download_marker_path);
+			}
+		} 
 	}
-	return false;
+	return result;
 }
 
 void LLUpdaterServiceImpl::error(std::string const & message)
@@ -406,3 +442,20 @@ void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callbac
 {
 	return mImpl->setAppExitCallback(aecb);
 }
+
+
+std::string const & ll_get_version(void) {
+	static std::string version("");
+	
+	if (version.empty()) {
+		std::ostringstream stream;
+		stream << LL_VERSION_MAJOR << "."
+		<< LL_VERSION_MINOR << "."
+		<< LL_VERSION_PATCH << "."
+		<< LL_VERSION_BUILD;
+		version = stream.str();
+	}
+	
+	return version;
+}
+
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 42ec3a2cab3..ec20dc6e053 100644
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -68,4 +68,7 @@ class LLUpdaterService
 	void setImplAppExitCallback(app_exit_callback_t aecb);
 };
 
+// Returns the full version as a string.
+std::string const & ll_get_version(void);
+
 #endif // LL_UPDATERSERVICE_H
-- 
GitLab