Merge commit 'c36ed586e25eb9c3f822d595be2b0ef83a2b9fbc'

Conflicts:
	td/telegram/MessagesManager.cpp
This commit is contained in:
Andrea Cavalli 2021-04-04 16:37:10 +02:00
commit ae6ef91da2
5 changed files with 94 additions and 24 deletions

View File

@ -11164,7 +11164,11 @@ void MessagesManager::unload_dialog(DialogId dialog_id) {
LOG(ERROR) << "Unknown dialog " << dialog_id; LOG(ERROR) << "Unknown dialog " << dialog_id;
return; return;
} }
CHECK(d->has_unload_timeout);
if (!d->has_unload_timeout) {
// possible right after the dialog was opened
return;
}
if (!is_message_unload_enabled()) { if (!is_message_unload_enabled()) {
// just in case // just in case
@ -14918,7 +14922,13 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<te
} }
} }
for (auto dialog_id : old_pinned_dialog_ids) { for (auto dialog_id : old_pinned_dialog_ids) {
if (set_dialog_is_pinned(dialog_id, false)) { Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
LOG(ERROR) << "Failed to find " << dialog_id << " to unpin in " << folder_id;
force_create_dialog(dialog_id, "from_pinned_dialog_list", true);
d = get_dialog_force(dialog_id);
}
if (d != nullptr && set_dialog_is_pinned(DialogListId(folder_id), d, false)) {
are_pinned_dialogs_saved = true; are_pinned_dialogs_saved = true;
} }
} }
@ -19129,7 +19139,15 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector<D
set_dialog_is_pinned(dialog_id, true); set_dialog_is_pinned(dialog_id, true);
} }
for (auto dialog_id : old_pinned_dialog_ids) { for (auto dialog_id : old_pinned_dialog_ids) {
set_dialog_is_pinned(dialog_id, false); Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
LOG(ERROR) << "Failed to find " << dialog_id << " to unpin in " << dialog_list_id;
force_create_dialog(dialog_id, "set_pinned_dialogs", true);
d = get_dialog_force(dialog_id);
}
if (d != nullptr) {
set_dialog_is_pinned(dialog_list_id, d, false);
}
} }
if (server_old_dialog_ids != server_new_dialog_ids) { if (server_old_dialog_ids != server_new_dialog_ids) {
@ -34081,6 +34099,7 @@ MessageId MessagesManager::get_message_id_by_random_id(Dialog *d, int64 random_i
void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source, bool expect_no_access, void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source, bool expect_no_access,
bool force_update_dialog_pos) { bool force_update_dialog_pos) {
LOG_CHECK(dialog_id.is_valid()) << source; LOG_CHECK(dialog_id.is_valid()) << source;
LOG_CHECK(is_inited_) << dialog_id << ' ' << source << ' ' << expect_no_access << ' ' << force_update_dialog_pos;
Dialog *d = get_dialog_force(dialog_id); Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) { if (d == nullptr) {
LOG(INFO) << "Force create " << dialog_id << " from " << source; LOG(INFO) << "Force create " << dialog_id << " from " << source;
@ -34171,6 +34190,7 @@ MessagesManager::Dialog *MessagesManager::add_dialog(DialogId dialog_id) {
MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d, bool is_loaded_from_database) { MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d, bool is_loaded_from_database) {
auto dialog_id = d->dialog_id; auto dialog_id = d->dialog_id;
LOG_CHECK(is_inited_) << dialog_id << ' ' << is_loaded_from_database;
switch (dialog_id.get_type()) { switch (dialog_id.get_type()) {
case DialogType::User: case DialogType::User:
if (dialog_id == get_my_dialog_id() && d->last_read_inbox_message_id == MessageId::max() && if (dialog_id == get_my_dialog_id() && d->last_read_inbox_message_id == MessageId::max() &&
@ -34903,8 +34923,9 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen
} }
auto folder_ptr = get_dialog_folder(d->folder_id); auto folder_ptr = get_dialog_folder(d->folder_id);
LOG_CHECK(folder_ptr != nullptr) << dialog_id << ' ' << d->folder_id << ' ' << is_loaded_from_database << ' ' LOG_CHECK(folder_ptr != nullptr) << is_inited_ << ' ' << G()->close_flag() << ' ' << dialog_id << ' ' << d->folder_id
<< source; << ' ' << is_loaded_from_database << ' ' << td_->auth_manager_->is_authorized()
<< ' ' << td_->auth_manager_->was_authorized() << ' ' << source;
auto &folder = *folder_ptr; auto &folder = *folder_ptr;
if (old_date == new_date) { if (old_date == new_date) {
if (new_order == DEFAULT_ORDER) { if (new_order == DEFAULT_ORDER) {

View File

@ -36,6 +36,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <unistd.h> #include <unistd.h>
#else
#include <limits>
#endif #endif
#if TD_PORT_WINDOWS && defined(WIN32_LEAN_AND_MEAN) #if TD_PORT_WINDOWS && defined(WIN32_LEAN_AND_MEAN)
@ -254,7 +256,9 @@ Result<size_t> FileFd::write(Slice slice) {
BOOL success = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, nullptr); BOOL success = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, nullptr);
#endif #endif
if (success) { if (success) {
return narrow_cast<size_t>(bytes_written); auto result = narrow_cast<size_t>(bytes_written);
CHECK(result <= slice.size());
return result;
} }
return OS_ERROR(PSLICE() << "Write to " << get_native_fd() << " has failed"); return OS_ERROR(PSLICE() << "Write to " << get_native_fd() << " has failed");
} }
@ -266,14 +270,29 @@ Result<size_t> FileFd::writev(Span<IoSlice> slices) {
auto bytes_written = detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), slices_size); }); auto bytes_written = detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), slices_size); });
bool success = bytes_written >= 0; bool success = bytes_written >= 0;
if (success) { if (success) {
return narrow_cast<size_t>(bytes_written); auto result = narrow_cast<size_t>(bytes_written);
auto left = result;
for (const auto &slice : slices) {
if (left <= slice.iov_len) {
return result;
}
left -= slice.iov_len;
}
UNREACHABLE();
} }
return OS_ERROR(PSLICE() << "Writev to " << get_native_fd() << " has failed"); return OS_ERROR(PSLICE() << "Writev to " << get_native_fd() << " has failed");
#else #else
size_t res = 0; size_t res = 0;
for (auto slice : slices) { for (const auto &slice : slices) {
if (slice.size() > std::numeric_limits<size_t>::max() - res) {
break;
}
TRY_RESULT(size, write(slice)); TRY_RESULT(size, write(slice));
res += size; res += size;
if (size != slice.size()) {
CHECK(size < slice.size());
break;
}
} }
return res; return res;
#endif #endif
@ -305,7 +324,9 @@ Result<size_t> FileFd::read(MutableSlice slice) {
if (is_eof) { if (is_eof) {
get_poll_info().clear_flags(PollFlags::Read()); get_poll_info().clear_flags(PollFlags::Read());
} }
return static_cast<size_t>(bytes_read); auto result = narrow_cast<size_t>(bytes_read);
CHECK(result <= slice.size());
return result;
} }
return OS_ERROR(PSLICE() << "Read from " << get_native_fd() << " has failed"); return OS_ERROR(PSLICE() << "Read from " << get_native_fd() << " has failed");
} }
@ -329,7 +350,9 @@ Result<size_t> FileFd::pwrite(Slice slice, int64 offset) {
BOOL success = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, &overlapped); BOOL success = WriteFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_written, &overlapped);
#endif #endif
if (success) { if (success) {
return narrow_cast<size_t>(bytes_written); auto result = narrow_cast<size_t>(bytes_written);
CHECK(result <= slice.size());
return result;
} }
return OS_ERROR(PSLICE() << "Pwrite to " << get_native_fd() << " at offset " << offset << " has failed"); return OS_ERROR(PSLICE() << "Pwrite to " << get_native_fd() << " at offset " << offset << " has failed");
} }
@ -352,7 +375,9 @@ Result<size_t> FileFd::pread(MutableSlice slice, int64 offset) const {
BOOL success = ReadFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_read, &overlapped); BOOL success = ReadFile(native_fd, slice.data(), narrow_cast<DWORD>(slice.size()), &bytes_read, &overlapped);
#endif #endif
if (success) { if (success) {
return narrow_cast<size_t>(bytes_read); auto result = narrow_cast<size_t>(bytes_read);
CHECK(result <= slice.size());
return result;
} }
return OS_ERROR(PSLICE() << "Pread from " << get_native_fd() << " at offset " << offset << " has failed"); return OS_ERROR(PSLICE() << "Pread from " << get_native_fd() << " at offset " << offset << " has failed");
} }

View File

@ -76,11 +76,15 @@ inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) {
} }
inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) {
auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFileEx); auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFile);
if (func != &MoveFileEx && (dwFlags & MOVEFILE_REPLACE_EXISTING) != 0) { if (func == &MoveFile || (dwFlags & ~MOVEFILE_REPLACE_EXISTING) != 0) {
// if can't find MoveFileFromAppW or have unsupported flags, call MoveFileEx directly
return MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags);
}
if ((dwFlags & MOVEFILE_REPLACE_EXISTING) != 0) {
td::DeleteFileFromAppW(lpNewFileName); td::DeleteFileFromAppW(lpNewFileName);
} }
return func(lpExistingFileName, lpNewFileName, dwFlags); return func(lpExistingFileName, lpNewFileName);
} }
inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId,

View File

@ -25,7 +25,7 @@ inline IoSlice as_io_slice(Slice slice) {
return res; return res;
} }
inline Slice as_slice(const IoSlice io_slice) { inline Slice as_slice(const IoSlice &io_slice) {
return Slice(static_cast<const char *>(io_slice.iov_base), io_slice.iov_len); return Slice(static_cast<const char *>(io_slice.iov_base), io_slice.iov_len);
} }

View File

@ -18,6 +18,8 @@
#include "td/utils/port/detail/Iocp.h" #include "td/utils/port/detail/Iocp.h"
#include "td/utils/SpinLock.h" #include "td/utils/SpinLock.h"
#include "td/utils/VectorQueue.h" #include "td/utils/VectorQueue.h"
#include <limits>
#endif #endif
#if TD_PORT_POSIX #if TD_PORT_POSIX
@ -98,7 +100,9 @@ class SocketFdImpl : private Iocp::Callback {
Result<size_t> writev(Span<IoSlice> slices) { Result<size_t> writev(Span<IoSlice> slices) {
size_t total_size = 0; size_t total_size = 0;
for (auto io_slice : slices) { for (auto io_slice : slices) {
total_size += as_slice(io_slice).size(); auto size = as_slice(io_slice).size();
CHECK(size <= std::numeric_limits<size_t>::max() - total_size);
total_size += size;
} }
auto left_size = total_size; auto left_size = total_size;
@ -399,7 +403,19 @@ class SocketFdImpl {
return ::writev(native_fd, slices.begin(), slices_size); return ::writev(native_fd, slices.begin(), slices_size);
#endif #endif
}); });
return write_finish(write_res); if (write_res >= 0) {
auto result = narrow_cast<size_t>(write_res);
auto left = result;
for (const auto &slice : slices) {
if (left <= slice.iov_len) {
return result;
}
left -= slice.iov_len;
}
LOG(FATAL) << "Receive " << result << " as writev response, but tried to write only " << result - left
<< " bytes";
}
return write_finish();
} }
Result<size_t> write(Slice slice) { Result<size_t> write(Slice slice) {
@ -412,15 +428,17 @@ class SocketFdImpl {
::write(native_fd, slice.begin(), slice.size()); ::write(native_fd, slice.begin(), slice.size());
#endif #endif
}); });
return write_finish(write_res); if (write_res >= 0) {
auto result = narrow_cast<size_t>(write_res);
LOG_CHECK(result <= slice.size()) << "Receive " << result << " as write response, but tried to write only "
<< slice.size() << " bytes";
return result;
}
return write_finish();
} }
Result<size_t> write_finish(ssize_t write_res) { Result<size_t> write_finish() {
auto write_errno = errno; auto write_errno = errno;
if (write_res >= 0) {
return narrow_cast<size_t>(write_res);
}
if (write_errno == EAGAIN if (write_errno == EAGAIN
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK
|| write_errno == EWOULDBLOCK || write_errno == EWOULDBLOCK
@ -468,7 +486,9 @@ class SocketFdImpl {
get_poll_info().clear_flags(PollFlags::Read()); get_poll_info().clear_flags(PollFlags::Read());
get_poll_info().add_flags(PollFlags::Close()); get_poll_info().add_flags(PollFlags::Close());
} }
return narrow_cast<size_t>(read_res); auto result = narrow_cast<size_t>(read_res);
CHECK(result <= slice.size());
return result;
} }
if (read_errno == EAGAIN if (read_errno == EAGAIN
#if EAGAIN != EWOULDBLOCK #if EAGAIN != EWOULDBLOCK