2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 14:45:14 +00:00

Fix possible crash in calls.

Fixes #5732.
This commit is contained in:
John Preston
2019-03-12 15:16:58 +04:00
parent 13a9b967e9
commit 383b29dbd8
4 changed files with 123 additions and 85 deletions

View File

@@ -106,10 +106,13 @@ void Instance::destroyCall(not_null<Call*> call) {
}
void Instance::destroyCurrentPanel() {
_pendingPanels.erase(std::remove_if(_pendingPanels.begin(), _pendingPanels.end(), [](auto &&panel) {
return !panel;
}), _pendingPanels.end());
_pendingPanels.push_back(_currentCallPanel.release());
_pendingPanels.erase(
std::remove_if(
_pendingPanels.begin(),
_pendingPanels.end(),
[](auto &&panel) { return !panel; }),
_pendingPanels.end());
_pendingPanels.emplace_back(_currentCallPanel.release());
_pendingPanels.back()->hideAndDestroy(); // Always queues the destruction.
}
@@ -130,56 +133,65 @@ void Instance::createCall(not_null<UserData*> user, Call::Type type) {
void Instance::refreshDhConfig() {
Expects(_currentCall != nullptr);
const auto weak = base::make_weak(_currentCall);
request(MTPmessages_GetDhConfig(
MTP_int(_dhConfig.version),
MTP_int(MTP::ModExpFirst::kRandomPowerSize)
)).done([this, call = base::make_weak(_currentCall)](
const MTPmessages_DhConfig &result) {
auto random = bytes::const_span();
switch (result.type()) {
case mtpc_messages_dhConfig: {
auto &config = result.c_messages_dhConfig();
if (!MTP::IsPrimeAndGood(bytes::make_span(config.vp.v), config.vg.v)) {
LOG(("API Error: bad p/g received in dhConfig."));
callFailed(call.get());
return;
}
_dhConfig.g = config.vg.v;
_dhConfig.p = bytes::make_vector(config.vp.v);
random = bytes::make_span(config.vrandom.v);
} break;
case mtpc_messages_dhConfigNotModified: {
auto &config = result.c_messages_dhConfigNotModified();
random = bytes::make_span(config.vrandom.v);
if (!_dhConfig.g || _dhConfig.p.empty()) {
LOG(("API Error: dhConfigNotModified on zero version."));
callFailed(call.get());
return;
}
} break;
default: Unexpected("Type in messages.getDhConfig");
}
if (random.size() != MTP::ModExpFirst::kRandomPowerSize) {
LOG(("API Error: dhConfig random bytes wrong size: %1").arg(random.size()));
callFailed(call.get());
return;
}
if (call) {
call->start(random);
}
}).fail([this, call = base::make_weak(_currentCall)](
const RPCError &error) {
)).done([=](const MTPmessages_DhConfig &result) {
const auto call = weak.get();
const auto random = updateDhConfig(result);
if (!call) {
DEBUG_LOG(("API Warning: call was destroyed before got dhConfig."));
return;
}
callFailed(call.get());
if (!random.empty()) {
Assert(random.size() == MTP::ModExpFirst::kRandomPowerSize);
call->start(random);
} else {
callFailed(call);
}
}).fail([=](const RPCError &error) {
const auto call = weak.get();
if (!call) {
return;
}
callFailed(call);
}).send();
}
bytes::const_span Instance::updateDhConfig(
const MTPmessages_DhConfig &data) {
const auto validRandom = [](const QByteArray & random) {
if (random.size() != MTP::ModExpFirst::kRandomPowerSize) {
return false;
}
return true;
};
return data.match([&](const MTPDmessages_dhConfig &data)
-> bytes::const_span {
auto primeBytes = bytes::make_vector(data.vp.v);
if (!MTP::IsPrimeAndGood(primeBytes, data.vg.v)) {
LOG(("API Error: bad p/g received in dhConfig."));
return {};
} else if (!validRandom(data.vrandom.v)) {
return {};
}
_dhConfig.g = data.vg.v;
_dhConfig.p = std::move(primeBytes);
_dhConfig.version = data.vversion.v;
return bytes::make_span(data.vrandom.v);
}, [&](const MTPDmessages_dhConfigNotModified &data)
-> bytes::const_span {
if (!_dhConfig.g || _dhConfig.p.empty()) {
LOG(("API Error: dhConfigNotModified on zero version."));
return {};
} else if (!validRandom(data.vrandom.v)) {
return {};
}
return bytes::make_span(data.vrandom.v);
});
}
void Instance::refreshServerConfig() {
if (_serverConfigRequestId) {
return;