aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2023-03-09 17:36:17 +0100
committerLinus Jahn <lnj@kaidan.im>2023-03-09 20:07:35 +0100
commit18353901a2215376e2f0274a408ce2213c180f16 (patch)
tree9fdc9e80206cdea8b35216bcd32ab769e5c97bfb
parent4df9803baf460b4779bcfdecda95708c5c96dab8 (diff)
SaslDigestMd5: Fix UB when at the end of input byte array [Qt6 only]
Also adds a unit test. Fixes #541.
-rw-r--r--src/base/QXmppSasl.cpp8
-rw-r--r--tests/qxmppsasl/tst_qxmppsasl.cpp10
2 files changed, 16 insertions, 2 deletions
diff --git a/src/base/QXmppSasl.cpp b/src/base/QXmppSasl.cpp
index d8a86bb0..86e67b01 100644
--- a/src/base/QXmppSasl.cpp
+++ b/src/base/QXmppSasl.cpp
@@ -896,8 +896,12 @@ QMap<QByteArray, QByteArray> QXmppSaslDigestMd5::parseMessage(const QByteArray &
const QByteArray key = ba.mid(startIndex, pos - startIndex).trimmed();
pos++;
- // check whether string is quoted
- if (ba.at(pos) == '"') {
+ if (pos == ba.size()) {
+ // end of the input
+ map.insert(key, QByteArray());
+ startIndex = pos;
+ } else if (ba.at(pos) == '"') {
+ // check whether string is quoted
// skip opening quote
pos++;
int endPos = ba.indexOf('"', pos);
diff --git a/tests/qxmppsasl/tst_qxmppsasl.cpp b/tests/qxmppsasl/tst_qxmppsasl.cpp
index 951af0b4..88dd5673 100644
--- a/tests/qxmppsasl/tst_qxmppsasl.cpp
+++ b/tests/qxmppsasl/tst_qxmppsasl.cpp
@@ -28,6 +28,7 @@ private:
Q_SLOT void testClientAnonymous();
Q_SLOT void testClientDigestMd5();
Q_SLOT void testClientDigestMd5_data();
+ Q_SLOT void testDigestMd5ParseMessage();
Q_SLOT void testClientFacebook();
Q_SLOT void testClientGoogle();
Q_SLOT void testClientPlain();
@@ -220,6 +221,15 @@ void tst_QXmppSasl::testClientDigestMd5_data()
QTest::newRow("qop-multi") << QByteArray(",qop=\"auth,auth-int\"");
}
+void tst_QXmppSasl::testDigestMd5ParseMessage()
+{
+ auto result = QXmppSaslDigestMd5::parseMessage("charset=utf-8,digest-uri=\"xmpp/0.0.0.0\",nc=00000001,qop=auth,realm=0.0.0.0,response=9c3ee0a919d714c9d72853ff51c0a4f3,username=");
+ QCOMPARE(result["username"], QByteArray());
+
+ result = QXmppSaslDigestMd5::parseMessage("nc=00000001,username=,qop=auth,realm=0.0.0.0,response=9c3ee0a919d714c9d72853ff51c0a4f3");
+ QCOMPARE(result["username"], QByteArray());
+}
+
void tst_QXmppSasl::testClientDigestMd5()
{
QFETCH(QByteArray, qop);