From bee68243e8541c3d3038679f0a0c7a4aadf81ed8 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 3 Apr 2021 02:19:30 +0300 Subject: [PATCH 1/8] Fix CHECK. --- td/telegram/MessagesManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ad0b10593..63df32454 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -10970,7 +10970,11 @@ void MessagesManager::unload_dialog(DialogId dialog_id) { Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - CHECK(d->has_unload_timeout); + + if (!d->has_unload_timeout) { + // possible right after the dialog was opened + return; + } if (!is_message_unload_enabled()) { // just in case From 5a885bd06d783cee8253f290638277c42e906a8a Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 3 Apr 2021 02:46:56 +0300 Subject: [PATCH 2/8] Add more logging. --- td/telegram/MessagesManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 63df32454..9c3a9be12 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -34561,8 +34561,9 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen } auto folder_ptr = get_dialog_folder(d->folder_id); - LOG_CHECK(folder_ptr != nullptr) << dialog_id << ' ' << d->folder_id << ' ' << is_loaded_from_database << ' ' - << source; + LOG_CHECK(folder_ptr != nullptr) << is_inited_ << ' ' << G()->close_flag() << ' ' << dialog_id << ' ' << d->folder_id + << ' ' << is_loaded_from_database << ' ' << td_->auth_manager_->is_authorized() + << ' ' << td_->auth_manager_->was_authorized() << ' ' << source; auto &folder = *folder_ptr; if (old_date == new_date) { if (new_order == DEFAULT_ORDER) { From 84194768ae963ee91b2ca2a5fb018ca8c1003fd8 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 3 Apr 2021 22:41:26 +0300 Subject: [PATCH 3/8] Add check that chats aren't created before MessagesManager is inited. --- td/telegram/MessagesManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 9c3a9be12..d5dc8d544 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -33739,6 +33739,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, bool force_update_dialog_pos) { 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); if (d == nullptr) { LOG(INFO) << "Force create " << dialog_id << " from " << source; @@ -33829,6 +33830,7 @@ MessagesManager::Dialog *MessagesManager::add_dialog(DialogId dialog_id) { MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&d, bool is_loaded_from_database) { auto dialog_id = d->dialog_id; + LOG_CHECK(is_inited_) << dialog_id << ' ' << is_loaded_from_database; switch (dialog_id.get_type()) { case DialogType::User: if (dialog_id == get_my_dialog_id() && d->last_read_inbox_message_id == MessageId::max() && From 6285d98479cfbacd53b5c70e1dc433ab6dcaf182 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 4 Apr 2021 00:40:37 +0300 Subject: [PATCH 4/8] Fix writev on Windows. --- tdutils/td/utils/port/FileFd.cpp | 11 ++++++++++- tdutils/td/utils/port/IoSlice.h | 2 +- tdutils/td/utils/port/SocketFd.cpp | 6 +++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index d5c0db9dc..6b8ba9078 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -36,6 +36,8 @@ #include #include #include +#else +#include #endif #if TD_PORT_WINDOWS && defined(WIN32_LEAN_AND_MEAN) @@ -271,9 +273,16 @@ Result FileFd::writev(Span slices) { return OS_ERROR(PSLICE() << "Writev to " << get_native_fd() << " has failed"); #else size_t res = 0; - for (auto slice : slices) { + for (const auto &slice : slices) { + if (slice.size() > std::numeric_limits::max() - res) { + break; + } TRY_RESULT(size, write(slice)); res += size; + if (size != slice.size()) { + CHECK(size < slice.size()); + break; + } } return res; #endif diff --git a/tdutils/td/utils/port/IoSlice.h b/tdutils/td/utils/port/IoSlice.h index f1d356dd1..47fa230d8 100644 --- a/tdutils/td/utils/port/IoSlice.h +++ b/tdutils/td/utils/port/IoSlice.h @@ -25,7 +25,7 @@ inline IoSlice as_io_slice(Slice slice) { return res; } -inline Slice as_slice(const IoSlice io_slice) { +inline Slice as_slice(const IoSlice &io_slice) { return Slice(static_cast(io_slice.iov_base), io_slice.iov_len); } diff --git a/tdutils/td/utils/port/SocketFd.cpp b/tdutils/td/utils/port/SocketFd.cpp index 05e6aee4b..36719ef61 100644 --- a/tdutils/td/utils/port/SocketFd.cpp +++ b/tdutils/td/utils/port/SocketFd.cpp @@ -30,6 +30,8 @@ #include #include #include +#else +#include #endif #include @@ -98,7 +100,9 @@ class SocketFdImpl : private Iocp::Callback { Result writev(Span slices) { size_t total_size = 0; for (auto io_slice : slices) { - total_size += as_slice(io_slice).size(); + auto size = as_slice(io_slice).size(); + CHECK(size <= std::numeric_limits::max() - total_size); + total_size += size; } auto left_size = total_size; From e246201cf0fd77d106078ce253462fc03fee9396 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 4 Apr 2021 00:47:30 +0300 Subject: [PATCH 5/8] Add checks that FileFd::read/write/pread/pwrite/writev return correct response. --- tdutils/td/utils/port/FileFd.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 6b8ba9078..8ee8c4a40 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -256,7 +256,9 @@ Result FileFd::write(Slice slice) { BOOL success = WriteFile(native_fd, slice.data(), narrow_cast(slice.size()), &bytes_written, nullptr); #endif if (success) { - return narrow_cast(bytes_written); + auto result = narrow_cast(bytes_written); + CHECK(result <= slice.size()); + return result; } return OS_ERROR(PSLICE() << "Write to " << get_native_fd() << " has failed"); } @@ -268,7 +270,15 @@ Result FileFd::writev(Span slices) { auto bytes_written = detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), slices_size); }); bool success = bytes_written >= 0; if (success) { - return narrow_cast(bytes_written); + auto result = narrow_cast(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"); #else @@ -314,7 +324,9 @@ Result FileFd::read(MutableSlice slice) { if (is_eof) { get_poll_info().clear_flags(PollFlags::Read()); } - return static_cast(bytes_read); + auto result = narrow_cast(bytes_read); + CHECK(result <= slice.size()); + return result; } return OS_ERROR(PSLICE() << "Read from " << get_native_fd() << " has failed"); } @@ -338,7 +350,9 @@ Result FileFd::pwrite(Slice slice, int64 offset) { BOOL success = WriteFile(native_fd, slice.data(), narrow_cast(slice.size()), &bytes_written, &overlapped); #endif if (success) { - return narrow_cast(bytes_written); + auto result = narrow_cast(bytes_written); + CHECK(result <= slice.size()); + return result; } return OS_ERROR(PSLICE() << "Pwrite to " << get_native_fd() << " at offset " << offset << " has failed"); } @@ -361,7 +375,9 @@ Result FileFd::pread(MutableSlice slice, int64 offset) const { BOOL success = ReadFile(native_fd, slice.data(), narrow_cast(slice.size()), &bytes_read, &overlapped); #endif if (success) { - return narrow_cast(bytes_read); + auto result = narrow_cast(bytes_read); + CHECK(result <= slice.size()); + return result; } return OS_ERROR(PSLICE() << "Pread from " << get_native_fd() << " at offset " << offset << " has failed"); } From 2ab94b9ca75e0607b5384f04f0681213966547de Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 4 Apr 2021 01:08:53 +0300 Subject: [PATCH 6/8] Add checks that SocketFd::read/write/writev return correct response. --- tdutils/td/utils/port/SocketFd.cpp | 36 +++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/tdutils/td/utils/port/SocketFd.cpp b/tdutils/td/utils/port/SocketFd.cpp index 36719ef61..83d418a0c 100644 --- a/tdutils/td/utils/port/SocketFd.cpp +++ b/tdutils/td/utils/port/SocketFd.cpp @@ -18,6 +18,8 @@ #include "td/utils/port/detail/Iocp.h" #include "td/utils/SpinLock.h" #include "td/utils/VectorQueue.h" + +#include #endif #if TD_PORT_POSIX @@ -30,8 +32,6 @@ #include #include #include -#else -#include #endif #include @@ -403,7 +403,19 @@ class SocketFdImpl { return ::writev(native_fd, slices.begin(), slices_size); #endif }); - return write_finish(write_res); + if (write_res >= 0) { + auto result = narrow_cast(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 write(Slice slice) { @@ -416,15 +428,17 @@ class SocketFdImpl { ::write(native_fd, slice.begin(), slice.size()); #endif }); - return write_finish(write_res); + if (write_res >= 0) { + auto result = narrow_cast(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 write_finish(ssize_t write_res) { + Result write_finish() { auto write_errno = errno; - if (write_res >= 0) { - return narrow_cast(write_res); - } - if (write_errno == EAGAIN #if EAGAIN != EWOULDBLOCK || write_errno == EWOULDBLOCK @@ -472,7 +486,9 @@ class SocketFdImpl { get_poll_info().clear_flags(PollFlags::Read()); get_poll_info().add_flags(PollFlags::Close()); } - return narrow_cast(read_res); + auto result = narrow_cast(read_res); + CHECK(result <= slice.size()); + return result; } if (read_errno == EAGAIN #if EAGAIN != EWOULDBLOCK From 6dfe45c03c9b96da85e204a71ec76949fb24351d Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 4 Apr 2021 01:59:45 +0300 Subject: [PATCH 7/8] Fix unpinning of unknown chats. --- td/telegram/MessagesManager.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d5dc8d544..46e8ceb0e 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -14685,7 +14685,13 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector Date: Sun, 4 Apr 2021 02:58:59 +0300 Subject: [PATCH 8/8] Fix MoveFileExFromAppW. --- tdutils/td/utils/port/FromApp.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tdutils/td/utils/port/FromApp.h b/tdutils/td/utils/port/FromApp.h index bab7324a8..71cdfb9bb 100644 --- a/tdutils/td/utils/port/FromApp.h +++ b/tdutils/td/utils/port/FromApp.h @@ -76,11 +76,15 @@ inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) { } inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { - auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFileEx); - if (func != &MoveFileEx && (dwFlags & MOVEFILE_REPLACE_EXISTING) != 0) { + auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFile); + 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); } - return func(lpExistingFileName, lpNewFileName, dwFlags); + return func(lpExistingFileName, lpNewFileName); } inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId,