Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libqxmpp for openSUSE:Factory 
checked in at 2026-03-06 18:20:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libqxmpp (Old)
 and      /work/SRC/openSUSE:Factory/.libqxmpp.new.561 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libqxmpp"

Fri Mar  6 18:20:35 2026 rev:45 rq:1337286 version:1.14.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/libqxmpp/libqxmpp.changes        2026-02-12 
17:30:41.175735319 +0100
+++ /work/SRC/openSUSE:Factory/.libqxmpp.new.561/libqxmpp.changes       
2026-03-06 18:21:29.999391527 +0100
@@ -1,0 +2,9 @@
+Fri Mar  6 08:37:57 UTC 2026 - Christophe Marin <[email protected]>
+
+- Update to 1.14.3
+  * JMI: Fix JMI objects not being removed
+  * OmemoManager: Abort building session without public pre keys
+  * OutgoingIqManager: Fix potential double-finish of IQ promises
+  * JMI: Fix regressions introduced by auto-removal of closed JMIs
+
+-------------------------------------------------------------------

Old:
----
  qxmpp-1.14.1.tar.xz
  qxmpp-1.14.1.tar.xz.sig

New:
----
  _constraints
  qxmpp-1.14.3.tar.xz
  qxmpp-1.14.3.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libqxmpp.spec ++++++
--- /var/tmp/diff_new_pack.bDVK1Y/_old  2026-03-06 18:21:31.043435100 +0100
+++ /var/tmp/diff_new_pack.bDVK1Y/_new  2026-03-06 18:21:31.047435267 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package libqxmpp
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %define sover 8
 Name:           libqxmpp
-Version:        1.14.1
+Version:        1.14.3
 Release:        0
 Summary:        Qt XMPP Library
 License:        LGPL-2.1-or-later

++++++ _constraints ++++++
<?xml version="1.0" encoding="UTF-8"?>
<constraints>
  <hardware>
    <disk>
      <size unit="G">8</size>
    </disk>
  </hardware>
  <overwrite>
    <conditions>
      <arch>ppc64le</arch>
      <arch>riscv64</arch>
    </conditions>
    <hardware>
      <memory>
        <size unit="G">6</size>
      </memory>
    </hardware>
  </overwrite>
</constraints>

++++++ qxmpp-1.14.1.tar.xz -> qxmpp-1.14.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qxmpp-1.14.1/CHANGELOG.md 
new/qxmpp-1.14.3/CHANGELOG.md
--- old/qxmpp-1.14.1/CHANGELOG.md       2026-02-10 13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/CHANGELOG.md       2026-02-26 04:52:39.000000000 +0100
@@ -4,6 +4,18 @@
 SPDX-License-Identifier: CC0-1.0
 -->
 
+QXmpp 1.14.3 (February 26, 2026)
+--------------------------------
+
+ - JMI: Fix regressions introduced by auto-removal of closed JMIs (@lnj, !747)
+ - OutgoingIqManager: Fix potential double-finish of IQ promises (@lnj, !748)
+
+QXmpp 1.14.2 (February 21, 2026)
+--------------------------------
+
+ - OmemoManager: Abort building session without public pre keys (@melvo, !742)
+ - JMI: Fix JMI objects not being removed (@melvo, !737)
+
 QXmpp 1.14.1 (February 10, 2026)
 --------------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qxmpp-1.14.1/CMakeLists.txt 
new/qxmpp-1.14.3/CMakeLists.txt
--- old/qxmpp-1.14.1/CMakeLists.txt     2026-02-10 13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/CMakeLists.txt     2026-02-26 04:52:39.000000000 +0100
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: CC0-1.0
 
 cmake_minimum_required(VERSION 3.16)
-project(qxmpp VERSION 1.14.1)
+project(qxmpp VERSION 1.14.3)
 
 set(SO_VERSION 8)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qxmpp-1.14.1/doc/doap.xml 
new/qxmpp-1.14.3/doc/doap.xml
--- old/qxmpp-1.14.1/doc/doap.xml       2026-02-10 13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/doc/doap.xml       2026-02-26 04:52:39.000000000 +0100
@@ -783,6 +783,20 @@
     </implements>
     <release>
       <Version>
+        <revision>1.14.3</revision>
+        <created>2026-02-26</created>
+        <file-release 
rdf:resource='https://download.kde.org/unstable/qxmpp/qxmpp-1.14.3.tar.xz'/>
+      </Version>
+    </release>
+    <release>
+      <Version>
+        <revision>1.14.2</revision>
+        <created>2026-02-21</created>
+        <file-release 
rdf:resource='https://download.kde.org/unstable/qxmpp/qxmpp-1.14.2.tar.xz'/>
+      </Version>
+    </release>
+    <release>
+      <Version>
         <revision>1.14.1</revision>
         <created>2026-02-10</created>
         <file-release 
rdf:resource='https://download.kde.org/unstable/qxmpp/qxmpp-1.14.1.tar.xz'/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qxmpp-1.14.1/src/client/QXmppJingleMessageInitiationManager.cpp 
new/qxmpp-1.14.3/src/client/QXmppJingleMessageInitiationManager.cpp
--- old/qxmpp-1.14.1/src/client/QXmppJingleMessageInitiationManager.cpp 
2026-02-10 13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/src/client/QXmppJingleMessageInitiationManager.cpp 
2026-02-26 04:52:39.000000000 +0100
@@ -97,6 +97,8 @@
 ///
 QXmppTask<SendResult> 
QXmppJingleMessageInitiation::reject(std::optional<QXmppJingleReason> reason, 
bool containsTieBreak)
 {
+    QXmppPromise<SendResult> promise;
+
     JmiElement jmiElement;
     jmiElement.setType(JmiType::Reject);
 
@@ -109,7 +111,20 @@
     jmiElement.setReason(reason);
     jmiElement.setContainsTieBreak(containsTieBreak);
 
-    return d->request(std::move(jmiElement));
+    d->request(std::move(jmiElement)).then(this, [this, promise, 
containsTieBreak](SendResult &&result) mutable {
+        // Tie-break rejections don't close the local session; only emit 
closed() for real rejections.
+        if (!containsTieBreak) {
+            if (hasError(result)) {
+                Q_EMIT closed(getError(result));
+            } else {
+                Q_EMIT closed(Rejected {});
+            }
+        }
+
+        promise.finish(std::move(result));
+    });
+
+    return promise.task();
 }
 
 ///
@@ -121,6 +136,8 @@
 ///
 QXmppTask<SendResult> 
QXmppJingleMessageInitiation::retract(std::optional<QXmppJingleReason> reason, 
bool containsTieBreak)
 {
+    QXmppPromise<SendResult> promise;
+
     JmiElement jmiElement;
     jmiElement.setType(JmiType::Retract);
 
@@ -133,7 +150,20 @@
     jmiElement.setReason(reason);
     jmiElement.setContainsTieBreak(containsTieBreak);
 
-    return d->request(std::move(jmiElement));
+    d->request(std::move(jmiElement)).then(this, [this, promise, 
containsTieBreak](SendResult &&result) mutable {
+        // Tie-break retractions don't close the local session; only emit 
closed() for real retractions.
+        if (!containsTieBreak) {
+            if (hasError(result)) {
+                Q_EMIT closed(getError(result));
+            } else {
+                Q_EMIT closed(Retracted {});
+            }
+        }
+
+        promise.finish(std::move(result));
+    });
+
+    return promise.task();
 }
 
 ///
@@ -145,6 +175,8 @@
 ///
 QXmppTask<SendResult> 
QXmppJingleMessageInitiation::finish(std::optional<QXmppJingleReason> reason, 
const QString &migratedTo)
 {
+    QXmppPromise<SendResult> promise;
+
     d->finished = true;
 
     JmiElement jmiElement;
@@ -159,7 +191,17 @@
     jmiElement.setReason(reason);
     jmiElement.setMigratedTo(migratedTo);
 
-    return d->request(std::move(jmiElement));
+    d->request(std::move(jmiElement)).then(this, [this, promise](SendResult 
&&result) mutable {
+        if (hasError(result)) {
+            Q_EMIT closed(getError(result));
+        } else {
+            Q_EMIT closed(Finished {});
+        }
+
+        promise.finish(std::move(result));
+    });
+
+    return promise.task();
 }
 
 ///
@@ -437,7 +479,6 @@
         return true;
     case JmiType::Finish:
         if (!existingJmi->isFinished()) {
-            existingJmi->finish(jmiElement.reason(), jmiElement.migratedTo());
             Q_EMIT existingJmi->closed(
                 Jmi::Finished { jmiElement.reason(), jmiElement.migratedTo() 
});
         }
@@ -551,18 +592,13 @@
 
     if (QUuid::fromString(existingJmi->id()) < 
QUuid::fromString(jmiElementId)) {
         // Jingle message initiator with lower ID rejects the other proposal.
+        // The local session is not closed; the JMI remains active.
         existingJmi->setId(jmiElementId);
-        existingJmi->reject(std::move(reason), true).then(this, 
[existingJmi](auto result) {
-            if (hasError(result)) {
-                Q_EMIT existingJmi->closed(getError(std::move(result)));
-            }
-        });
+        existingJmi->reject(std::move(reason), true).then(this, [](auto) { });
     } else {
         // Jingle message initiator with higher ID retracts its proposal.
         existingJmi->retract(std::move(reason), true).then(this, [this, 
existingJmi, jmiElementId, remoteResource](auto result) {
-            if (hasError(result)) {
-                Q_EMIT existingJmi->closed(getError(std::move(result)));
-            } else {
+            if (!hasError(result)) {
                 // Afterwards, JMI ID is changed to lower ID.
                 existingJmi->setId(jmiElementId);
 
@@ -590,6 +626,23 @@
 std::shared_ptr<QXmppJingleMessageInitiation> 
QXmppJingleMessageInitiationManager::addJmi(const QString &id, const QString 
&remoteJid)
 {
     auto jmi = std::shared_ptr<QXmppJingleMessageInitiation>(new 
QXmppJingleMessageInitiation(this, id, remoteJid));
+
+    connect(jmi.get(), &QXmppJingleMessageInitiation::closed, this, [this, 
jmi](const QXmppJingleMessageInitiation::Result &result) {
+        // Don't remove the JMI on tie-break rejection/retraction since the 
local session persists.
+        if (const auto *rejected = 
std::get_if<QXmppJingleMessageInitiation::Rejected>(&result)) {
+            if (rejected->containsTieBreak) {
+                return;
+            }
+        }
+        if (const auto *retracted = 
std::get_if<QXmppJingleMessageInitiation::Retracted>(&result)) {
+            if (retracted->containsTieBreak) {
+                return;
+            }
+        }
+        debug(u"JMI with ID '%1' for remote JID '%2' is closed and thus being 
removed"_s.arg(jmi->id(), jmi->remoteJid()));
+        clear(jmi);
+    });
+
     d->jmis.append(jmi);
     return jmi;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qxmpp-1.14.1/src/client/QXmppOutgoingClient.cpp 
new/qxmpp-1.14.3/src/client/QXmppOutgoingClient.cpp
--- old/qxmpp-1.14.1/src/client/QXmppOutgoingClient.cpp 2026-02-10 
13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/src/client/QXmppOutgoingClient.cpp 2026-02-26 
04:52:39.000000000 +0100
@@ -1219,19 +1219,21 @@
 void OutgoingIqManager::finish(const QString &id, IqResult &&result)
 {
     if (auto itr = m_requests.find(id); itr != m_requests.end()) {
-        itr->second.interface.finish(std::move(result));
+        auto promise = std::move(itr->second.interface);
         m_requests.erase(itr);
+        promise.finish(std::move(result));
     }
 }
 
 void OutgoingIqManager::cancelAll()
 {
-    for (auto &[id, state] : m_requests) {
+    auto requests = std::move(m_requests);
+    m_requests = {};
+    for (auto &[id, state] : requests) {
         state.interface.finish(QXmppError {
             u"IQ has been cancelled."_s,
             QXmpp::SendError::Disconnected });
     }
-    m_requests.clear();
 }
 
 void OutgoingIqManager::onSessionOpened(const SessionBegin &session)
@@ -1268,20 +1270,22 @@
         return false;
     }
 
-    auto &promise = itr->second.interface;
-    const auto &expectedFrom = itr->second.jid;
-
     // Check that the sender of the response matches the recipient of the 
request.
     // Stanzas coming from the server on behalf of the user's account must 
have no "from"
     // attribute or have it set to the user's bare JID.
     // If 'from' is empty, the IQ has been sent by the server. In this case we 
don't need to
     // do the check as we trust the server anyways.
-    if (auto from = stanza.attribute(u"from"_s); !from.isEmpty() && from != 
expectedFrom) {
+    if (auto from = stanza.attribute(u"from"_s); !from.isEmpty() && from != 
itr->second.jid) {
         warning(u"Ignored received IQ response to request '%1' because of 
wrong sender '%2' instead of expected sender '%3'"_s
-                    .arg(id, from, expectedFrom));
+                    .arg(id, from, itr->second.jid));
         return false;
     }
 
+    // Extract the promise and erase from the map before calling finish() to 
prevent
+    // re-entrant double-finish if a continuation triggers cancelAll().
+    auto promise = std::move(itr->second.interface);
+    m_requests.erase(itr);
+
     // report IQ errors as QXmppError (this makes it impossible to parse the 
full error IQ,
     // but that is okay for now)
     if (iqType == u"error") {
@@ -1300,7 +1304,6 @@
         promise.finish(stanza);
     }
 
-    m_requests.erase(itr);
     return true;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qxmpp-1.14.1/src/omemo/QXmppOmemoManager_p.cpp 
new/qxmpp-1.14.3/src/omemo/QXmppOmemoManager_p.cpp
--- old/qxmpp-1.14.1/src/omemo/QXmppOmemoManager_p.cpp  2026-02-10 
13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/src/omemo/QXmppOmemoManager_p.cpp  2026-02-26 
04:52:39.000000000 +0100
@@ -3319,12 +3319,11 @@
 //
 bool ManagerPrivate::buildSession(signal_protocol_address address, const 
QXmppOmemoDeviceBundle &deviceBundle)
 {
-    QXmppPromise<bool> interface;
-
     // Choose a pre key randomly.
     const auto publicPreKeys = deviceBundle.publicPreKeys();
     if (publicPreKeys.isEmpty()) {
         warning(u"No public pre key could be found in device bundle"_s);
+        return false;
     }
     const auto publicPreKeyIds = publicPreKeys.keys();
     const auto publicPreKeyIndex = 
QRandomGenerator::system()->bounded(publicPreKeyIds.size());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qxmpp-1.14.1/tests/qxmppcallmanager/tst_qxmppcallmanager.cpp 
new/qxmpp-1.14.3/tests/qxmppcallmanager/tst_qxmppcallmanager.cpp
--- old/qxmpp-1.14.1/tests/qxmppcallmanager/tst_qxmppcallmanager.cpp    
2026-02-10 13:49:31.000000000 +0100
+++ new/qxmpp-1.14.3/tests/qxmppcallmanager/tst_qxmppcallmanager.cpp    
2026-02-26 04:52:39.000000000 +0100
@@ -80,7 +80,7 @@
     QCoreApplication::processEvents();
     client.expect(u"<iq id='ph37a419' to='[email protected]/orchard' 
type='result'/>"_s);
     client.expect(u"<iq id=\"qx3\" to=\"capulet.lit\" type=\"get\"><services 
xmlns=\"urn:xmpp:extdisco:2\"/></iq>"_s);
-    client.inject(u"<iq id='qx3' from='capulet.lit' type='result'><services 
xmlns='urn:xmpp:extdisco:2'/></iq>");
+    client.inject(u"<iq id='qx3' from='capulet.lit' type='result'><services 
xmlns='urn:xmpp:extdisco:2'/></iq>"_s);
     QCoreApplication::processEvents();
     client.expect(u"<iq id=\"qx2\" to=\"[email protected]/orchard\" 
from=\"[email protected]/balcony\" type=\"set\"><jingle 
xmlns=\"urn:xmpp:jingle:1\" action=\"session-info\" sid=\"abc1\"><ringing 
xmlns=\"urn:xmpp:jingle:apps:rtp:info:1\"/></jingle></iq>"_s);
 

Reply via email to