Browse Source

Verify large signed profiles alongside full owner records

master
evgeny 6 days ago
parent
commit
8fb9129300
  1. 2
      src/chat/member_sync.c
  2. 14
      tests/test_member_adapter.c
  3. 6
      tools/chatgui/tests/test_avatars.cpp

2
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;

14
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;

6
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)

Loading…
Cancel
Save