Skip to content

Commit

Permalink
Fixed crash with forbidden megagroup in App::feedChats.
Browse files Browse the repository at this point in the history
ReplyMarkupClickHandler holds FullMsgId instead of HistoryItem*.
  • Loading branch information
john-preston committed Jun 15, 2016
1 parent 893cd9e commit 021c889
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
7 changes: 4 additions & 3 deletions Telegram/SourceFiles/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ namespace {
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
cdata->access = d.vaccess_hash.v;
cdata->date = d.vdate.v;
cdata->flags = d.vflags.v;
if (cdata->version < d.vversion.v) {
cdata->version = d.vversion.v;
}
Expand All @@ -694,12 +693,14 @@ namespace {
} else {
cdata->setRestrictionReason(QString());
}
cdata->flags = d.vflags.v;
}
cdata->flagsUpdated();

QString uname = d.has_username() ? textOneLine(qs(d.vusername)) : QString();
cdata->setName(qs(d.vtitle), uname);

cdata->isForbidden = false;
cdata->flagsUpdated();
cdata->setPhoto(d.vphoto);

if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn;
Expand Down Expand Up @@ -731,6 +732,7 @@ namespace {

auto mask = mtpCastFlags(MTPDchannelForbidden::Flag::f_broadcast | MTPDchannelForbidden::Flag::f_megagroup);
cdata->flags = (cdata->flags & ~mask) | (mtpCastFlags(d.vflags) & mask);
cdata->flagsUpdated();

cdata->setName(qs(d.vtitle), QString());

Expand All @@ -739,7 +741,6 @@ namespace {
cdata->date = 0;
cdata->setMembersCount(0);
cdata->isForbidden = true;
cdata->flagsUpdated();

if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn;
if (canEditPhoto != cdata->canEditPhoto()) update.flags |= UpdateFlag::ChannelCanEditPhoto;
Expand Down
47 changes: 38 additions & 9 deletions Telegram/SourceFiles/history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2180,7 +2180,7 @@ void HistoryBlock::removeItem(HistoryItem *item) {

class ReplyMarkupClickHandler : public LeftButtonClickHandler {
public:
ReplyMarkupClickHandler(const HistoryItem *item, int row, int col) : _item(item), _row(row), _col(col) {
ReplyMarkupClickHandler(const HistoryItem *item, int row, int col) : _itemId(item->fullId()), _row(row), _col(col) {
}

QString tooltip() const override {
Expand Down Expand Up @@ -2216,24 +2216,34 @@ class ReplyMarkupClickHandler : public LeftButtonClickHandler {
// Note: it is possible that we will point to the different button
// than the one was used when constructing the handler, but not a big deal.
const HistoryMessageReplyMarkup::Button *getButton() const {
if (auto markup = _item->Get<HistoryMessageReplyMarkup>()) {
if (_row < markup->rows.size()) {
const HistoryMessageReplyMarkup::ButtonRow &row(markup->rows.at(_row));
if (_col < row.size()) {
return &row.at(_col);
if (auto item = App::histItemById(_itemId)) {
if (auto markup = item->Get<HistoryMessageReplyMarkup>()) {
if (_row < markup->rows.size()) {
const HistoryMessageReplyMarkup::ButtonRow &row(markup->rows.at(_row));
if (_col < row.size()) {
return &row.at(_col);
}
}
}
}
return nullptr;
}

// We hold only FullMsgId, not HistoryItem*, because all click handlers
// are activated async and the item may be already destroyed.
void setMessageId(const FullMsgId &msgId) {
_itemId = msgId;
}

protected:
void onClickImpl() const override {
App::activateBotCommand(_item, _row, _col);
if (auto item = App::histItemById(_itemId)) {
App::activateBotCommand(item, _row, _col);
}
}

private:
const HistoryItem *_item = nullptr;
FullMsgId _itemId;
int _row, _col;
bool _fullDisplayed = true;

Expand Down Expand Up @@ -2270,6 +2280,16 @@ ReplyKeyboard::ReplyKeyboard(const HistoryItem *item, StylePtr &&s)
}
}

void ReplyKeyboard::updateMessageId() {
auto msgId = _item->fullId();
for_const (auto &row, _rows) {
for_const (auto &button, row) {
button.link->setMessageId(msgId);
}
}

}

void ReplyKeyboard::resize(int width, int height) {
_width = width;

Expand Down Expand Up @@ -2775,6 +2795,15 @@ void HistoryItem::recountAttachToPrevious() {
void HistoryItem::setId(MsgId newId) {
history()->changeMsgId(id, newId);
id = newId;

// We don't need to call Notify::replyMarkupUpdated(this) and update keyboard
// in history widget, because it can't exist for an outgoing message.
// Only inline keyboards can be in outgoing messages.
if (auto markup = inlineReplyMarkup()) {
if (markup->inlineKeyboard) {
markup->inlineKeyboard->updateMessageId();
}
}
}

bool HistoryItem::canEdit(const QDateTime &cur) const {
Expand Down Expand Up @@ -6816,7 +6845,7 @@ void HistoryMessage::initDimensions() {
}
if (replyw > _maxw) _maxw = replyw;
}
if (HistoryMessageReplyMarkup *markup = inlineReplyMarkup()) {
if (auto markup = inlineReplyMarkup()) {
if (!markup->inlineKeyboard) {
markup->inlineKeyboard.reset(new ReplyKeyboard(this, std_::make_unique<KeyboardStyle>(st::msgBotKbButton)));
}
Expand Down
1 change: 1 addition & 0 deletions Telegram/SourceFiles/history.h
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ class ReplyKeyboard {
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed);

void clearSelection();
void updateMessageId();

private:
const HistoryItem *_item;
Expand Down

0 comments on commit 021c889

Please sign in to comment.