media_download: fix md_mkdir_parent for Windows (drive letter, backslash), add errno to fopen errors, sanitize base_filename with WARNING
This commit is contained in:
1 parent
cf1843e586
commit
fa5878ef4b
3 files changed
+31
-8
No files matched your search
+22
-4
@@ -434,6 +434,22 @@ static void md_download_done_cb(void* arg, int err) {
|
||||
u_free(ctx);
|
||||
}
|
||||
|
||||
static void sanitize_filename(char* buf, size_t size) {
|
||||
char orig[256]; snprintf(orig, sizeof(orig), "%s", buf);
|
||||
size_t w = 0;
|
||||
for (size_t r = 0; buf[r]; r++) {
|
||||
char c = buf[r];
|
||||
if ((unsigned char)c < 0x20) continue;
|
||||
if (c == '/' || c == '\\' || c == ':' || c == '*' || c == '?'
|
||||
|| c == '"' || c == '<' || c == '>' || c == '|') continue;
|
||||
if (w < size - 1) buf[w++] = c;
|
||||
}
|
||||
buf[w] = '\0';
|
||||
if (w == 0) snprintf(buf, size, "file");
|
||||
if (strcmp(orig, buf) != 0)
|
||||
DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "%s: filename sanitized [%s] -> [%s]", CC_ID, orig, buf);
|
||||
}
|
||||
|
||||
static int md_start_download(struct UTUN_INSTANCE* inst,
|
||||
const char* data_str, size_t data_len,
|
||||
const char* ch_id, const char* base_filename,
|
||||
@@ -503,8 +519,8 @@ static int md_start_download(struct UTUN_INSTANCE* inst,
|
||||
snprintf(ctx->dest_relpath, sizeof(ctx->dest_relpath), "%s", fp_name);
|
||||
if (author_sig) memcpy(ctx->author_sig, author_sig, 64);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "%s: download start ch=%s media=%02x%02x... blocks=%d size=%lld dest=%s",
|
||||
CC_ID, ch_id, result.media_id[0], result.media_id[1], nb, (long long)fsize, dest);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "%s: download start ch=%s file=%s blocks=%d size=%lld dest=%s",
|
||||
CC_ID, ch_id, base_filename, nb, (long long)fsize, dest);
|
||||
media_download_start(inst, 0, &result, dest, media_base, author_node_id, md_download_done_cb, ctx, md_download_progress_cb, ctx);
|
||||
media_index_result_free(&result);
|
||||
return 0;
|
||||
@@ -561,9 +577,10 @@ void on_msg_inserted(struct DB_SYNC_INSTANCE* si, uint64_t record_ts, const char
|
||||
uint8_t dec[256]; int dlen = (int)b64_decode(base_filename + 1, bfi - 1, dec, sizeof(dec));
|
||||
if (dlen > 0 && dlen < (int)sizeof(base_filename)) { memcpy(base_filename, dec, (size_t)dlen); base_filename[dlen] = '\0'; }
|
||||
}
|
||||
if (bfi == 0) snprintf(base_filename, sizeof(base_filename), "file");
|
||||
if (bfi == 0) snprintf(base_filename, sizeof(base_filename), "file");
|
||||
sanitize_filename(base_filename, sizeof(base_filename));
|
||||
|
||||
const uint8_t* sig_field = (const uint8_t*)strstr(buf, "\"sig\":\"");
|
||||
const uint8_t* sig_field = (const uint8_t*)strstr(buf, "\"sig\":\"");
|
||||
uint8_t author_sig[64] = {0};
|
||||
if (sig_field) {
|
||||
/* read author_signature from DB — find by ts in on_msg_inserted we don't have sig
|
||||
@@ -647,6 +664,7 @@ void chat_core_attachment_download(const char* channel_id, int64_t msg_id) {
|
||||
if (dlen > 0 && dlen < (int)sizeof(base_filename)) { memcpy(base_filename, dec, (size_t)dlen); base_filename[dlen] = '\0'; }
|
||||
}
|
||||
if (bfi == 0) snprintf(base_filename, sizeof(base_filename), "file");
|
||||
sanitize_filename(base_filename, sizeof(base_filename));
|
||||
|
||||
uint8_t author_sig[64]; memcpy(author_sig, sig_blob, 64);
|
||||
sqlite3_finalize(st);
|
||||
|
||||
@@ -45,8 +45,11 @@ static void md_dl_free(struct media_download* dl) {
|
||||
|
||||
static void md_mkdir_parent(const char* filepath) {
|
||||
char path[1024]; snprintf(path, sizeof(path), "%s", filepath);
|
||||
char* p = path[0] == '/' ? path + 1 : path;
|
||||
while ((p = strchr(p, '/'))) {
|
||||
char* p = path;
|
||||
if (((p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z')) && p[1] == ':')
|
||||
p += 2;
|
||||
while (*p == '/' || *p == '\\') p++;
|
||||
while ((p = strpbrk(p, "/\\"))) {
|
||||
*p = '\0';
|
||||
if (utun_mkdir(path, 0755) != 0 && errno != EEXIST) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: mkdir(%s) failed: %s", MDL_ID, path, strerror(errno));
|
||||
@@ -381,7 +384,7 @@ void media_download_handle_chunk(struct UTUN_INSTANCE* inst,
|
||||
char tmp[2048];
|
||||
snprintf(tmp, sizeof(tmp), "%s.chunk_%d", dl->dest_path, bi);
|
||||
FILE* f = fopen(tmp, "ab");
|
||||
if (!f) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: fopen(%s) failed for chunk write", MDL_ID, tmp); return; }
|
||||
if (!f) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: fopen(%s) failed for chunk write: %s", MDL_ID, tmp, strerror(errno)); return; }
|
||||
size_t wlen = ch->data_len;
|
||||
if (len >= MEDIA_BLOCK_CHUNK_HDR_SIZE + wlen) {
|
||||
fwrite(d + MEDIA_BLOCK_CHUNK_HDR_SIZE, 1, wlen, f);
|
||||
@@ -540,7 +543,7 @@ void media_download_handle_done(struct UTUN_INSTANCE* inst,
|
||||
if (dl->blocks_validated == dl->num_blocks) {
|
||||
/* assemble file */
|
||||
FILE* out = fopen(dl->dest_path, "wb");
|
||||
if (!out) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: fopen(%s) failed for assembly", MDL_ID, dl->dest_path); }
|
||||
if (!out) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: fopen(%s) failed for assembly: %s", MDL_ID, dl->dest_path, strerror(errno)); }
|
||||
else {
|
||||
for (int n = 0; n < dl->num_blocks; n++) {
|
||||
char tmp2[2048];
|
||||
|
||||
Reference in new issue
Block a user