From 7e412d950af5ba5a3c5460320b36479a387e49bb Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 27 Oct 2026 17:42:52 +0100 Subject: [PATCH] Bind owned admin transfer requests to the selected database --- tools/chatgui/transport/gui_bridge_impl.cpp | 28 +++++++++++++++++++++ tools/chatgui/transport/member_edit.h | 4 +++ 2 files changed, 32 insertions(+) diff --git a/tools/chatgui/transport/gui_bridge_impl.cpp b/tools/chatgui/transport/gui_bridge_impl.cpp index 82da220a..b67a3fb7 100644 --- a/tools/chatgui/transport/gui_bridge_impl.cpp +++ b/tools/chatgui/transport/gui_bridge_impl.cpp @@ -227,6 +227,9 @@ bool gui_bridge_save_member(sqlite3* db, const QString& channel, quint64 node, c DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "member save: invalid GUI request/context"); return false; } const QByteArray id = channel.toLatin1(), nick = nickname.toUtf8(); + if (ownerJson.size() > 8192 || static_cast(nick.size()) + ownerJson.size() + sizeof(MemberEditRequest) + 2 > UINT32_MAX) { + DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "member save: snapshot exceeds allocation/JSON limit"); return false; + } bool valid = false; quint64 number = channel.toULongLong(&valid); if (!valid || !number || number > INT64_MAX || QString::number(number) != channel || !++member_sequence) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "member save: invalid channel or exhausted request ID"); return false; @@ -252,6 +255,31 @@ bool gui_bridge_save_member(sqlite3* db, const QString& channel, quint64 node, c return true; } +struct TransferAdminRequest { UTUN_INSTANCE* instance; sqlite3* database; uint64_t node; char channel[64]; }; +static void execute_transfer_admin(void* arg) { + auto* request = static_cast(arg); + if (chat_core_get_db(request->instance) == request->database) + chat_core_transfer_admin(request->instance, request->channel, request->node); + else DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: database changed"); + u_free(request); +} + +bool gui_bridge_transfer_admin(sqlite3* db, const QString& channel, quint64 node) { + bool valid = false; quint64 number = channel.toULongLong(&valid); + if (!db || !node || !valid || !number || number > INT64_MAX || QString::number(number) != channel) { + DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: invalid request"); return false; + } + std::lock_guard guard(bridge_mutex); + if (!g_inst || !g_ua) { DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: core unavailable"); return false; } + auto* request = static_cast(u_calloc(1, sizeof(TransferAdminRequest))); + if (!request) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: allocation failed"); return false; } + request->instance = g_inst; request->database = db; request->node = node; + const QByteArray id = channel.toLatin1(); memcpy(request->channel, id.constData(), id.size() + 1); + if (post_command(execute_transfer_admin, request, true) < 0) { u_free(request); return false; } + DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: queued ch=%s node=%016llx", id.constData(), (unsigned long long)node); + return true; +} + /* ── GuiBridgeReceiver implementation ── */ void GuiBridgeReceiver::processPost(int eventType, QByteArray data) { diff --git a/tools/chatgui/transport/member_edit.h b/tools/chatgui/transport/member_edit.h index a8a11f3d..2947e323 100644 --- a/tools/chatgui/transport/member_edit.h +++ b/tools/chatgui/transport/member_edit.h @@ -16,3 +16,7 @@ struct sqlite3; * Аргументы/ошибки логируются без ника, ключей и содержимого JSON. */ bool gui_bridge_save_member(sqlite3* db, const QString& channel, quint64 node, const QString& nickname, const QByteArray& ownerJson, QObject* context, std::function complete); + +/* GUI-only: скопировать команду передачи admin-ключа текущему ядру; db должен совпасть при выполнении. + * true — очередь приняла запрос, не подтверждение доставки ключа; false — отказ с логом без оставшейся памяти. */ +bool gui_bridge_transfer_admin(sqlite3* db, const QString& channel, quint64 node);