Add sanity checks for get_channel_participants results.
GitOrigin-RevId: 3bc0ac414e7b6ca18631528ff069564ac9862409
This commit is contained in:
parent
d3a82b449c
commit
3c8fd02d07
@ -7433,20 +7433,32 @@ void ContactsManager::on_get_channel_participants_success(
|
|||||||
auto it = received_channel_participants_.find(random_id);
|
auto it = received_channel_participants_.find(random_id);
|
||||||
CHECK(it != received_channel_participants_.end());
|
CHECK(it != received_channel_participants_.end());
|
||||||
|
|
||||||
it->second.first = total_count;
|
|
||||||
|
|
||||||
auto &result = it->second.second;
|
auto &result = it->second.second;
|
||||||
CHECK(result.empty());
|
CHECK(result.empty());
|
||||||
for (auto &participant_ptr : participants) {
|
for (auto &participant_ptr : participants) {
|
||||||
result.push_back(get_dialog_participant(channel_id, std::move(participant_ptr)));
|
result.push_back(get_dialog_participant(channel_id, std::move(participant_ptr)));
|
||||||
|
if ((filter.is_bots() && !is_user_bot(result.back().user_id)) ||
|
||||||
|
(filter.is_administrators() && !result.back().status.is_administrator()) ||
|
||||||
|
((filter.is_recent() || filter.is_search()) && !result.back().status.is_member()) ||
|
||||||
|
(filter.is_restricted() && !result.back().status.is_restricted()) ||
|
||||||
|
(filter.is_banned() && !result.back().status.is_banned())) {
|
||||||
|
LOG(ERROR) << "Receive " << result.back() << ", while searching for " << filter;
|
||||||
|
result.pop_back();
|
||||||
|
total_count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (total_count < narrow_cast<int32>(result.size())) {
|
||||||
|
LOG(ERROR) << "Receive total_count = " << total_count << ", but have at least " << result.size() << " members in "
|
||||||
|
<< channel_id;
|
||||||
|
total_count = static_cast<int32>(result.size());
|
||||||
|
}
|
||||||
|
it->second.first = total_count;
|
||||||
|
|
||||||
if (filter.is_recent() && total_count != 0 && total_count < 10000) {
|
if (filter.is_recent() && total_count != 0 && total_count < 10000) {
|
||||||
auto channel_full = get_channel_full(channel_id);
|
auto channel_full = get_channel_full(channel_id);
|
||||||
if (channel_full != nullptr && channel_full->participant_count != total_count) {
|
if (channel_full != nullptr && channel_full->participant_count != total_count) {
|
||||||
channel_full->participant_count = total_count;
|
channel_full->participant_count = total_count;
|
||||||
channel_full->is_changed = true;
|
channel_full->is_changed = true;
|
||||||
update_channel_full(channel_full, channel_id);
|
|
||||||
}
|
}
|
||||||
auto c = get_channel(channel_id);
|
auto c = get_channel(channel_id);
|
||||||
if (c != nullptr && c->participant_count != total_count) {
|
if (c != nullptr && c->participant_count != total_count) {
|
||||||
@ -7455,16 +7467,23 @@ void ContactsManager::on_get_channel_participants_success(
|
|||||||
update_channel(c, channel_id);
|
update_channel(c, channel_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset == 0 && static_cast<int32>(participants.size()) < limit) {
|
int32 administrator_count = filter.is_administrators() ? total_count : -1;
|
||||||
if (filter.is_administrators() || filter.is_bots()) {
|
if (offset == 0 && static_cast<int32>(participants.size()) < limit &&
|
||||||
auto user_ids = transform(result, [](const DialogParticipant &participant) { return participant.user_id; });
|
(filter.is_administrators() || filter.is_bots())) {
|
||||||
if (filter.is_administrators()) {
|
auto user_ids = transform(result, [](const DialogParticipant &participant) { return participant.user_id; });
|
||||||
on_update_dialog_administrators(DialogId(channel_id), std::move(user_ids), true);
|
if (filter.is_administrators()) {
|
||||||
} else {
|
on_update_dialog_administrators(DialogId(channel_id), std::move(user_ids), true);
|
||||||
td_->messages_manager_->on_dialog_bots_updated(DialogId(channel_id), std::move(user_ids));
|
}
|
||||||
}
|
if (filter.is_bots()) {
|
||||||
|
td_->messages_manager_->on_dialog_bots_updated(DialogId(channel_id), std::move(user_ids));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto channel_full = get_channel_full(channel_id);
|
||||||
|
if (channel_full != nullptr && channel_full->administrator_count != administrator_count) {
|
||||||
|
channel_full->administrator_count = administrator_count;
|
||||||
|
channel_full->is_changed = true;
|
||||||
|
}
|
||||||
|
update_channel_full(channel_full, channel_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::on_get_channel_participants_fail(ChannelId channel_id, ChannelParticipantsFilter filter,
|
void ContactsManager::on_get_channel_participants_fail(ChannelId channel_id, ChannelParticipantsFilter filter,
|
||||||
|
@ -371,6 +371,12 @@ DialogParticipantStatus get_dialog_participant_status(
|
|||||||
can_send_games, can_use_inline_bots, can_add_web_page_previews);
|
can_send_games, can_use_inline_bots, can_add_web_page_previews);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant &dialog_participant) {
|
||||||
|
return string_builder << '[' << dialog_participant.user_id << " invited by " << dialog_participant.inviter_user_id
|
||||||
|
<< " at " << dialog_participant.joined_date << " with status " << dialog_participant.status
|
||||||
|
<< ']';
|
||||||
|
}
|
||||||
|
|
||||||
tl_object_ptr<telegram_api::ChannelParticipantsFilter>
|
tl_object_ptr<telegram_api::ChannelParticipantsFilter>
|
||||||
ChannelParticipantsFilter::get_input_channel_participants_filter() const {
|
ChannelParticipantsFilter::get_input_channel_participants_filter() const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -425,6 +431,26 @@ ChannelParticipantsFilter::ChannelParticipantsFilter(const tl_object_ptr<td_api:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter) {
|
||||||
|
switch (filter.type) {
|
||||||
|
case ChannelParticipantsFilter::Type::Recent:
|
||||||
|
return string_builder << "Recent";
|
||||||
|
case ChannelParticipantsFilter::Type::Administrators:
|
||||||
|
return string_builder << "Administrators";
|
||||||
|
case ChannelParticipantsFilter::Type::Search:
|
||||||
|
return string_builder << "Search \"" << filter.query << '"';
|
||||||
|
case ChannelParticipantsFilter::Type::Restricted:
|
||||||
|
return string_builder << "Restricted \"" << filter.query << '"';
|
||||||
|
case ChannelParticipantsFilter::Type::Banned:
|
||||||
|
return string_builder << "Banned \"" << filter.query << '"';
|
||||||
|
case ChannelParticipantsFilter::Type::Bots:
|
||||||
|
return string_builder << "Bots";
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return string_builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter) {
|
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter) {
|
||||||
if (filter == nullptr) {
|
if (filter == nullptr) {
|
||||||
return DialogParticipantsFilter::Members;
|
return DialogParticipantsFilter::Members;
|
||||||
|
@ -246,10 +246,14 @@ struct DialogParticipant {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant &dialog_participant);
|
||||||
|
|
||||||
class ChannelParticipantsFilter {
|
class ChannelParticipantsFilter {
|
||||||
enum class Type : int32 { Recent, Administrators, Search, Restricted, Banned, Bots } type;
|
enum class Type : int32 { Recent, Administrators, Search, Restricted, Banned, Bots } type;
|
||||||
string query;
|
string query;
|
||||||
|
|
||||||
|
friend StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ChannelParticipantsFilter(const tl_object_ptr<td_api::SupergroupMembersFilter> &filter);
|
explicit ChannelParticipantsFilter(const tl_object_ptr<td_api::SupergroupMembersFilter> &filter);
|
||||||
|
|
||||||
@ -266,8 +270,22 @@ class ChannelParticipantsFilter {
|
|||||||
bool is_recent() const {
|
bool is_recent() const {
|
||||||
return type == Type::Recent;
|
return type == Type::Recent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_search() const {
|
||||||
|
return type == Type::Search;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_restricted() const {
|
||||||
|
return type == Type::Search;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_banned() const {
|
||||||
|
return type == Type::Search;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter);
|
||||||
|
|
||||||
enum class DialogParticipantsFilter : int32 { Administrators, Members, Restricted, Banned, Bots };
|
enum class DialogParticipantsFilter : int32 { Administrators, Members, Restricted, Banned, Bots };
|
||||||
|
|
||||||
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter);
|
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter);
|
||||||
|
Reference in New Issue
Block a user