From 80142ae63d4639f38f3ab491bde47e886d9c0ea8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Tue, 27 Feb 2024 14:38:43 -0500
Subject: [PATCH] conversation_module: avoid infinite loop on bad sync

If no commit is fetch, no need to forward the message

Change-Id: I1311a15d8ab81cd0b84ecce6a81a9398c239d938
---
 src/jamidht/conversation.cpp        | 17 +++++++++++++----
 src/jamidht/conversation.h          |  3 ++-
 src/jamidht/conversation_module.cpp |  2 +-
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/jamidht/conversation.cpp b/src/jamidht/conversation.cpp
index 3c5bf49484..392994c2f3 100644
--- a/src/jamidht/conversation.cpp
+++ b/src/jamidht/conversation.cpp
@@ -1637,18 +1637,27 @@ Conversation::Impl::mergeHistory(const std::string& uri)
     return result;
 }
 
-void
+bool
 Conversation::pull(const std::string& deviceId, OnPullCb&& cb, std::string commitId)
 {
     std::lock_guard lk(pimpl_->pullcbsMtx_);
     auto isInProgress = not pimpl_->pullcbs_.empty();
+    auto itPull = std::find_if(pimpl_->pullcbs_.begin(),
+                               pimpl_->pullcbs_.end(),
+                               [&](const auto& elem) { return std::get<0>(elem) == deviceId && std::get<1>(elem) == commitId; });
+    if (itPull != pimpl_->pullcbs_.end()) {
+        cb(false);
+        return false;
+    }
+    JAMI_INFO() << "Sync " << id() << " with " << deviceId;
     pimpl_->pullcbs_.emplace_back(deviceId, std::move(commitId), std::move(cb));
     if (isInProgress)
-        return;
+        return true;
     dht::ThreadPool::io().run([w = weak()] {
         if (auto sthis_ = w.lock())
             sthis_->pimpl_->pull();
     });
+    return true;
 }
 
 void
@@ -1747,8 +1756,8 @@ Conversation::sync(const std::string& member,
                    OnPullCb&& cb,
                    std::string commitId)
 {
-    JAMI_INFO() << "Sync " << id() << " with " << deviceId;
-    pull(deviceId, std::move(cb), commitId);
+    if (!pull(deviceId, std::move(cb), commitId))
+        return;
     dht::ThreadPool::io().run([member, deviceId, a = pimpl_->account_, w = weak_from_this()] {
         auto sthis = w.lock();
         if (auto account = a.lock()) {
diff --git a/src/jamidht/conversation.h b/src/jamidht/conversation.h
index 1201562157..71621ab4e6 100644
--- a/src/jamidht/conversation.h
+++ b/src/jamidht/conversation.h
@@ -319,8 +319,9 @@ public:
      * @param deviceId  Peer device
      * @param cb        On pulled callback
      * @param commitId  Commit id that triggered this fetch
+     * @return true if callback will be called later
      */
-    void pull(const std::string& deviceId, OnPullCb&& cb, std::string commitId = "");
+    bool pull(const std::string& deviceId, OnPullCb&& cb, std::string commitId = "");
     /**
      * Fetch new commits and re-ask for waiting files
      * @param member
diff --git a/src/jamidht/conversation_module.cpp b/src/jamidht/conversation_module.cpp
index 4fb230ce1f..ad01a00222 100644
--- a/src/jamidht/conversation_module.cpp
+++ b/src/jamidht/conversation_module.cpp
@@ -608,7 +608,7 @@ ConversationModule::Impl::fetchNewCommits(const std::string& peer,
                             std::lock_guard lk(conv->mtx);
                             conv->pending.reset();
                             // Notify peers that a new commit is there (DRT)
-                            if (not commitId.empty()) {
+                            if (not commitId.empty() && ok) {
                                 shared->sendMessageNotification(*conv->conversation,
                                                                 false,
                                                                 commitId,
-- 
GitLab