From cd862242358f1c5456c8c305c6b225fe9770ebb2 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Tue, 4 Nov 2008 00:31:32 +0100 Subject: [PATCH] Fixing BR #387 - core session sometimes hangs --- src/common/signalproxy.cpp | 39 +++++++++++++++++++++++++++----------- src/common/signalproxy.h | 2 ++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index 4308d8a8..82db1abf 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -1055,28 +1055,33 @@ bool SignalProxy::readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVarian } if(blockSize > 1 << 22) { - qWarning() << qPrintable(tr("Client tried to send package larger than max package size!")); - QAbstractSocket *sock = qobject_cast(dev); - qWarning() << qPrintable(tr("Disconnecting")) << (sock ? qPrintable(sock->peerAddress().toString()) : qPrintable(tr("local client"))); - dev->close(); + disconnectDevice(dev, tr("Client tried to send package larger than max package size!")); + return false; + } + + if(blockSize == 0) { + disconnectDevice(dev, tr("Client tried to send 0 byte package!")); return false; } if(dev->bytesAvailable() < blockSize) return false; + blockSize = 0; + if(compressed) { QByteArray rawItem; in >> rawItem; - // debug check + int nbytes = rawItem.size(); - if (nbytes <= 4) { + if(nbytes <= 4) { const char *data = rawItem.constData(); - if (nbytes < 4 || (data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0)) - qWarning() << "receieved corrupted compressed data:" - << blockSize << rawItem << rawItem.size() << dev; + if(nbytes < 4 || (data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0)) { + disconnectDevice(dev, tr("Client sent corrupted compressed data!")); + return false; + } } - // end + rawItem = qUncompress(rawItem); QDataStream itemStream(&rawItem, QIODevice::ReadOnly); @@ -1086,7 +1091,10 @@ bool SignalProxy::readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVarian in >> item; } - blockSize = 0; + if(!item.isValid()) { + disconnectDevice(dev, tr("Client sent corrupt data: unable to load QVariant!")); + return false; + } return true; } @@ -1205,6 +1213,15 @@ void SignalProxy::customEvent(QEvent *event) { } } +void SignalProxy::disconnectDevice(QIODevice *dev, const QString &reason) { + if(!reason.isEmpty()) + qWarning() << qPrintable(reason); + QAbstractSocket *sock = qobject_cast(dev); + if(sock) + qWarning() << qPrintable(tr("Disconnecting")) << qPrintable(sock->peerAddress().toString()); + dev->close(); +} + void SignalProxy::updateLag(IODevicePeer *peer, int lag) { peer->lag = lag; if(proxyMode() == Client) { diff --git a/src/common/signalproxy.h b/src/common/signalproxy.h index e6288977..76ed4d54 100644 --- a/src/common/signalproxy.h +++ b/src/common/signalproxy.h @@ -185,6 +185,8 @@ public: inline int peerCount() const { return _peers.size(); } private: + static void disconnectDevice(QIODevice *dev, const QString &reason = QString()); + class AbstractPeer { public: enum PeerType { -- 2.20.1