diff --git a/src/chat/member_sync.c b/src/chat/member_sync.c index a412feec..28f405a1 100644 --- a/src/chat/member_sync.c +++ b/src/chat/member_sync.c @@ -935,7 +935,7 @@ static int _member_apply_items(void* ctx, const char* ns, uint64_t from_peer, co DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: invalid member page ns=%s bytes=%zu", MS_ID, ns, len); return MT_ERR_DATA; } uint16_t count = ((uint16_t)data[0] << 8) | data[1]; - if (count > (len - 2) / 284) { + if (count > (len - 2) / 285) { DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: impossible page count=%u bytes=%zu", MS_ID, count, len); return MT_ERR_DATA; } size_t off = 2; diff --git a/tests/test_member_adapter.c b/tests/test_member_adapter.c index a1a93610..21b5b3bc 100644 --- a/tests/test_member_adapter.c +++ b/tests/test_member_adapter.c @@ -32,16 +32,25 @@ static void test_owner_sizes(struct UASYNC* ua) { assert(topo_node_sqlite_channel_put(source.topo_sqlite_db, "1001", "test", 1, x, NULL, owner_pub, owner_priv, zero) == 0); assert(topo_node_sqlite_channel_put(target.topo_sqlite_db, "1001", "test", 1, x, NULL, owner_pub, NULL, zero) == 0); uint64_t nid = sc_derive_node_id_from_pubkey(x); - uint8_t join[64], tree[64], owner[64], msg[MS_ADM_TAGS_MAX + 8]; + uint8_t join[64], tree[64], owner[64], update[64], msg[MS_ADM_TAGS_MAX + 8]; int n = member_sync_build_join_msg(x, owner_pub, nid, x, 1, msg, sizeof(msg)); assert(n > 0); assert(sc_ed25519_sign(priv, msg, n, join) == SC_OK); assert(member_sync_sign_pubkey(owner_priv, x, tree) == 0); char tags[MS_ADM_TAGS_MAX + 2]; + char userinfo[MS_USERINFO_MAX + 1]; struct ms_member_rec rec = { .node_id = nid, .x25519 = x, .ed25519 = pub, - .join_sig = join, .join_ts = 1, .userinfo = "", .adm_tags = tags, .adm_tags_sig = owner, .signature = tree }; + .join_sig = join, .join_ts = 1, .userinfo = userinfo, .update_sig = update, + .adm_tags = tags, .adm_tags_sig = owner, .signature = tree }; const size_t sizes[] = {191, 192, 255, 256, 4096, MS_ADM_TAGS_MAX}; uint8_t page[MT_PAGE_SIZE], expected[32], actual[32]; for (size_t i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++) { + const size_t profile_sizes[] = {191, 255, 256, 512, 1023, MS_USERINFO_MAX}; + int head = snprintf(userinfo, sizeof(userinfo), "{\"name\":\"avatar\",\"pad\":\""); + size_t end = profile_sizes[i] - 2; + memset(userinfo + head, 'p', end - head); memcpy(userinfo + end, "\"}", 3); + rec.update_ts = i + 1; + n = member_sync_build_update_msg(join, rec.update_ts, userinfo, msg, sizeof(msg)); assert(n > 0); + assert(sc_ed25519_sign(priv, msg, n, update) == SC_OK); size_t len = sizes[i]; int prefix = snprintf(tags, sizeof(tags), "{\"ver\":\"%zu\",\"pad\":\"", i + 1); const char* suffix = "\",\"storage\":\"yes\"}"; @@ -56,6 +65,7 @@ static void test_owner_sizes(struct UASYNC* ua) { assert(next == nid && !more && bytes < MT_PAGE_SIZE); struct member_wire w; size_t used; assert(member_decode(page + 2, bytes - 2, &w, &used) == 0 && used == bytes - 2 && !strcmp(w.rec.adm_tags, tags)); + assert(!strcmp(w.rec.userinfo, userinfo)); assert(_member_apply_items(&target, "1001", 2, page, bytes) == 0); root(&source, expected); root(&target, actual); assert(!memcmp(expected, actual, 32)); sqlite3_stmt* st; diff --git a/tools/chatgui/tests/test_avatars.cpp b/tools/chatgui/tests/test_avatars.cpp index ce6e1731..e7d5d8b0 100644 --- a/tools/chatgui/tests/test_avatars.cpp +++ b/tools/chatgui/tests/test_avatars.cpp @@ -26,7 +26,7 @@ extern "C" void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg) { if (fn == member_files_gui_transfer && !((mf_transfer_request*)arg)->upload) downloads++; uasync_call_soon(testInstance->ua, arg, fn); } -static void event(UTUN_INSTANCE*, int type, const uint8_t* data, int length) { +static void avatarEvent(UTUN_INSTANCE*, int type, const uint8_t* data, int length) { auto* manager = AvatarManager::instance(); if (!manager) return; if (type == CHAT_EVT_MEMBER_FILES_RESPONSE) manager->onResponse(data, length); if (type == CHAT_EVT_MEMBER_FILES_TRANSFER) manager->onTransfer(data, length); @@ -82,7 +82,7 @@ private slots: chat_member_tags_free(tags); } QTimer poll; connect(&poll, &QTimer::timeout, this, [ua] { uasync_poll(ua, 0); }); poll.start(1); - chat_event_set_handler(testInstance, event); + chat_event_set_handler(testInstance, avatarEvent); const QString source = directory.path() + "/photo.png"; QImage image(300, 200, QImage::Format_RGB32); image.fill(Qt::blue); QVERIFY(image.save(source)); QString cached; @@ -130,7 +130,7 @@ private slots: } } poll.stop(); chat_event_set_handler(testInstance, nullptr); db.setDb(nullptr); - utun_instance_destroy(testInstance); testInstance = nullptr; uasync_destroy(ua); + utun_instance_destroy(testInstance); testInstance = nullptr; uasync_destroy(ua, 0); } }; QTEST_MAIN(AvatarTest)