Browse Source

Bound upload cache growth and reject stale transfer completions

master
evgeny 6 days ago
parent
commit
8b327a3f27
  1. 4
      src/chat/chat_profile.c
  2. 9
      tools/chatgui/src/avatars/avatarmanager.cpp
  3. 1
      tools/chatgui/tests/test_avatars.cpp

4
src/chat/chat_profile.c

@ -131,7 +131,9 @@ static int profile_update_channel(struct UTUN_INSTANCE* inst, const char* ch, in
uint64_t local_uts = 0; uint64_t local_uts = 0;
struct profile_json profile = { .text = "{", .used = 1, .avatar = avatar }; struct profile_json profile = { .text = "{", .used = 1, .avatar = avatar };
if (profile_pair(&profile, "name", inst->name) < 0) return -1; if (profile_pair(&profile, "name", inst->name) < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "profile: display name exceeds profile limit channel=%s", ch); return -1;
}
{ char q[256]; snprintf(q, sizeof(q), "SELECT update_ts,userinfo FROM \"%s\" WHERE node_id=?", tbl); { char q[256]; snprintf(q, sizeof(q), "SELECT update_ts,userinfo FROM \"%s\" WHERE node_id=?", tbl);
sqlite3_stmt* ps = NULL; sqlite3_stmt* ps = NULL;
if (sqlite3_prepare_v2(cc->db, q, -1, &ps, NULL) == SQLITE_OK) { if (sqlite3_prepare_v2(cc->db, q, -1, &ps, NULL) == SQLITE_OK) {

9
tools/chatgui/src/avatars/avatarmanager.cpp

@ -185,8 +185,11 @@ void AvatarManager::uploadDefault(const QString& source, quint64 server) {
if (!m_ready || m_preparing || !server || !gui_bridge_is_uasync_ready()) return; if (!m_ready || m_preparing || !server || !gui_bridge_is_uasync_ready()) return;
m_preparing = true; emit statusChanged(text("Preparing avatar…")); m_preparing = true; emit statusChanged(text("Preparing avatar…"));
const QString directory = m_directory; const quint64 generation = ++m_generation; cancelUploads(); const QString directory = m_directory; const quint64 generation = ++m_generation; cancelUploads();
m_pool.start(QRunnable::create([this, source, directory, server, generation] { QStringList pinned; if (!m_defaultHash.isEmpty()) pinned << m_defaultHash;
for (const auto& job : m_jobs) if (job.upload) pinned << job.ref.hash;
m_pool.start(QRunnable::create([this, source, directory, server, generation, pinned] {
const auto result = AvatarCache::prepare(source, directory); const auto result = AvatarCache::prepare(source, directory);
if (!result.image.isNull()) { auto keep = pinned; keep << result.hash; AvatarCache::prune(directory, keep); }
QMetaObject::invokeMethod(this, [this, result, server, generation] { QMetaObject::invokeMethod(this, [this, result, server, generation] {
m_preparing = false; m_preparing = false;
if (generation != m_generation) return; if (generation != m_generation) return;
@ -314,6 +317,10 @@ void AvatarManager::onTransfer(const uint8_t* data, int length) {
if (length != 51 || data[50] != 2) return; if (length != 51 || data[50] != 2) return;
const quint64 id = mf_get64(data); if (!m_jobs.contains(id)) return; const quint64 id = mf_get64(data); if (!m_jobs.contains(id)) return;
auto& job = m_jobs[id]; const int status = data[48] | (int(data[49]) << 8); auto& job = m_jobs[id]; const int status = data[48] | (int(data[49]) << 8);
if (job.stage != 99 || job.ref.group != mf_get64(data + 8) || job.ref.server != mf_get64(data + 16) ||
job.ref.owner != mf_get64(data + 24)) {
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "avatar: stale or mismatched transfer completion id=%llu", (unsigned long long)id); return;
}
if (status) { finish(id, status); return; } if (status) { finish(id, status); return; }
if (job.upload) { publish(job); return; } if (job.upload) { publish(job); return; }
const Job snapshot = job; const QString directory = m_directory; job.stage = 101; const Job snapshot = job; const QString directory = m_directory; job.stage = 101;

1
tools/chatgui/tests/test_avatars.cpp

@ -13,6 +13,7 @@ extern "C" {
#include "chat/chat_member.h" #include "chat/chat_member.h"
#include "chat/member_sync.h" #include "chat/member_sync.h"
#include "routing_layer/topo_group.h" #include "routing_layer/topo_group.h"
#include "routing_layer/topo_node_sqlite.h"
#include "member_files/member_files.h" #include "member_files/member_files.h"
#include "json_flat.h" #include "json_flat.h"
#include "mem.h" #include "mem.h"

Loading…
Cancel
Save