Skip to content

Commit 3f429da

Browse files
ckammguruz
authored andcommitted
SocketApi: Fix crash with readyRead() after disconnected() #7044
With the recent bugfix to avoid sending messages on dead connections 0bfe7ac the client now crashed if readyRead() was received after disconnected() for the socket as the listener for that connection was already removed. This code fixes it by still invoking the handler from readyRead() but passing a SocketListener that won't attempt to send messages.
1 parent 9ea3efd commit 3f429da

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

src/gui/socketapi.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,20 @@ class BloomFilter
118118
class SocketListener
119119
{
120120
public:
121-
QIODevice *socket;
121+
QPointer<QIODevice> socket;
122122

123-
SocketListener(QIODevice *socket = 0)
123+
explicit SocketListener(QIODevice *socket)
124124
: socket(socket)
125125
{
126126
}
127127

128128
void sendMessage(const QString &message, bool doWait = false) const
129129
{
130+
if (!socket) {
131+
qCInfo(lcSocketApi) << "Not sending message to dead socket:" << message;
132+
return;
133+
}
134+
130135
qCInfo(lcSocketApi) << "Sending SocketAPI message -->" << message << "to" << socket;
131136
QString localMessage = message;
132137
if (!localMessage.endsWith(QLatin1Char('\n'))) {
@@ -280,7 +285,19 @@ void SocketApi::slotReadSocket()
280285
{
281286
QIODevice *socket = qobject_cast<QIODevice *>(sender());
282287
ASSERT(socket);
283-
SocketListener *listener = &*std::find_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket));
288+
289+
// Find the SocketListener
290+
//
291+
// It's possible for the disconnected() signal to be triggered before
292+
// the readyRead() signals are received - in that case there won't be a
293+
// valid listener. We execute the handler anyway, but it will work with
294+
// a SocketListener that doesn't send any messages.
295+
static auto noListener = SocketListener(nullptr);
296+
SocketListener *listener = &noListener;
297+
auto listenerIt = std::find_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket));
298+
if (listenerIt != _listeners.end()) {
299+
listener = &*listenerIt;
300+
}
284301

285302
while (socket->canReadLine()) {
286303
// Make sure to normalize the input from the socket to

0 commit comments

Comments
 (0)