Check relative path limits and binding failures without truncation

This commit is contained in:
evgeny committed 2026-10-22 15:11:23 +02:00
1 parent f123a1bdeb
commit ec70908733
2 files changed
+13 -2

No files matched your search

+4 -2
View File
@@ -66,13 +66,15 @@ static int mi_location_valid(const char* location) {
}
int media_index_path(const char* base, const char* location, char path[MEDIA_PATH_MAX]) {
char clean[MEDIA_BASE_MAX];
char clean[MEDIA_BASE_MAX], full[MEDIA_PATH_MAX];
if (!path) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media_index path without output"); return -1; }
if (mi_clean_path(base, clean, sizeof(clean)) || mi_location_valid(location)) return -1;
int size = snprintf(path, MEDIA_PATH_MAX, "%s%s%s", clean, clean[strlen(clean) - 1] == '/' ? "" : "/", location);
int size = !strcmp(clean, ".") ? snprintf(full, sizeof(full), "%s", location)
: snprintf(full, sizeof(full), "%s%s%s", clean, clean[strlen(clean) - 1] == '/' ? "" : "/", location);
if (size >= MEDIA_PATH_MAX || size < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media_index joined path too long base=%s location=%s", clean, location); return -1;
}
memcpy(path, full, (size_t)size + 1);
return 0;
}
+9
View File
@@ -59,6 +59,9 @@ static void paths(void) {
assert(media_index_path(root, "a//file", path) == -1 && media_index_path(root, "a/./file", path) == -1);
assert(media_index_path(root, "C:/file", path) == -1 && media_index_path(root, "a\\file", path) == -1);
memset(relative, 'a', sizeof(relative)); relative[sizeof(relative) - 1] = 0;
assert(!media_index_path(".", relative, path) && strlen(path) == MEDIA_PATH_MAX - 1);
assert(!media_index_location(path, ".", relative) && strlen(relative) == MEDIA_PATH_MAX - 1);
assert(!media_index_path(".", relative, relative) && strlen(relative) == MEDIA_PATH_MAX - 1);
assert(media_index_path("/", relative, path) == -1);
relative[sizeof(relative) - 2] = 0;
assert(!media_index_path("/", relative, path) && strlen(path) == MEDIA_PATH_MAX - 1);
@@ -117,6 +120,12 @@ static void transactions(void) {
assert(scalar(db, "SELECT count(*) FROM media_files WHERE node_sign!=zeroblob(64)") == 2);
assert(media_index_register_downloaded(db, result.media_id, ids, result.content_hash, "conflict", "wrong", 1, 14, 7, 0, 0) == -1);
assert(scalar(db, "SELECT count(*) FROM media_files WHERE chat_id='1'") == 2);
sql(db, "DELETE FROM media_files");
char long_path[MEDIA_PATH_MAX], relative[301]; memset(relative, 'x', sizeof(relative) - 1); relative[300] = 0;
assert(!media_index_path(root, relative, long_path));
int previous_limit = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 200);
assert(commit(db, "1", long_path) == -1 && !scalar(db, "SELECT count(*) FROM media_files"));
sqlite3_limit(db, SQLITE_LIMIT_LENGTH, previous_limit);
result.num_blocks = INT_MAX;
assert(commit(db, "1", path) == -1); result.num_blocks = 2;
sqlite3_close(db);