Skip to content
Permalink
Browse files Browse the repository at this point in the history
Don't brute-force reading the socket
The package will arrive eventually, and dataReceived will be emitted.
Otherwise we just end up calling dataReceived to no end.

Thanks Matthias Gerstner <mgerstner@suse.de> for reporting this.
  • Loading branch information
aleixpol authored and albertvaka committed Oct 2, 2020
1 parent 024e5f2 commit 8112729
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
8 changes: 0 additions & 8 deletions core/backends/lan/socketlinereader.cpp
Expand Up @@ -24,14 +24,6 @@ void SocketLineReader::dataReceived()
}
}

//If we still have things to read from the socket, call dataReceived again
//We do this manually because we do not trust readyRead to be emitted again
//So we call this method again just in case.
if (m_socket->bytesAvailable() > 0) {
QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection);
return;
}

//If we have any packets, tell it to the world.
if (!m_packets.isEmpty()) {
Q_EMIT readyRead();
Expand Down
31 changes: 29 additions & 2 deletions tests/testsocketlinereader.cpp
Expand Up @@ -13,16 +13,19 @@
#include <QProcess>
#include <QEventLoop>
#include <QTimer>
#include <QSignalSpy>

class TestSocketLineReader : public QObject
{
Q_OBJECT
public Q_SLOTS:
void initTestCase();
void init();
void cleanup() { delete m_server; }
void newPacket();

private Q_SLOTS:
void socketLineReader();
void badData();

private:
QTimer m_timer;
Expand All @@ -33,8 +36,9 @@ private Q_SLOTS:
SocketLineReader* m_reader;
};

void TestSocketLineReader::initTestCase()
void TestSocketLineReader::init()
{
m_packets.clear();
m_server = new Server(this);

QVERIFY2(m_server->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server");
Expand Down Expand Up @@ -85,6 +89,29 @@ void TestSocketLineReader::socketLineReader()
}
}

void TestSocketLineReader::badData()
{
const QList<QByteArray> dataToSend = { "data1\n", "data" }; //does not end in a \n
for (const QByteArray& line : qAsConst(dataToSend)) {
m_conn->write(line);
}
m_conn->flush();

QSignalSpy spy(m_server, &QTcpServer::newConnection);
QVERIFY(m_server->hasPendingConnections() || spy.wait(1000));
QSslSocket* sock = m_server->nextPendingConnection();

QVERIFY2(sock != nullptr, "Could not open a connection to the client");

m_reader = new SocketLineReader(sock, this);
connect(m_reader, &SocketLineReader::readyRead, this, &TestSocketLineReader::newPacket);
m_timer.start();
m_loop.exec();

QCOMPARE(m_packets.count(), 1);
QCOMPARE(m_packets[0], dataToSend[0]);
}

void TestSocketLineReader::newPacket()
{
int maxLoops = 5;
Expand Down

0 comments on commit 8112729

Please sign in to comment.