Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Addons] RepositoryUpdater: fix time calculation overflow #26531

Merged
merged 1 commit into from
Mar 17, 2025

Conversation

mglae
Copy link
Contributor

@mglae mglae commented Mar 14, 2025

Description

Using (32 bit) int for ms calculation lead to (negative) overflow when more than ~25 days ago. Using seconds std::chrono increase time span to ~68 years.

Motivation and context

When updating a LE13 test installation after a few weeks no addon updates were shown. The log looked odd:

2025-02-01 18:02:08.178 T:842     debug <general>: CRepositoryUpdater: closest next update check at 2024-12-17 7:04:17 (in 281096 s)
2025-02-01 18:02:08.178 T:842     debug <general>: CRepositoryUpdater: checking in 281096296 ms

How has this been tested?

PR included in LE13 build successfully tested on previous failing Addon33.db

What is the effect on users?

Working addon updates.

Screenshots (if appropriate):

Types of change

  • Bug fix (non-breaking change which fixes an issue)
  • Clean up (non-breaking change which removes non-working, unmaintained functionality)
  • Improvement (non-breaking change which improves existing functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that will cause existing functionality to change)
  • Cosmetic change (non-breaking change that doesn't touch code)
  • Student submission (PR was done for educational purposes and will be treated as such)
  • None of the above (please explain below)

Checklist:

  • My code follows the Code Guidelines of this project
  • My change requires a change to the documentation, either Doxygen or wiki
  • I have updated the documentation accordingly
  • I have read the Contributing document
  • I have added tests to cover my change
  • All new and existing tests passed

@neo1973
Copy link
Member

neo1973 commented Mar 15, 2025

The proposed change should work, but how about a solution using std::chrono?

diff
diff --git a/xbmc/addons/RepositoryUpdater.cpp b/xbmc/addons/RepositoryUpdater.cpp
index c8c1dcbcc32..cd4a7e6b224 100644
--- a/xbmc/addons/RepositoryUpdater.cpp
+++ b/xbmc/addons/RepositoryUpdater.cpp
@@ -313,6 +313,8 @@ CDateTime CRepositoryUpdater::ClosestNextCheck() const
 
 void CRepositoryUpdater::ScheduleUpdate(UpdateScheduleType scheduleType)
 {
+  using namespace std::chrono;
+
   std::unique_lock<CCriticalSection> lock(m_criticalSection);
   m_timer.Stop(true);
 
@@ -322,14 +324,16 @@ void CRepositoryUpdater::ScheduleUpdate(UpdateScheduleType scheduleType)
   if (!m_addonMgr.HasAddons(AddonType::REPOSITORY))
     return;
 
-  int delta{1};
+  milliseconds delta{1};
   const auto nextCheck = ClosestNextCheck();
   if (nextCheck.IsValid())
   {
-    // Repos were already checked once and we know when to check next
-    delta = std::max(1, (nextCheck - CDateTime::GetCurrentDateTime()).GetSecondsTotal() * 1000);
-    CLog::Log(LOGDEBUG, "CRepositoryUpdater: closest next update check at {} (in {} s)",
-              nextCheck.GetAsLocalizedDateTime(), delta / 1000);
+    // Repos were already checked once and we know when to check next.
+    // delta must be positive and not zero (m_timer.Start() ignores 0 wait time)
+    delta = std::max<milliseconds>(
+        delta, seconds((nextCheck - CDateTime::GetCurrentDateTime()).GetSecondsTotal()));
+    CLog::Log(LOGDEBUG, "CRepositoryUpdater: closest next update check at {} (in {})",
+              nextCheck.GetAsLocalizedDateTime(), duration_cast<seconds>(delta));
   }
 
   if (scheduleType == UpdateScheduleType::Regular)
@@ -337,17 +341,12 @@ void CRepositoryUpdater::ScheduleUpdate(UpdateScheduleType scheduleType)
     // Enforce minimum hold-off time of 1 hour between regular updates - this is especially
     // important to handle all sorts of failure cases (e.g., failure to update the add-on database)
     // that would otherwise lead to an immediate new update attempt and continuous hammering of the servers.
-    delta = std::max(1 * 60 * 60 * 1'000, delta);
-  }
-  else
-  {
-    // delta must be positive and not zero (m_timer.Start() ignores 0 wait time)
-    delta = std::max(1, delta);
+    delta = std::max<milliseconds>(hours(1), delta);
   }
 
-  CLog::Log(LOGDEBUG, "CRepositoryUpdater: checking in {} ms", delta);
+  CLog::Log(LOGDEBUG, "CRepositoryUpdater: checking in {}", delta);
 
-  if (!m_timer.Start(std::chrono::milliseconds(delta)))
+  if (!m_timer.Start(delta))
     CLog::Log(LOGERROR,"CRepositoryUpdater: failed to start timer");
 }
 }

Switching to std::chrono is one of our distance goals anyway so this should be future proof.

@chewitt chewitt added this to the Piers 22.0 Alpha 1 milestone Mar 15, 2025
@chewitt chewitt added Component: Add-ons v22 Piers Type: Fix non-breaking change which fixes an issue Backport: Done labels Mar 15, 2025
@mglae mglae force-pushed the piers_RepositoryUpdater_overflow branch from 010e72c to 94dc183 Compare March 16, 2025 10:56
@mglae
Copy link
Contributor Author

mglae commented Mar 16, 2025

The proposed change should work, but how about a solution using std::chrono?

Sure, when it does compile :)

Do you recommend updating the backport too?

Using (32 bit) int for ms calculation lead to (negative) overflow when more
than ~25 days ago. Use std::chrono increase time span
@mglae mglae force-pushed the piers_RepositoryUpdater_overflow branch from 94dc183 to d24da28 Compare March 16, 2025 17:14
Copy link
Member

@neo1973 neo1973 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good to me now 👍

Once merged please update the backport to match this PR.

Copy link
Member

@ksooo ksooo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@mglae
Copy link
Contributor Author

mglae commented Mar 16, 2025

Backport is updated.

@ksooo ksooo merged commit 2bceeb9 into xbmc:master Mar 17, 2025
2 checks passed
@mglae mglae deleted the piers_RepositoryUpdater_overflow branch March 17, 2025 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants