QAbstractSocket: fix writing to socket in HostLookup state

After calling connectToHost(), the socket enters HostLookup state. At this
stage, the socket engine was not created yet, and writing to the socket
should result in either data buffering or an error. So, add a check for
d->socketEngine to prevent a crash on unbuffered sockets.

Task-number: QTBUG-48356
Change-Id: I15ea9ce7de97ce6d7e13e358eca5350745b556bb
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Richard J. Moore <rich@kde.org>
This commit is contained in:
Alex Trotsenko 2015-10-10 19:49:41 +03:00
parent a2f6ece27f
commit 0872156559
2 changed files with 18 additions and 4 deletions

View File

@ -2456,13 +2456,15 @@ qint64 QAbstractSocket::readLineData(char *data, qint64 maxlen)
qint64 QAbstractSocket::writeData(const char *data, qint64 size)
{
Q_D(QAbstractSocket);
if (d->state == QAbstractSocket::UnconnectedState) {
if (d->state == QAbstractSocket::UnconnectedState
|| (!d->socketEngine && d->socketType != TcpSocket && !d->isBuffered)) {
d->socketError = QAbstractSocket::UnknownSocketError;
setErrorString(tr("Socket is not connected"));
return -1;
}
if (!d->isBuffered && d->socketType == TcpSocket && d->writeBuffer.isEmpty()) {
if (!d->isBuffered && d->socketType == TcpSocket
&& d->socketEngine && d->writeBuffer.isEmpty()) {
// This code is for the new Unbuffered QTcpSocket use case
qint64 written = d->socketEngine->write(data, size);
if (written < 0) {
@ -2473,8 +2475,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
// Buffer what was not written yet
char *ptr = d->writeBuffer.reserve(size - written);
memcpy(ptr, data + written, size - written);
if (d->socketEngine)
d->socketEngine->setWriteNotificationEnabled(true);
d->socketEngine->setWriteNotificationEnabled(true);
}
return size; // size=actually written + what has been buffered
} else if (!d->isBuffered && d->socketType != TcpSocket) {

View File

@ -117,6 +117,7 @@ private slots:
void readyRead();
void readyReadForEmptyDatagram();
void asyncReadDatagram();
void writeInHostLookupState();
protected slots:
void empty_readyReadSlot();
@ -1725,5 +1726,17 @@ void tst_QUdpSocket::asyncReadDatagram()
delete m_asyncReceiver;
}
void tst_QUdpSocket::writeInHostLookupState()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
QUdpSocket socket;
socket.connectToHost("nosuchserver.qt-project.org", 80);
QCOMPARE(socket.state(), QUdpSocket::HostLookupState);
QVERIFY(!socket.putChar('0'));
}
QTEST_MAIN(tst_QUdpSocket)
#include "tst_qudpsocket.moc"