From 040c7eab81f8b1526841d3c8ce56e4912cae10f1 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Sat, 24 Oct 2026 05:29:39 +0200 Subject: Fix: Stop treating an empty accesslist file as an error by allowing empty file pseudo mapping --- ot_accesslist.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'ot_accesslist.c') diff --git a/ot_accesslist.c b/ot_accesslist.c index 6315bc2..a199fa4 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c @@ -124,29 +124,37 @@ size_t accesslist_parse_hashes(ot_hash *dest, size_t capacity, const char *buf, return count; } -/* Map a file read only and report its size. Returns NULL if the file cannot - be opened, is empty, or is too large to map, leaving maplen untouched. */ -static const char *accesslist_map(const char *filename, size_t *maplen) { - struct stat st; - const char *map; - int fd = open(filename, O_RDONLY); +/* Map a file read only. Returns 0 and sets map and maplen on success, -1 if + the file cannot be opened or mapped. */ +static int accesslist_map(const char *filename, const char **map, size_t *maplen) { + struct stat st; + void *mapped; + int fd = open(filename, O_RDONLY); if (fd < 0) - return NULL; + return -1; - if (fstat(fd, &st) < 0 || st.st_size <= 0 || (uintmax_t)st.st_size > (uintmax_t)SIZE_MAX) { + if (fstat(fd, &st) < 0 || st.st_size < 0 || (uintmax_t)st.st_size > (uintmax_t)SIZE_MAX) { close(fd); - return NULL; + return -1; + } + + if (st.st_size == 0) { + close(fd); + *map = NULL; + *maplen = 0; + return 0; } - map = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0); + mapped = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); - if (map == MAP_FAILED) - return NULL; + if (mapped == MAP_FAILED) + return -1; + *map = mapped; *maplen = (size_t)st.st_size; - return map; + return 0; } static void accesslist_readfile(void) { @@ -154,7 +162,7 @@ static void accesslist_readfile(void) { const char *map; size_t maplen, capacity, found; - if ((map = accesslist_map(g_accesslist_filename, &maplen)) == NULL) { + if (accesslist_map(g_accesslist_filename, &map, &maplen) < 0) { char *wd = getcwd(NULL, 0); fprintf(stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).\nPWD: %s\n", g_accesslist_filename, wd); free(wd); @@ -166,16 +174,18 @@ static void accesslist_readfile(void) { accesslist_new = accesslist_make(g_accesslist, capacity); if (!accesslist_new) { fprintf(stderr, "Warning: Not enough memory to allocate %zd bytes for accesslist buffer. May succeed later.\n", capacity * sizeof(ot_hash)); - munmap((void *)map, maplen); + if (map) + munmap((void *)map, maplen); return; } - found = accesslist_parse_hashes(accesslist_new->list, capacity, map, maplen); + found = maplen ? accesslist_parse_hashes(accesslist_new->list, capacity, map, maplen) : 0; #ifdef _DEBUG fprintf(stderr, "Added %zd info_hashes to accesslist\n", found); #endif - munmap((void *)map, maplen); + if (map) + munmap((void *)map, maplen); qsort(accesslist_new->list, found, sizeof(ot_hash), vector_compare_hash); accesslist_new->size = found; -- cgit v1.3