forked from qt-creator/qt-creator
LanguageClient: fix crash in call and type hierarchy
The response to a request sent by Call or TypeHierarchy was still handled by deleted Hierarchy instances. This happens when a second request was sent before the first was handled. Make sure to cancel a potentially running request when destructing a hierarchy in order to prevent accessing the deleted instance. Change-Id: Icd810f7a6e9eb090b28f13cb1a3254f75a27cdbb Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -287,6 +287,12 @@ public:
|
|||||||
theWidget, [this](const QModelIndex &index) { onItemDoubleClicked(index); });
|
theWidget, [this](const QModelIndex &index) { onItemDoubleClicked(index); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~HierarchyWidgetHelper()
|
||||||
|
{
|
||||||
|
if (m_runningRequest && m_runningRequest->first)
|
||||||
|
m_runningRequest->first->cancelRequest(m_runningRequest->second);
|
||||||
|
}
|
||||||
|
|
||||||
void updateHierarchyAtCursorPosition()
|
void updateHierarchyAtCursorPosition()
|
||||||
{
|
{
|
||||||
m_model.clear();
|
m_model.clear();
|
||||||
@@ -315,6 +321,17 @@ protected:
|
|||||||
item->forChildrenAtLevel(1, [&](const TreeItem *child) { m_view->expand(child->index()); });
|
item->forChildrenAtLevel(1, [&](const TreeItem *child) { m_view->expand(child->index()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send(Client *client, const JsonRpcMessage &request, const MessageId &requestId)
|
||||||
|
{
|
||||||
|
m_runningRequest = std::make_pair(QPointer<Client>(client), requestId);
|
||||||
|
client->sendMessage(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetRunningRequest()
|
||||||
|
{
|
||||||
|
m_runningRequest.reset();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void sendRequest(Client *client, const TextDocumentPositionParams ¶ms,
|
virtual void sendRequest(Client *client, const TextDocumentPositionParams ¶ms,
|
||||||
const Core::IDocument *document) = 0;
|
const Core::IDocument *document) = 0;
|
||||||
@@ -334,6 +351,7 @@ private:
|
|||||||
|
|
||||||
AnnotatedItemDelegate m_delegate;
|
AnnotatedItemDelegate m_delegate;
|
||||||
NavigationTreeView * const m_view;
|
NavigationTreeView * const m_view;
|
||||||
|
std::optional<std::pair<QPointer<Client>, MessageId>> m_runningRequest;
|
||||||
TreeModel<TreeItem> m_model;
|
TreeModel<TreeItem> m_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -358,12 +376,13 @@ private:
|
|||||||
const PrepareCallHierarchyRequest::Response &response) {
|
const PrepareCallHierarchyRequest::Response &response) {
|
||||||
handlePrepareResponse(client, response);
|
handlePrepareResponse(client, response);
|
||||||
});
|
});
|
||||||
client->sendMessage(request);
|
send(client, request, request.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePrepareResponse(Client *client,
|
void handlePrepareResponse(Client *client,
|
||||||
const PrepareCallHierarchyRequest::Response &response)
|
const PrepareCallHierarchyRequest::Response &response)
|
||||||
{
|
{
|
||||||
|
resetRunningRequest();
|
||||||
if (!client)
|
if (!client)
|
||||||
return;
|
return;
|
||||||
const std::optional<PrepareCallHierarchyRequest::Response::Error> error = response.error();
|
const std::optional<PrepareCallHierarchyRequest::Response::Error> error = response.error();
|
||||||
@@ -401,12 +420,13 @@ private:
|
|||||||
const PrepareTypeHierarchyRequest::Response &response) {
|
const PrepareTypeHierarchyRequest::Response &response) {
|
||||||
handlePrepareResponse(client, response);
|
handlePrepareResponse(client, response);
|
||||||
});
|
});
|
||||||
client->sendMessage(request);
|
send(client, request, request.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePrepareResponse(Client *client,
|
void handlePrepareResponse(Client *client,
|
||||||
const PrepareTypeHierarchyRequest::Response &response)
|
const PrepareTypeHierarchyRequest::Response &response)
|
||||||
{
|
{
|
||||||
|
resetRunningRequest();
|
||||||
if (!client)
|
if (!client)
|
||||||
return;
|
return;
|
||||||
const std::optional<PrepareTypeHierarchyRequest::Response::Error> error = response.error();
|
const std::optional<PrepareTypeHierarchyRequest::Response::Error> error = response.error();
|
||||||
|
Reference in New Issue
Block a user