From c514c62d615454dcbbf0e7660293a1e9b796432f Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 22 Oct 2016 18:58:14 +0300 Subject: [PATCH] Attempt to fix a crash in getUserFull() without a loaded peer. --- Telegram/SourceFiles/dialogswidget.cpp | 89 ++++++++++++------- Telegram/SourceFiles/history.cpp | 6 +- Telegram/SourceFiles/historywidget.cpp | 2 +- Telegram/SourceFiles/mainwidget.cpp | 2 +- .../SourceFiles/ui/style/style_core_icon.cpp | 9 +- 5 files changed, 64 insertions(+), 44 deletions(-) diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 978109375..db1ce4495 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -432,9 +432,14 @@ void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRo } void DialogsInner::createDialog(History *history) { + if (history->peer->loadedStatus != PeerData::LoadedStatus::FullLoaded) { + LOG(("API Error: DialogsInner::createDialog() called for a non loaded peer!")); + return; + } + bool creating = !history->inChatList(Dialogs::Mode::All); if (creating) { - Dialogs::Row *mainRow = history->addToChatList(Dialogs::Mode::All, dialogs.get()); + auto mainRow = history->addToChatList(Dialogs::Mode::All, dialogs.get()); contactsNoDialogs->del(history->peer, mainRow); } if (importantDialogs && !history->inChatList(Dialogs::Mode::Important) && !history->mute()) { @@ -1046,30 +1051,39 @@ bool DialogsInner::searchReceived(const QVector &messages, DialogsSe if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) { clearSearchResults(false); } - int32 lastDateFound = 0; - for (QVector::const_iterator i = messages.cbegin(), e = messages.cend(); i != e; ++i) { - HistoryItem *item = App::histories().addNewMessage(*i, NewMessageExisting); - int32 lastDate = dateFromMessage(*i); - if (lastDate) { - _searchResults.push_back(new Dialogs::FakeRow(item)); - lastDateFound = lastDate; - if (type == DialogsSearchFromStart || type == DialogsSearchFromOffset) { - _lastSearchDate = lastDateFound; + auto isGlobalSearch = (type == DialogsSearchFromStart || type == DialogsSearchFromOffset); + auto isMigratedSearch = (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset); + + TimeId lastDateFound = 0; + for_const (auto message, messages) { + if (auto msgId = idFromMessage(message)) { + auto peerId = peerFromMessage(message); + auto lastDate = dateFromMessage(message); + if (auto peer = App::peerLoaded(peerId)) { + if (lastDate) { + auto item = App::histories().addNewMessage(message, NewMessageExisting); + _searchResults.push_back(new Dialogs::FakeRow(item)); + lastDateFound = lastDate; + if (isGlobalSearch) { + _lastSearchDate = lastDateFound; + } + } + if (isGlobalSearch) { + _lastSearchPeer = peer; + } + } else { + LOG(("API Error: a search results with not loaded peer %1").arg(peerId)); } - } - if (item) { - if (type == DialogsSearchFromStart || type == DialogsSearchFromOffset) { - _lastSearchPeer = item->history()->peer; + if (isMigratedSearch) { + _lastSearchMigratedId = msgId; + } else { + _lastSearchId = msgId; } - } - MsgId msgId = item ? item->id : idFromMessage(*i); - if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) { - _lastSearchMigratedId = msgId; } else { - _lastSearchId = msgId; + LOG(("API Error: a search results with not message id")); } } - if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) { + if (isMigratedSearch) { _searchedMigratedCount = fullCount; } else { _searchedCount = fullCount; @@ -1085,15 +1099,18 @@ void DialogsInner::peopleReceived(const QString &query, const QVector & _peopleQuery = query.toLower().trimmed(); _peopleResults.clear(); _peopleResults.reserve(people.size()); - for (QVector::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) { - PeerId peerId = peerFromMTP(*i); - if (History *h = App::historyLoaded(peerId)) { - if (h->inChatList(Dialogs::Mode::All)) { + for (auto i = people.cbegin(), e = people.cend(); i != e; ++i) { + auto peerId = peerFromMTP(*i); + if (auto history = App::historyLoaded(peerId)) { + if (history->inChatList(Dialogs::Mode::All)) { continue; // skip existing chats } } - - _peopleResults.push_back(App::peer(peerId)); + if (auto peer = App::peerLoaded(peerId)) { + _peopleResults.push_back(App::peer(peerId)); + } else { + LOG(("API Error: user %1 was not loaded in DialogsInner::peopleReceived()").arg(peerId)); + } } refresh(); } @@ -1112,8 +1129,12 @@ void DialogsInner::contactsReceived(const QVector &contacts) { } void DialogsInner::notify_userIsContactChanged(UserData *user, bool fromThisApp) { + if (user->loadedStatus != PeerData::FullLoaded) { + LOG(("API Error: notify_userIsContactChanged() called for a not loaded user!")); + return; + } if (user->contact > 0) { - History *history = App::history(user->id); + auto history = App::history(user->id); contacts->addByName(history); if (auto row = shownDialogs()->getRow(user->id)) { if (fromThisApp) { @@ -2050,7 +2071,7 @@ bool DialogsWidget::onSearchMessages(bool searchCache) { } if (!_searchInPeer && q.size() >= MinUsernameLength) { if (searchCache) { - PeopleCache::const_iterator i = _peopleCache.constFind(q); + auto i = _peopleCache.constFind(q); if (i != _peopleCache.cend()) { _peopleQuery = q; _peopleRequest = 0; @@ -2214,22 +2235,22 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa } void DialogsWidget::peopleReceived(const MTPcontacts_Found &result, mtpRequestId req) { - QString q = _peopleQuery; + auto q = _peopleQuery; if (_inner.state() == DialogsInner::FilteredState || _inner.state() == DialogsInner::SearchedState) { - PeopleQueries::iterator i = _peopleQueries.find(req); + auto i = _peopleQueries.find(req); if (i != _peopleQueries.cend()) { q = i.value(); _peopleCache[q] = result; _peopleQueries.erase(i); } } - if (_peopleRequest == req) { switch (result.type()) { case mtpc_contacts_found: { - App::feedUsers(result.c_contacts_found().vusers); - App::feedChats(result.c_contacts_found().vchats); - _inner.peopleReceived(q, result.c_contacts_found().vresults.c_vector().v); + auto &d = result.c_contacts_found(); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + _inner.peopleReceived(q, d.vresults.c_vector().v); } break; } diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index b9df52925..038a91514 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -957,8 +957,9 @@ HistoryItem *History::addNewMessage(const MTPMessage &msg, NewMessageType type) } HistoryItem *History::addNewToLastBlock(const MTPMessage &msg, NewMessageType type) { - bool applyServiceAction = (type == NewMessageUnread), detachExistingItem = (type != NewMessageLast); - HistoryItem *item = createItem(msg, applyServiceAction, detachExistingItem); + auto applyServiceAction = (type == NewMessageUnread); + auto detachExistingItem = (type != NewMessageLast); + auto item = createItem(msg, applyServiceAction, detachExistingItem); if (!item || !item->detached()) { return item; } @@ -1139,7 +1140,6 @@ void History::newItemAdded(HistoryItem *item) { outboxRead(item); } } else if (item->unread()) { - bool skip = false; if (!isChannel() || peer->asChannel()->amIn()) { notifies.push_back(item); App::main()->newUnreadMsg(this, item); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 863993545..a8917224e 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -4742,7 +4742,7 @@ void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) { void HistoryWidget::historyToDown(History *history) { history->forgetScrollState(); - if (History *migrated = App::historyLoaded(history->peer->migrateFrom())) { + if (auto migrated = App::historyLoaded(history->peer->migrateFrom())) { migrated->forgetScrollState(); } if (history == _history) { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 6ee85f510..6f13aed38 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -4716,7 +4716,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_updateNewChannelMessage: { auto &d = update.c_updateNewChannelMessage(); auto channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage))); - DataIsLoadedResult isDataLoaded = allDataLoadedForMessage(d.vmessage); + auto isDataLoaded = allDataLoadedForMessage(d.vmessage); if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) { MTP_LOG(0, ("getDifference { good - after not all data loaded in updateNewChannelMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); diff --git a/Telegram/SourceFiles/ui/style/style_core_icon.cpp b/Telegram/SourceFiles/ui/style/style_core_icon.cpp index d373b8b58..acad1c618 100644 --- a/Telegram/SourceFiles/ui/style/style_core_icon.cpp +++ b/Telegram/SourceFiles/ui/style/style_core_icon.cpp @@ -40,16 +40,15 @@ inline int pxAdjust(int value, int scale) { } QPixmap createIconPixmap(const IconMask *mask, const Color &color) { - QImage maskImage, finalImage; - bool loaded = maskImage.loadFromData(mask->data(), mask->size(), "PNG"); - t_assert(loaded != false); + auto maskImage = QImage::fromData(mask->data(), mask->size(), "PNG"); + t_assert(!maskImage.isNull()); // images are layouted like this: // 200x 100x // 150x 125x int width = maskImage.width() / 3; int height = qRound((maskImage.height() * 2) / 7.); - QRect r = QRect(0, 0, width * 2, height * 2); + auto r = QRect(0, 0, width * 2, height * 2); if (!cRetina() && cScale() != dbisTwo) { if (cScale() == dbisOne) { r = QRect(width * 2, 0, width, height); @@ -65,7 +64,7 @@ QPixmap createIconPixmap(const IconMask *mask, const Color &color) { } } } - finalImage = colorizeImage(maskImage, color, r); + auto finalImage = colorizeImage(maskImage, color, r); finalImage.setDevicePixelRatio(cRetinaFactor()); return App::pixmapFromImageInPlace(std_::move(finalImage)); }