Use the signed-history limit for manual attachment parsing
This commit is contained in:
1 parent
67368ebbac
commit
00c4065771
2 files changed
+15
-14
No files matched your search
+8
-10
@@ -1124,7 +1124,7 @@ void chat_core_attachment_download(struct UTUN_INSTANCE* inst, const char* chann
|
||||
const uint8_t* sig_blob = (const uint8_t*)sqlite3_column_blob(st, 2);
|
||||
int sig_len = sqlite3_column_bytes(st, 2);
|
||||
int64_t author_node_id = sqlite3_column_int64(st, 3);
|
||||
if (!jdata || jlen <= 0 || !sig_blob || sig_len != 64) {
|
||||
if (!jdata || jlen <= 0 || jlen > DB_SYNC_MESSAGE_MAX || !sig_blob || sig_len != 64) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: download bad msg data ch=%s id=%lld", CC_ID, channel_id, (long long)msg_id);
|
||||
sqlite3_finalize(st);
|
||||
return;
|
||||
@@ -1134,11 +1134,10 @@ void chat_core_attachment_download(struct UTUN_INSTANCE* inst, const char* chann
|
||||
if (!ds) { DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "manual media download: missing body ch=%s", channel_id); sqlite3_finalize(st); return; }
|
||||
const char* d_start = ds + 5;
|
||||
const char* d_end = strchr(d_start, '"');
|
||||
if (!d_end || d_end - d_start > 65536) {
|
||||
if (!d_end || d_end - d_start > DB_SYNC_MESSAGE_MAX) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "manual media download: invalid body length ch=%s", channel_id); sqlite3_finalize(st); return;
|
||||
}
|
||||
size_t bi = (size_t)(d_end - d_start); char* body = u_malloc(bi + 1);
|
||||
if (!body) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "manual media download: body allocation failed bytes=%zu", bi); sqlite3_finalize(st); return; }
|
||||
size_t bi = (size_t)(d_end - d_start); char body[DB_SYNC_MESSAGE_MAX + 1];
|
||||
memcpy(body, d_start, bi); body[bi] = 0;
|
||||
|
||||
char content_type[32] = {0};
|
||||
@@ -1163,16 +1162,16 @@ void chat_core_attachment_download(struct UTUN_INSTANCE* inst, const char* chann
|
||||
if (observed) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "manual encrypted download: cannot index manifest ch=%s result=%d", channel_id, observed);
|
||||
if (observed == -1) media_queue_channel_backfill(inst, channel_id);
|
||||
sqlite3_finalize(st); u_free(body); return;
|
||||
sqlite3_finalize(st); return;
|
||||
}
|
||||
}
|
||||
int final_rc = sqlite3_finalize(st);
|
||||
if (final_rc != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "manual media download: history finalize failed ch=%s rc=%d", channel_id, final_rc); u_free(body); return;
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "manual media download: history finalize failed ch=%s rc=%d", channel_id, final_rc); return;
|
||||
}
|
||||
|
||||
if (encrypted_attachment) {
|
||||
if (chat_attachment_want(inst, channel_id, message)) { u_free(body); return; }
|
||||
if (chat_attachment_want(inst, channel_id, message)) return;
|
||||
sqlite3_stmt* encrypted = NULL;
|
||||
int rc = sqlite3_prepare_v2(cc->db, "SELECT cipher_path FROM attachment_keys WHERE channel=? AND message_id=? AND downloaded=1",
|
||||
-1, &encrypted, NULL);
|
||||
@@ -1184,11 +1183,11 @@ void chat_core_attachment_download(struct UTUN_INSTANCE* inst, const char* chann
|
||||
int finish = sqlite3_finalize(encrypted);
|
||||
if ((rc != SQLITE_ROW && rc != SQLITE_DONE) || finish != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted media: local file lookup failed ch=%s step=%d finalize=%d db=%s",
|
||||
channel_id, rc, finish, sqlite3_errmsg(cc->db)); u_free(body); return;
|
||||
channel_id, rc, finish, sqlite3_errmsg(cc->db)); return;
|
||||
}
|
||||
if (present) {
|
||||
if (chat_attachment_downloaded(inst, channel_id, message, 0)) media_queue_channel_backfill(inst, channel_id);
|
||||
u_free(body); return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1199,7 +1198,6 @@ void chat_core_attachment_download(struct UTUN_INSTANCE* inst, const char* chann
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "%s: manual download ch=%s id=%lld ct=%s file=%s",
|
||||
CC_ID, channel_id, (long long)msg_id, content_type, base_filename);
|
||||
md_start_download(inst, body, bi, channel_id, base_filename, (uint64_t)db_ts, author_sig, (uint64_t)author_node_id, msg_id, content_type);
|
||||
u_free(body);
|
||||
}
|
||||
|
||||
static void chat_core_attachment_download_trampoline_impl(void* arg) {
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/sha.h>
|
||||
#include "../src/utun_instance.h"
|
||||
#include "../src/chat/chat_core.h"
|
||||
#include "../src/chat/chat_attachment.h"
|
||||
#include "../src/chat/chat_core_priv.h"
|
||||
#include "../src/chat/chat_event.h"
|
||||
#include "../src/chat/chat_feedback.h"
|
||||
#include "../src/media_async/media_async.h"
|
||||
#include "../src/media_delivery/media_download.h"
|
||||
#include "../src/media_delivery/media_index.h"
|
||||
#include "../lib/platform_compat.h"
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../lib/mem.h"
|
||||
@@ -970,7 +973,7 @@ int __wrap_media_download_start(struct UTUN_INSTANCE* inst, uint64_t group, cons
|
||||
}
|
||||
|
||||
static void test_long_manual_manifest(void) {
|
||||
struct fixture f; setup(&f); enum { BLOCKS = 30 };
|
||||
struct fixture f; setup(&f); enum { BLOCKS = 23 };
|
||||
uint8_t content[BLOCKS], ids[BLOCKS * 16], signatures[BLOCKS * 64];
|
||||
struct media_index_result result = {.file_size = BLOCKS, .block_size = 1, .num_blocks = BLOCKS, .block_ids = ids, .block_sigs = signatures};
|
||||
result.media_id[0] = 99; memset(ids, 0, sizeof(ids));
|
||||
@@ -993,10 +996,10 @@ static void test_long_manual_manifest(void) {
|
||||
for (unsigned i = 0; i < 64; i++) offset += (size_t)snprintf(body + offset, sizeof(body) - offset, "%02x", signatures[block * 64 + i]);
|
||||
assert(offset < sizeof(body));
|
||||
}
|
||||
body[offset] = 0; assert(offset > 4096);
|
||||
body[offset] = 0; assert(offset > 3000);
|
||||
char json[6500]; int length = snprintf(json, sizeof(json), "{\"n\":%llu,\"ch\":\"%s\",\"ct\":\"application/octet-stream\",\"d\":\"%s\"}",
|
||||
(unsigned long long)f.inst->node_id, f.channel, body);
|
||||
assert(length > 0 && (size_t)length < sizeof(json));
|
||||
assert(length > 0 && length <= DB_SYNC_MESSAGE_MAX && (size_t)length < sizeof(json));
|
||||
struct DB_SYNC_INSTANCE* si = si_find(f.inst, f.channel); assert(si);
|
||||
uint64_t timestamp = db_sync_next_timestamp(si); struct db_message_revision revision = {.ver = 1}; revision.nonce[0] = 33;
|
||||
uint8_t signature[64], message[32];
|
||||
@@ -1010,7 +1013,7 @@ static void test_long_manual_manifest(void) {
|
||||
int64_t id = sqlite3_column_int64(st, 0); assert(sqlite3_finalize(st) == SQLITE_OK);
|
||||
expected_download = &result; download_starts = 0; chat_core_attachment_download(f.inst, f.channel, id);
|
||||
assert(download_starts == 1); expected_download = NULL; cleanup(&f);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS manual manifest:%zu bytes, all30 signed blocks reach download port; rejected start frees context", offset);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS manual manifest:%zu bytes, all23 signed blocks near protocol limit reach download port; rejected start frees context", offset);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
Reference in new issue
Block a user