From 346baf8e9b042425a5af7533616f044257d98f9b Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 20 Feb 2016 18:23:46 +0100 Subject: [PATCH] Only show update check warning if version on server is actually newer --- src/cryfs/CMakeLists.txt | 1 + src/cryfs/cli/Cli.cpp | 5 ++- src/cryfs/cli/VersionCompare.cpp | 43 +++++++++++++++++++++ src/cryfs/cli/VersionCompare.h | 19 ++++++++++ test/cryfs/CMakeLists.txt | 1 + test/cryfs/cli/VersionCompareTest.cpp | 54 +++++++++++++++++++++++++++ 6 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 src/cryfs/cli/VersionCompare.cpp create mode 100644 src/cryfs/cli/VersionCompare.h create mode 100644 test/cryfs/cli/VersionCompareTest.cpp diff --git a/src/cryfs/CMakeLists.txt b/src/cryfs/CMakeLists.txt index 1c997d7a..fdd5c12a 100644 --- a/src/cryfs/CMakeLists.txt +++ b/src/cryfs/CMakeLists.txt @@ -3,6 +3,7 @@ project (cryfs) set(SOURCES cli/Cli.cpp cli/VersionChecker.cpp + cli/VersionCompare.cpp cli/CallAfterTimeout.cpp cli/program_options/utils.cpp cli/program_options/ProgramOptions.cpp diff --git a/src/cryfs/cli/Cli.cpp b/src/cryfs/cli/Cli.cpp index dc52a6bb..7d9a47a8 100644 --- a/src/cryfs/cli/Cli.cpp +++ b/src/cryfs/cli/Cli.cpp @@ -21,6 +21,7 @@ #include #include "VersionChecker.h" +#include "VersionCompare.h" //TODO Fails with gpg-homedir in filesystem: gpg --homedir gpg-homedir --gen-key //TODO Many functions accessing the ProgramOptions object. Factor out into class that stores it as a member. @@ -90,8 +91,8 @@ namespace cryfs { VersionChecker versionChecker(_httpClient); optional newestVersion = versionChecker.newestVersion(); if (newestVersion == none) { - cout << "Could not connect to cryfs.org to check for updates." << endl; - } else if (*newestVersion != version::VERSION_STRING) { + cout << "Could not check for updates." << endl; + } else if (VersionCompare::isOlderThan(version::VERSION_STRING, *newestVersion)) { cout << "CryFS " << *newestVersion << " is released. Please update." << endl; } optional securityWarning = versionChecker.securityWarningFor(version::VERSION_STRING); diff --git a/src/cryfs/cli/VersionCompare.cpp b/src/cryfs/cli/VersionCompare.cpp new file mode 100644 index 00000000..3464354c --- /dev/null +++ b/src/cryfs/cli/VersionCompare.cpp @@ -0,0 +1,43 @@ +#include "VersionCompare.h" + +using std::string; + +namespace cryfs { + + bool VersionCompare::isOlderThan(const string &v1, const string &v2) { + return _isOlderThanStartingFrom(v1, v2, 0, 0); + } + + bool VersionCompare::_isOlderThanStartingFrom(const string &v1, const string &v2, size_t startPos1, size_t startPos2) { + if (startPos1 > v1.size() && startPos2 > v2.size()) { + // All components are equal + return false; + } + string componentStr1 = _extractComponent(v1, startPos1); + string componentStr2 = _extractComponent(v2, startPos2); + uint32_t component1 = _parseComponent(componentStr1); + uint32_t component2 = _parseComponent(componentStr2); + if (component1 == component2) { + return _isOlderThanStartingFrom(v1, v2, startPos1 + componentStr1.size() + 1, startPos2 + componentStr2.size() + 1); + } + return component1 < component2; + } + + string VersionCompare::_extractComponent(const string &version, size_t startPos) { + if (startPos >= version.size()) { + return ""; + } + size_t found = version.find('.', startPos); + if (found == string::npos) { + return version.substr(startPos); + } + return version.substr(startPos, found-startPos); + } + + uint32_t VersionCompare::_parseComponent(const string &component) { + if (component == "" || component.substr(0, 3) == "dev") { + return 0; + } + return std::stoul(component); + } +} diff --git a/src/cryfs/cli/VersionCompare.h b/src/cryfs/cli/VersionCompare.h new file mode 100644 index 00000000..5c1ad569 --- /dev/null +++ b/src/cryfs/cli/VersionCompare.h @@ -0,0 +1,19 @@ +#pragma once +#ifndef MESSMER_CRYFS_CLI_VERSIONCOMPARE_H +#define MESSMER_CRYFS_CLI_VERSIONCOMPARE_H + +#include + +namespace cryfs { + class VersionCompare { + public: + static bool isOlderThan(const std::string &v1, const std::string &v2); + + private: + static bool _isOlderThanStartingFrom(const std::string &v1, const std::string &v2, size_t startPos1, size_t startPos2); + static std::string _extractComponent(const std::string &version, size_t startPos); + static uint32_t _parseComponent(const std::string &component); + }; +} + +#endif diff --git a/test/cryfs/CMakeLists.txt b/test/cryfs/CMakeLists.txt index 8ba9d344..0790a4a7 100644 --- a/test/cryfs/CMakeLists.txt +++ b/test/cryfs/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES cli/program_options/ParserTest.cpp cli/CliTest_ShowingHelp.cpp cli/VersionCheckerTest.cpp + cli/VersionCompareTest.cpp config/crypto/CryConfigEncryptorFactoryTest.cpp config/crypto/outer/OuterConfigTest.cpp config/crypto/outer/OuterEncryptorTest.cpp diff --git a/test/cryfs/cli/VersionCompareTest.cpp b/test/cryfs/cli/VersionCompareTest.cpp new file mode 100644 index 00000000..f1bc75f4 --- /dev/null +++ b/test/cryfs/cli/VersionCompareTest.cpp @@ -0,0 +1,54 @@ +#include +#include + +using namespace cryfs; +using std::string; + +class VersionCompareTest : public ::testing::Test { +public: + void EXPECT_IS_OLDER_THAN(const string &v1, const string &v2) { + EXPECT_TRUE(VersionCompare::isOlderThan(v1, v2)); + EXPECT_FALSE(VersionCompare::isOlderThan(v2, v1)); + } + + void EXPECT_IS_SAME_AGE(const string &v1, const string &v2) { + EXPECT_FALSE(VersionCompare::isOlderThan(v1, v2)); + EXPECT_FALSE(VersionCompare::isOlderThan(v2, v1)); + } +}; + +TEST_F(VersionCompareTest, IsDifferentVersion) { + EXPECT_IS_OLDER_THAN("0.8", "0.8.1"); + EXPECT_IS_OLDER_THAN("0.8", "1.0"); + EXPECT_IS_OLDER_THAN("0.8", "1.0.1"); + EXPECT_IS_OLDER_THAN("0.8.1", "1.0"); + EXPECT_IS_OLDER_THAN("0.7.9", "0.8.0"); + EXPECT_IS_OLDER_THAN("1.0.0", "1.0.1"); + EXPECT_IS_OLDER_THAN("1.0.0.0", "1.0.0.1"); + EXPECT_IS_OLDER_THAN("1", "1.0.0.1"); + EXPECT_IS_OLDER_THAN("1.0.0.0", "1.1"); +} + +TEST_F(VersionCompareTest, IsSameVersion) { + EXPECT_IS_SAME_AGE("0.8", "0.8"); + EXPECT_IS_SAME_AGE("1.0", "1.0"); + EXPECT_IS_SAME_AGE("1", "1.0"); + EXPECT_IS_SAME_AGE("1.0.0", "1.0.0"); + EXPECT_IS_SAME_AGE("0.8", "0.8.0"); + EXPECT_IS_SAME_AGE("1", "1.0.0.0"); +} + +TEST_F(VersionCompareTest, ZeroPrefix) { + EXPECT_IS_OLDER_THAN("1.00.0", "1.0.01"); + EXPECT_IS_SAME_AGE("1.0.01", "1.0.1"); + EXPECT_IS_SAME_AGE("01.0.01", "1.0.1"); +} + +TEST_F(VersionCompareTest, DevVersions) { + EXPECT_IS_OLDER_THAN("0.8", "0.8.1.dev1"); + EXPECT_IS_OLDER_THAN("0.8.1", "0.8.2.dev2"); + EXPECT_IS_OLDER_THAN("0.8.1.dev1", "0.8.2"); + EXPECT_IS_OLDER_THAN("0.8.dev1", "0.8.1"); + EXPECT_IS_OLDER_THAN("0.8.dev1", "0.9"); + EXPECT_IS_SAME_AGE("0.9.1.dev5", "0.9.1"); +} \ No newline at end of file