Release v2.26.0 #284

Merged
TapTap merged 210 commits from dev into main 2026-09-18 19:05:52 +02:00
Showing only changes of commit dbf1b39d47 - Show all commits
+11 -8
View File
@@ -435,20 +435,22 @@ static bool valid_name(const char* value) {
strchr(value, '/') == NULL; strchr(value, '/') == NULL;
} }
static bool read_section(int fd, ArrayList* list, bool rel_path) { /* Read one count-prefixed section. `bytes` is the running per-frame budget,
* shared across every section of the frame so a hostile peer cannot retain more
* than MAX_MANIFEST_BYTES from one STATUS_DELETE_PLAN frame. */
static bool read_section(int fd, ArrayList* list, bool rel_path, size_t* bytes) {
int count; int count;
if (!receive_int(fd, &count) || count < 0 || count > MAX_MANIFEST_ENTRIES) if (!receive_int(fd, &count) || count < 0 || count > MAX_MANIFEST_ENTRIES)
return false; return false;
size_t bytes = 0;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
char* value = receive_wire_str(fd); char* value = receive_wire_str(fd);
bool ok = value && (rel_path ? valid_rel_path(value) : valid_name(value)); bool ok = value && (rel_path ? valid_rel_path(value) : valid_name(value));
if (ok) { if (ok) {
size_t entry_size = strlen(value) + sizeof(char*) + 16; size_t entry_size = strlen(value) + sizeof(char*) + 16;
if (entry_size > MAX_MANIFEST_BYTES - bytes) { if (entry_size > MAX_MANIFEST_BYTES - *bytes) {
ok = false; ok = false;
} else { } else {
bytes += entry_size; *bytes += entry_size;
ok = array_list_add(list, value); ok = array_list_add(list, value);
} }
} }
@@ -747,10 +749,11 @@ int delete_plan_session_receive(DeletePlanSession* session, const Config* config
send_status(fd, STATUS_ERROR); send_status(fd, STATUS_ERROR);
return -1; return -1;
} }
size_t bytes = 0;
if (has_config) { if (has_config) {
if (session->config_seen || !read_section(fd, session->protected_prefixes, true) || if (session->config_seen || !read_section(fd, session->protected_prefixes, true, &bytes) ||
!read_section(fd, session->size_skipped, true) || !read_section(fd, session->size_skipped, true, &bytes) ||
!read_section(fd, session->missing, true)) { !read_section(fd, session->missing, true, &bytes)) {
send_status(fd, STATUS_ERROR); send_status(fd, STATUS_ERROR);
return -1; return -1;
} }
@@ -760,7 +763,7 @@ int delete_plan_session_receive(DeletePlanSession* session, const Config* config
ArrayList* dirs = array_list_create(free); ArrayList* dirs = array_list_create(free);
ArrayList* files = array_list_create(free); ArrayList* files = array_list_create(free);
bool parsed = dir && (strcmp(dir, ".") == 0 || valid_rel_path(dir)) && dirs && files && bool parsed = dir && (strcmp(dir, ".") == 0 || valid_rel_path(dir)) && dirs && files &&
read_section(fd, dirs, false) && read_section(fd, files, false); read_section(fd, dirs, false, &bytes) && read_section(fd, files, false, &bytes);
if (!parsed) { if (!parsed) {
free(dir); free(dir);
array_list_delete(dirs); array_list_delete(dirs);