[Libreoffice-commits] core.git: Branch 'feature/mar-updater' - 2 commits - desktop/source
Markus Mohrhard
markus.mohrhard at googlemail.com
Mon Apr 24 22:13:26 UTC 2017
desktop/source/app/updater.cxx | 113 +++++++++++++++++++++++++++++++++--------
1 file changed, 92 insertions(+), 21 deletions(-)
New commits:
commit 899754caa036a31dc45e9b79225c0dd882242054
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date: Mon Apr 24 23:57:22 2017 +0200
actually abort the update process if the update file is invalid
Change-Id: I724e50d1e74228f0be00b9b6376c3d074db5c9ed
diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx
index b4cc9430cfed..dc3a8be802d8 100644
--- a/desktop/source/app/updater.cxx
+++ b/desktop/source/app/updater.cxx
@@ -287,6 +287,40 @@ class invalid_update_info : public std::exception
{
};
+class invalid_hash : public std::exception
+{
+ OString maMessage;
+public:
+
+ invalid_hash(const OUString& rExpectedHash, const OUString& rReceivedHash)
+ {
+ OUString aMsg = "Invalid hash found.\nExpected: " + rExpectedHash + ";\nReceived: " + rReceivedHash;
+ maMessage = OUStringToOString(aMsg, RTL_TEXTENCODING_UTF8);
+ }
+
+ const char* what() const noexcept override
+ {
+ return maMessage.getStr();
+ }
+};
+
+class invalid_size : public std::exception
+{
+ OString maMessage;
+public:
+
+ invalid_size(const size_t nExpectedSize, const size_t nReceivedSize)
+ {
+ OUString aMsg = "Invalid file size found.\nExpected: " + OUString::number(nExpectedSize) + ";\nReceived: " + OUString::number(nReceivedSize);
+ maMessage = OUStringToOString(aMsg, RTL_TEXTENCODING_UTF8);
+ }
+
+ const char* what() const noexcept override
+ {
+ return maMessage.getStr();
+ }
+};
+
OUString toOUString(const std::string& rStr)
{
return OUString::fromUtf8(rStr.c_str());
@@ -540,11 +574,13 @@ void download_file(const OUString& rURL, size_t nFileSize, const OUString& rHash
if (nSize != nFileSize)
{
SAL_WARN("desktop.updater", "File sizes don't match. File might be corrupted.");
+ throw invalid_size(nFileSize, nSize);
}
if (aHash != rHash)
{
SAL_WARN("desktop.updater", "File hash don't match. File might be corrupted.");
+ throw invalid_hash(rHash, aHash);
}
OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/");
@@ -602,6 +638,14 @@ void update_checker()
{
SAL_WARN("desktop.updater", "error during the update check");
}
+ catch (const invalid_size& e)
+ {
+ SAL_WARN("desktop.updater", e.what());
+ }
+ catch (const invalid_hash& e)
+ {
+ SAL_WARN("desktop.updater", e.what());
+ }
catch (...)
{
SAL_WARN("desktop.updater", "unknown error during the update check");
commit ce2401e71108865f587dd11fe0d0a4085d67cb76
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date: Mon Apr 24 23:25:44 2017 +0200
actually check the hash of the update files
Change-Id: I98a5f8904a35cb167e87d6c5c11bcf133115cbc1
diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx
index e1b29d1402ec..b4cc9430cfed 100644
--- a/desktop/source/app/updater.cxx
+++ b/desktop/source/app/updater.cxx
@@ -31,6 +31,7 @@
#include <orcus/json_document_tree.hpp>
#include <orcus/config.hpp>
#include <orcus/pstring.hpp>
+#include <comphelper/hash.hxx>
namespace {
@@ -280,18 +281,6 @@ static size_t WriteCallback(void *ptr, size_t size,
return real_size;
}
-// Callback to get the response data from server to a file.
-static size_t WriteCallbackFile(void *ptr, size_t size,
- size_t nmemb, void *userp)
-{
- if (!userp)
- return 0;
-
- SvStream* response = static_cast<SvStream *>(userp);
- size_t real_size = size * nmemb;
- response->WriteBytes(static_cast<char *>(ptr), real_size);
- return real_size;
-}
class invalid_update_info : public std::exception
@@ -408,7 +397,45 @@ update_info parse_response(const std::string& rResponse)
return aUpdateInfo;
}
-std::string download_content(const OString& rURL, bool bFile)
+struct WriteDataFile
+{
+ comphelper::Hash maHash;
+ SvStream* mpStream;
+
+ WriteDataFile(SvStream* pStream):
+ maHash(comphelper::HashType::SHA512),
+ mpStream(pStream)
+ {
+ }
+
+ OUString getHash()
+ {
+ auto final_hash = maHash.finalize();
+ std::stringstream aStrm;
+ for (auto& i: final_hash)
+ {
+ aStrm << std::setw(2) << std::setfill('0') << std::hex << (int)i;
+ }
+
+ return toOUString(aStrm.str());
+ }
+};
+
+// Callback to get the response data from server to a file.
+size_t WriteCallbackFile(void *ptr, size_t size,
+ size_t nmemb, void *userp)
+{
+ if (!userp)
+ return 0;
+
+ WriteDataFile* response = static_cast<WriteDataFile *>(userp);
+ size_t real_size = size * nmemb;
+ response->mpStream->WriteBytes(static_cast<char *>(ptr), real_size);
+ response->maHash.update(static_cast<const unsigned char*>(ptr), real_size);
+ return real_size;
+}
+
+std::string download_content(const OString& rURL, bool bFile, OUString& rHash)
{
CURL* curl = curl_easy_init();
@@ -434,6 +461,7 @@ std::string download_content(const OString& rURL, bool bFile)
std::string response_body;
utl::TempFile aTempFile;
+ WriteDataFile aFile(aTempFile.GetStream(StreamMode::WRITE));
if (!bFile)
{
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
@@ -452,7 +480,7 @@ std::string download_content(const OString& rURL, bool bFile)
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallbackFile);
curl_easy_setopt(curl, CURLOPT_WRITEDATA,
- static_cast<void *>(aTempFile.GetStream(StreamMode::WRITE)));
+ static_cast<void *>(&aFile));
}
// Fail if 400+ is returned from the web server.
@@ -475,12 +503,10 @@ std::string download_content(const OString& rURL, bool bFile)
throw error_updater();
}
- return response_body;
-}
+ if (bFile)
+ rHash = aFile.getHash();
-OUString generateHash(const OUString& /*rURL*/)
-{
- return OUString();
+ return response_body;
}
void handle_file_error(osl::FileBase::RC eError)
@@ -498,7 +524,8 @@ void handle_file_error(osl::FileBase::RC eError)
void download_file(const OUString& rURL, size_t nFileSize, const OUString& rHash, const OUString& aFileName)
{
OString aURL = OUStringToOString(rURL, RTL_TEXTENCODING_UTF8);
- std::string temp_file = download_content(aURL, true);
+ OUString aHash;
+ std::string temp_file = download_content(aURL, true, aHash);
if (temp_file.empty())
throw error_updater();
@@ -515,7 +542,6 @@ void download_file(const OUString& rURL, size_t nFileSize, const OUString& rHash
SAL_WARN("desktop.updater", "File sizes don't match. File might be corrupted.");
}
- OUString aHash = generateHash(aTempFile);
if (aHash != rHash)
{
SAL_WARN("desktop.updater", "File hash don't match. File might be corrupted.");
@@ -550,7 +576,8 @@ void update_checker()
try
{
- std::string response_body = download_content(aURL, false);
+ OUString aHash;
+ std::string response_body = download_content(aURL, false, aHash);
if (!response_body.empty())
{
update_info aUpdateInfo = parse_response(response_body);
More information about the Libreoffice-commits
mailing list