From 65df1d8df95274c79db8c91a8b6eb5c3bfa077a8 Mon Sep 17 00:00:00 2001 From: henriquegeremia Date: Sat, 27 Jun 2026 01:58:18 -0300 Subject: [PATCH 1/2] Fix false positive update alert when local version is newer --- src/update-checker/update-checker.cpp | 41 +++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/update-checker/update-checker.cpp b/src/update-checker/update-checker.cpp index fff860f6..2b4df4bf 100644 --- a/src/update-checker/update-checker.cpp +++ b/src/update-checker/update-checker.cpp @@ -13,12 +13,49 @@ #include "../plugin-support.h" #include +#include +#include +#include extern "C" const char *PLUGIN_VERSION; static std::string latestVersionForUpdate; static std::mutex latestVersionMutex; +static bool is_newer_version(const std::string& remote, const std::string& local) +{ + std::vector remote_parts; + std::vector local_parts; + std::string part; + + std::stringstream ss_remote(remote); + while (std::getline(ss_remote, part, '.')) { + try { + remote_parts.push_back(std::stoi(part)); + } catch (...) { + remote_parts.push_back(0); + } + } + + std::stringstream ss_local(local); + while (std::getline(ss_local, part, '.')) { + try { + local_parts.push_back(std::stoi(part)); + } catch (...) { + local_parts.push_back(0); + } + } + + size_t max_parts = std::max(remote_parts.size(), local_parts.size()); + for (size_t i = 0; i < max_parts; ++i) { + int r = i < remote_parts.size() ? remote_parts[i] : 0; + int l = i < local_parts.size() ? local_parts[i] : 0; + if (r > l) return true; + if (r < l) return false; + } + return false; +} + void check_update(void) { bool shouldCheckForUpdates = false; @@ -41,8 +78,8 @@ void check_update(void) } obs_log(LOG_INFO, "Latest release is %s", info.version.c_str()); - if (info.version == PLUGIN_VERSION) { - // No update available, latest version is the same as the current version + if (!is_newer_version(info.version, PLUGIN_VERSION)) { + // No update available, latest version is not newer than the current version std::lock_guard lock(latestVersionMutex); latestVersionForUpdate.clear(); return; From 2f1267a0c5f101139fef2c907bb1fdeff3c7507e Mon Sep 17 00:00:00 2001 From: henriquegeremia Date: Sun, 28 Jun 2026 00:19:28 -0300 Subject: [PATCH 2/2] Refactor update checker to use std::regex for version comparison --- src/update-checker/update-checker.cpp | 52 +++++++++++++-------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/src/update-checker/update-checker.cpp b/src/update-checker/update-checker.cpp index 2b4df4bf..cb0a110b 100644 --- a/src/update-checker/update-checker.cpp +++ b/src/update-checker/update-checker.cpp @@ -13,8 +13,7 @@ #include "../plugin-support.h" #include -#include -#include +#include #include extern "C" const char *PLUGIN_VERSION; @@ -24,36 +23,33 @@ static std::mutex latestVersionMutex; static bool is_newer_version(const std::string& remote, const std::string& local) { - std::vector remote_parts; - std::vector local_parts; - std::string part; - - std::stringstream ss_remote(remote); - while (std::getline(ss_remote, part, '.')) { - try { - remote_parts.push_back(std::stoi(part)); - } catch (...) { - remote_parts.push_back(0); - } - } + std::regex version_regex(R"(^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z]+)(?:\.?(\d+))?)?$)"); + std::smatch remote_match; + std::smatch local_match; - std::stringstream ss_local(local); - while (std::getline(ss_local, part, '.')) { - try { - local_parts.push_back(std::stoi(part)); - } catch (...) { - local_parts.push_back(0); - } + bool remote_valid = std::regex_match(remote, remote_match, version_regex); + bool local_valid = std::regex_match(local, local_match, version_regex); + + if (!remote_valid || !local_valid) { + // Fallback to basic string comparison if regex fails + return remote > local; } - size_t max_parts = std::max(remote_parts.size(), local_parts.size()); - for (size_t i = 0; i < max_parts; ++i) { - int r = i < remote_parts.size() ? remote_parts[i] : 0; - int l = i < local_parts.size() ? local_parts[i] : 0; - if (r > l) return true; - if (r < l) return false; + int remote_major = std::stoi(remote_match[1].str()); + int remote_minor = std::stoi(remote_match[2].str()); + int remote_patch = std::stoi(remote_match[3].str()); + + int local_major = std::stoi(local_match[1].str()); + int local_minor = std::stoi(local_match[2].str()); + int local_patch = std::stoi(local_match[3].str()); + + if (remote_major != local_major) { + return remote_major > local_major; + } + if (remote_minor != local_minor) { + return remote_minor > local_minor; } - return false; + return remote_patch > local_patch; } void check_update(void)