2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Remove exceptions in TL parsing.

This commit is contained in:
John Preston
2019-07-18 16:06:38 +02:00
parent 4a10a88ecf
commit 6aa930d510
18 changed files with 463 additions and 384 deletions

View File

@@ -1637,8 +1637,7 @@ void ConnectionPrivate::handleReceived() {
}
ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPrime *from, const mtpPrime *end, uint64 msgId, int32 serverTime, uint64 serverSalt, bool badTime) {
mtpTypeId cons = *from;
try {
const auto cons = *from;
switch (cons) {
@@ -1652,17 +1651,23 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
}
case mtpc_msg_container: {
if (++from >= end) throw mtpErrorInsufficient();
if (++from >= end) {
return HandleResult::ParseError;
}
const mtpPrime *otherEnd;
uint32 msgsCount = (uint32)*(from++);
const auto msgsCount = (uint32)*(from++);
DEBUG_LOG(("Message Info: container received, count: %1").arg(msgsCount));
for (uint32 i = 0; i < msgsCount; ++i) {
if (from + 4 >= end) throw mtpErrorInsufficient();
if (from + 4 >= end) {
return HandleResult::ParseError;
}
otherEnd = from + 4;
MTPlong inMsgId;
inMsgId.read(from, otherEnd);
if (!inMsgId.read(from, otherEnd)) {
return HandleResult::ParseError;
}
bool isReply = ((inMsgId.v & 0x03) == 1);
if (!isReply && ((inMsgId.v & 0x03) != 3)) {
LOG(("Message Error: bad msg_id %1 in contained message received").arg(inMsgId.v));
@@ -1670,9 +1675,13 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
}
MTPint inSeqNo;
inSeqNo.read(from, otherEnd);
if (!inSeqNo.read(from, otherEnd)) {
return HandleResult::ParseError;
}
MTPint bytes;
bytes.read(from, otherEnd);
if (!bytes.read(from, otherEnd)) {
return HandleResult::ParseError;
}
if ((bytes.v & 0x03) || bytes.v < 4) {
LOG(("Message Error: bad length %1 of contained message received").arg(bytes.v));
return HandleResult::RestartConnection;
@@ -1684,7 +1693,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
DEBUG_LOG(("Message Info: message from container, msg_id: %1, needAck: %2").arg(inMsgId.v).arg(Logs::b(needAck)));
otherEnd = from + (bytes.v >> 2);
if (otherEnd > end) throw mtpErrorInsufficient();
if (otherEnd > end) {
return HandleResult::ParseError;
}
bool needToHandle = false;
{
@@ -1706,7 +1717,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_msgs_ack: {
MTPMsgsAck msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
auto &ids = msg.c_msgs_ack().vmsg_ids().v;
uint32 idsCount = ids.size();
@@ -1725,7 +1738,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_bad_msg_notification: {
MTPBadMsgNotification msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
const auto &data(msg.c_bad_msg_notification());
LOG(("Message Info: bad message notification received (error_code %3) for msg_id = %1, seq_no = %2").arg(data.vbad_msg_id().v).arg(data.vbad_msg_seqno().v).arg(data.verror_code().v));
@@ -1822,7 +1837,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_bad_server_salt: {
MTPBadMsgNotification msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
const auto &data(msg.c_bad_server_salt());
DEBUG_LOG(("Message Info: bad server salt received (error_code %4) for msg_id = %1, seq_no = %2, new salt: %3").arg(data.vbad_msg_id().v).arg(data.vbad_msg_seqno().v).arg(data.vnew_server_salt().v).arg(data.verror_code().v));
@@ -1857,7 +1874,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
return HandleResult::Ignored;
}
MTPMsgsStateReq msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
auto &ids = msg.c_msgs_state_req().vmsg_ids().v;
auto idsCount = ids.size();
DEBUG_LOG(("Message Info: msgs_state_req received, ids: %1").arg(LogIdsVector(ids)));
@@ -1905,7 +1924,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_msgs_state_info: {
MTPMsgsStateInfo msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
auto &data = msg.c_msgs_state_info();
auto reqMsgId = data.vreq_msg_id().v;
@@ -1938,20 +1959,21 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
LOG(("Message Error: bad request %1 found in requestMap, size: %2").arg(reqMsgId).arg(requestBuffer->size()));
return HandleResult::RestartConnection;
}
try {
const mtpPrime *rFrom = requestBuffer->constData() + 8, *rEnd = requestBuffer->constData() + requestBuffer->size();
if (mtpTypeId(*rFrom) == mtpc_msgs_state_req) {
MTPMsgsStateReq request;
request.read(rFrom, rEnd);
handleMsgsStates(request.c_msgs_state_req().vmsg_ids().v, states, toAck);
} else {
MTPMsgResendReq request;
request.read(rFrom, rEnd);
handleMsgsStates(request.c_msg_resend_req().vmsg_ids().v, states, toAck);
const mtpPrime *rFrom = requestBuffer->constData() + 8, *rEnd = requestBuffer->constData() + requestBuffer->size();
if (mtpTypeId(*rFrom) == mtpc_msgs_state_req) {
MTPMsgsStateReq request;
if (!request.read(rFrom, rEnd)) {
LOG(("Message Error: could not parse sent msgs_state_req"));
return HandleResult::ParseError;
}
} catch(Exception &) {
LOG(("Message Error: could not parse sent msgs_state_req"));
throw;
handleMsgsStates(request.c_msgs_state_req().vmsg_ids().v, states, toAck);
} else {
MTPMsgResendReq request;
if (!request.read(rFrom, rEnd)) {
LOG(("Message Error: could not parse sent msgs_state_req"));
return HandleResult::ParseError;
}
handleMsgsStates(request.c_msg_resend_req().vmsg_ids().v, states, toAck);
}
requestsAcked(toAck);
@@ -1964,7 +1986,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
}
MTPMsgsAllInfo msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
auto &data = msg.c_msgs_all_info();
auto &ids = data.vmsg_ids().v;
auto &states = data.vinfo().v;
@@ -1979,7 +2003,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_msg_detailed_info: {
MTPMsgDetailedInfo msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
const auto &data(msg.c_msg_detailed_info());
DEBUG_LOG(("Message Info: msg detailed info, sent msgId %1, answerId %2, status %3, bytes %4").arg(data.vmsg_id().v).arg(data.vanswer_msg_id().v).arg(data.vstatus().v).arg(data.vbytes().v));
@@ -2015,7 +2041,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
return HandleResult::Ignored;
}
MTPMsgDetailedInfo msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
const auto &data(msg.c_msg_new_detailed_info());
DEBUG_LOG(("Message Info: msg new detailed info, answerId %2, status %3, bytes %4").arg(data.vanswer_msg_id().v).arg(data.vstatus().v).arg(data.vbytes().v));
@@ -2036,7 +2064,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_msg_resend_req: {
MTPMsgResendReq msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
auto &ids = msg.c_msg_resend_req().vmsg_ids().v;
auto idsCount = ids.size();
@@ -2051,11 +2081,15 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success;
case mtpc_rpc_result: {
if (from + 3 > end) throw mtpErrorInsufficient();
if (from + 3 > end) {
return HandleResult::ParseError;
}
auto response = SerializedMessage();
MTPlong reqMsgId;
reqMsgId.read(++from, end);
if (!reqMsgId.read(++from, end)) {
return HandleResult::ParseError;
}
mtpTypeId typeId = from[0];
DEBUG_LOG(("RPC Info: response received for %1, queueing...").arg(reqMsgId.v));
@@ -2074,7 +2108,7 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
if (typeId == mtpc_gzip_packed) {
DEBUG_LOG(("RPC Info: gzip container"));
response = ungzip(++from, end);
if (!response.size()) {
if (response.empty()) {
return HandleResult::RestartConnection;
}
typeId = response[0];
@@ -2105,7 +2139,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_new_session_created: {
const mtpPrime *start = from;
MTPNewSession msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
const auto &data(msg.c_new_session_created());
if (badTime) {
@@ -2143,7 +2179,9 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_pong: {
MTPPong msg;
msg.read(from, end);
if (!msg.read(from, end)) {
return HandleResult::ParseError;
}
const auto &data(msg.c_pong());
DEBUG_LOG(("Message Info: pong received, msg_id: %1, ping_id: %2").arg(data.vmsg_id().v).arg(data.vping_id().v));
@@ -2170,10 +2208,6 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
}
} catch (Exception &) {
return HandleResult::RestartConnection;
}
if (badTime) {
DEBUG_LOG(("Message Error: bad time in updates cons, must create new session"));
return HandleResult::ResetSession;
@@ -2205,12 +2239,16 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
}
mtpBuffer ConnectionPrivate::ungzip(const mtpPrime *from, const mtpPrime *end) const {
MTPstring packed;
packed.read(from, end); // read packed string as serialized mtp string type
uint32 packedLen = packed.v.size(), unpackedChunk = packedLen, unpackedLen = 0;
mtpBuffer result; // * 4 because of mtpPrime type
result.resize(0);
MTPstring packed;
if (!packed.read(from, end)) { // read packed string as serialized mtp string type
LOG(("RPC Error: could not read gziped bytes."));
return result;
}
uint32 packedLen = packed.v.size(), unpackedChunk = packedLen, unpackedLen = 0;
z_stream stream;
stream.zalloc = 0;
stream.zfree = 0;
@@ -2730,7 +2768,10 @@ void ConnectionPrivate::dhParamsAnswered() {
const mtpPrime *from(&decBuffer[5]), *to(from), *end(from + (encDHBufLen - 5));
MTPServer_DH_inner_data dh_inner;
dh_inner.read(to, end);
if (!dh_inner.read(to, end)) {
LOG(("AuthKey Error: could not decrypt server_DH_inner_data!"));
return restart();
}
const auto &dh_inner_data(dh_inner.c_server_DH_inner_data());
if (dh_inner_data.vnonce() != _authKeyData->nonce) {
LOG(("AuthKey Error: received nonce <> sent nonce (in server_DH_inner_data)!"));
@@ -3100,13 +3141,8 @@ bool ConnectionPrivate::readNotSecureResponse(Response &response) {
if (answer.empty()) {
return false;
}
try {
auto from = answer.data();
response.read(from, from + answer.size());
} catch (Exception &) {
return false;
}
return true;
auto from = answer.data();
return response.read(from, from + answer.size());
}
bool ConnectionPrivate::sendSecureRequest(