diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a15f0558..0632fe75e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,20 @@ QXmpp 1.6.0 (UNRELEASED)
*under development*
+QXmpp 1.5.6 (Feb 4, 2024)
+-------------------------
+
+Changes:
+ - Behaviour change: sendIq() automatically parses stanza errors (returned as QXmppError) (@lnjX)
+ - CMake: "QXmpp" legacy cmake package is now only installed for Qt 5 builds (@lnjX)
+ - Fix unit test with Qt 6! (@lnjX)
+ - EncryptedFileSharingProvider: Fix wrong cipher set in sent file share element (@lnjX)
+ - Fix SCE parsing mode when parsing encrypted messages (@lnjX)
+ - Fix file encryption with QCA issues (@lnjX)
+ - Fix picking by strength of hashing algorithms (@lnjX)
+ - Fix github ci (@lnjX)
+ - Add unit tests for all file encryption ciphers (@lnjX)
+
QXmpp 1.5.5 (Apr 30, 2023)
--------------------------
diff --git a/src/base/QXmppFutureUtils_p.h b/src/base/QXmppFutureUtils_p.h
index 951500089..818b04372 100644
--- a/src/base/QXmppFutureUtils_p.h
+++ b/src/base/QXmppFutureUtils_p.h
@@ -157,12 +157,6 @@ auto parseIq(Input &&sendResult, Converter convert) -> decltype(convert({}))
[convert = std::move(convert)](const QDomElement &element) -> Result {
IqType iq;
iq.parse(element);
- if (iq.type() == QXmppIq::Error) {
- if (auto err = iq.errorOptional()) {
- return QXmppError { err->text(), std::move(*err) };
- }
- return QXmppError { QStringLiteral("Unknown error.") };
- }
return convert(std::move(iq));
},
[](QXmppError error) -> Result {
diff --git a/src/base/QXmppStream.cpp b/src/base/QXmppStream.cpp
index e82d4ca0f..0fc182a59 100644
--- a/src/base/QXmppStream.cpp
+++ b/src/base/QXmppStream.cpp
@@ -69,8 +69,8 @@ QXmppStreamPrivate::~QXmppStreamPrivate()
///
/// \typedef QXmppStream::IqResult
///
-/// Contains a QDomElement containing the IQ response or if the request couldn't
-/// be sent a QXmpp::PacketState.
+/// Contains a QDomElement if an IQ response of type 'result' has been received. In case of an
+/// error response of if an error occurred while sending the IQ request, a QXmppError is used.
///
/// \warning THIS API IS NOT FINALIZED YET!
///
@@ -488,7 +488,23 @@ bool QXmppStream::handleIqResponse(const QDomElement &stanza)
return false;
}
- itr.value().interface.finish(stanza);
+ // report IQ errors as QXmppError (this makes it impossible to parse the full error IQ,
+ // but that is okay for now)
+ if (iqType == QStringLiteral("error")) {
+ QXmppIq iq;
+ iq.parse(stanza);
+ if (auto err = iq.errorOptional()) {
+ // report stanza error
+ itr.value().interface.finish(QXmppError { err->text(), *err });
+ } else {
+ // this shouldn't happen (no element in IQ of type error)
+ using Err = QXmppStanza::Error;
+ itr.value().interface.finish(QXmppError { QStringLiteral("IQ error"), Err(Err::Cancel, Err::UndefinedCondition) });
+ }
+ } else {
+ // report stanza element for parsing
+ itr.value().interface.finish(stanza);
+ }
d->runningIqs.erase(itr);
return true;
diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp
index a80c595e1..a6aa320f2 100644
--- a/src/client/QXmppClient.cpp
+++ b/src/client/QXmppClient.cpp
@@ -171,9 +171,9 @@ bool process(QXmppClient *client, const QList &extension
///
/// \typedef QXmppClient::IqResult
///
-/// Result of an IQ request, either contains the QDomElement of the IQ answer
-/// (with type 'error' or 'result') or it contains the packet error, if the
-/// request couldn't be sent.
+/// Result of an IQ request, either contains the QDomElement of the IQ reponse (in case of an
+/// 'result' IQ type) or it contains an QXmppError with a QXmppStanza::Error (on type 'error') or
+/// a QXmpp::SendError.
///
/// \since QXmpp 1.5
///
@@ -516,6 +516,9 @@ QXmppTask QXmppClient::reply(QXmppStanza &&stanza, const std:
/// QDomElement. If you don't expect a special response, you may want use
/// sendGenericIq().
///
+/// IQs of type 'error' are parsed automatically and returned as QXmppError with a contained
+/// QXmppStanza::Error.
+///
/// This does not do any end-to-encryption on the IQ.
///
/// \sa sendSensitiveIq()
@@ -538,6 +541,9 @@ QXmppTask QXmppClient::sendIq(QXmppIq &&iq, const std::op
/// encrypted or it only makes little sense to do so. This is why the default
/// sendIq() does not do any additional end-to-end encryption.
///
+/// IQs of type 'error' are parsed automatically and returned as QXmppError with a contained
+/// QXmppStanza::Error.
+///
/// \warning THIS API IS NOT FINALIZED YET!
///
/// \since QXmpp 1.5