From 8758f6dc798a963609d23c2fa710d85aeb937657 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 25 Sep 2024 04:03:57 +0200 Subject: [PATCH] utils: parse_client_version, parse_client_version_build_number() implemented + unit tests stub --- src/common/util.cpp | 71 +++++++++++++++++++------ src/common/util.h | 3 ++ tests/unit_tests/p2p_client_version.cpp | 18 +++++++ 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index 1fdbe537..f87f0582 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -658,31 +658,68 @@ std::string get_nix_version_display_string() return static_cast(in.tellg()); } - bool check_remote_client_version(const std::string& client_ver) + bool parse_client_version(const std::string& str, int& major, int& minor, int& revision, int& build_number, std::string& commit_id, bool& dirty) { - std::string v = client_ver.substr(0, client_ver.find('[')); // remove commit id - v = v.substr(0, v.rfind('.')); // remove build number + // "10.101.999.28391" + // "10.101.999.28391[deadbeef31337]" + // "10.101.999.28391[deadbeef31337-dirty]" + // 0123456789012345678901234567890123456 - int v_major = 0, v_minor = 0, v_revision = 0; - - size_t dot_pos = v.find('.'); - if (dot_pos == std::string::npos || !epee::string_tools::string_to_num_fast(v.substr(0, dot_pos), v_major)) + if (str.size() == 0) return false; - v = v.substr(dot_pos + 1); - dot_pos = v.find('.'); - if (!epee::string_tools::string_to_num_fast(v.substr(0, dot_pos), v_minor)) - return false; - - if (dot_pos != std::string::npos) + auto bracket_pos = str.find('['); + if (bracket_pos != std::string::npos) { - // revision - v = v.substr(dot_pos + 1); - if (!epee::string_tools::string_to_num_fast(v, v_revision)) + if (str[str.size() - 1] != ']') return false; + + commit_id = str.substr(bracket_pos + 1, str.size() - bracket_pos - 2); + auto d_pos = commit_id.find("-dirty"); + if (d_pos != std::string::npos) + { + dirty = true; + commit_id.erase(d_pos); + } } - // got v_major, v_minor, v_revision + std::string ver_str = str.substr(0, bracket_pos); + std::vector versions; + boost::split(versions, ver_str, boost::is_any_of(".")); + if (versions.size() != 4) + return false; + + if (!epee::string_tools::string_to_num_fast(versions[0], major)) + return false; + + if (!epee::string_tools::string_to_num_fast(versions[1], minor)) + return false; + + if (!epee::string_tools::string_to_num_fast(versions[2], revision)) + return false; + + if (!epee::string_tools::string_to_num_fast(versions[3], build_number)) + return false; + + return true; + } + + bool parse_client_version_build_number(const std::string& str, int& build_number) + { + int major = -1, minor = -1, revision = -1; + std::string commit_id; + bool dirty = false; + return tools::parse_client_version(str, major, minor, revision, build_number, commit_id, dirty); + } + + bool check_remote_client_version(const std::string& client_ver) + { + int v_major = 0, v_minor = 0, v_revision = 0, v_build_number = 0; + std::string commit_id; + bool dirty_flag = false; + + if (!parse_client_version(client_ver, v_major, v_minor, v_revision, v_build_number, commit_id, dirty_flag)) + return false; // allow 2.x and greater if (v_major < 2) diff --git a/src/common/util.h b/src/common/util.h index 0c5b0bb1..7761775d 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -37,6 +37,9 @@ namespace tools std::string get_current_username(); std::string get_os_version_string(); bool copy_dir(boost::filesystem::path const & source, boost::filesystem::path const & destination); + + bool parse_client_version(const std::string& str, int& major, int& minor, int& revision, int& build_number, std::string& commit_id, bool& dirty); + bool parse_client_version_build_number(const std::string& str, int& build_number); bool check_remote_client_version(const std::string& client_ver); bool create_directories_if_necessary(const std::string& path); diff --git a/tests/unit_tests/p2p_client_version.cpp b/tests/unit_tests/p2p_client_version.cpp index 183f6d36..e89817b0 100644 --- a/tests/unit_tests/p2p_client_version.cpp +++ b/tests/unit_tests/p2p_client_version.cpp @@ -5,6 +5,24 @@ #include "gtest/gtest.h" #include "common/util.h" +bool check_parse_client_version(const std::string& str, int expected_major, int expected_minor, int expected_revision, int expected_build_number, const std::string& expected_commit_id, bool expected_dirty) +{ + int major = -1, minor = -1, revision = -1, build_number = -1; + std::string commit_id; + bool dirty = false; + if (!tools::parse_client_version(str, major, minor, revision, build_number, commit_id, dirty)) + return false; + + return major == expected_major && minor == expected_minor && revision == expected_revision && build_number == expected_build_number && commit_id == expected_commit_id && dirty == expected_dirty; +} + + +TEST(p2p_client_version, test_0) +{ + ASSERT_TRUE(check_parse_client_version("10.101.999.28391[deadbeef31337-dirty]", 10, 101, 999, 28391, "deadbeef31337", true)); +} + + TEST(p2p_client_version, test_1) { using namespace tools;