diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-24 05:29:39 +0200 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-24 05:29:39 +0200 |
| commit | 040c7eab81f8b1526841d3c8ce56e4912cae10f1 (patch) | |
| tree | 102d31b38c501350fc966bfe91df261ae3deee49 | |
| parent | 248bf17de8a25c741393b28e75c4e5380947792c (diff) | |
Fix: Stop treating an empty accesslist file as an error by allowing empty file pseudo mapping
| -rw-r--r-- | ot_accesslist.c | 44 |
1 files changed, 27 insertions, 17 deletions
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, | |||
| 124 | return count; | 124 | return count; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /* Map a file read only and report its size. Returns NULL if the file cannot | 127 | /* Map a file read only. Returns 0 and sets map and maplen on success, -1 if |
| 128 | be opened, is empty, or is too large to map, leaving maplen untouched. */ | 128 | the file cannot be opened or mapped. */ |
| 129 | static const char *accesslist_map(const char *filename, size_t *maplen) { | 129 | static int accesslist_map(const char *filename, const char **map, size_t *maplen) { |
| 130 | struct stat st; | 130 | struct stat st; |
| 131 | const char *map; | 131 | void *mapped; |
| 132 | int fd = open(filename, O_RDONLY); | 132 | int fd = open(filename, O_RDONLY); |
| 133 | 133 | ||
| 134 | if (fd < 0) | 134 | if (fd < 0) |
| 135 | return NULL; | 135 | return -1; |
| 136 | 136 | ||
| 137 | if (fstat(fd, &st) < 0 || st.st_size <= 0 || (uintmax_t)st.st_size > (uintmax_t)SIZE_MAX) { | 137 | if (fstat(fd, &st) < 0 || st.st_size < 0 || (uintmax_t)st.st_size > (uintmax_t)SIZE_MAX) { |
| 138 | close(fd); | 138 | close(fd); |
| 139 | return NULL; | 139 | return -1; |
| 140 | } | ||
| 141 | |||
| 142 | if (st.st_size == 0) { | ||
| 143 | close(fd); | ||
| 144 | *map = NULL; | ||
| 145 | *maplen = 0; | ||
| 146 | return 0; | ||
| 140 | } | 147 | } |
| 141 | 148 | ||
| 142 | map = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0); | 149 | mapped = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, fd, 0); |
| 143 | close(fd); | 150 | close(fd); |
| 144 | 151 | ||
| 145 | if (map == MAP_FAILED) | 152 | if (mapped == MAP_FAILED) |
| 146 | return NULL; | 153 | return -1; |
| 147 | 154 | ||
| 155 | *map = mapped; | ||
| 148 | *maplen = (size_t)st.st_size; | 156 | *maplen = (size_t)st.st_size; |
| 149 | return map; | 157 | return 0; |
| 150 | } | 158 | } |
| 151 | 159 | ||
| 152 | static void accesslist_readfile(void) { | 160 | static void accesslist_readfile(void) { |
| @@ -154,7 +162,7 @@ static void accesslist_readfile(void) { | |||
| 154 | const char *map; | 162 | const char *map; |
| 155 | size_t maplen, capacity, found; | 163 | size_t maplen, capacity, found; |
| 156 | 164 | ||
| 157 | if ((map = accesslist_map(g_accesslist_filename, &maplen)) == NULL) { | 165 | if (accesslist_map(g_accesslist_filename, &map, &maplen) < 0) { |
| 158 | char *wd = getcwd(NULL, 0); | 166 | char *wd = getcwd(NULL, 0); |
| 159 | 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); | 167 | 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); |
| 160 | free(wd); | 168 | free(wd); |
| @@ -166,16 +174,18 @@ static void accesslist_readfile(void) { | |||
| 166 | accesslist_new = accesslist_make(g_accesslist, capacity); | 174 | accesslist_new = accesslist_make(g_accesslist, capacity); |
| 167 | if (!accesslist_new) { | 175 | if (!accesslist_new) { |
| 168 | fprintf(stderr, "Warning: Not enough memory to allocate %zd bytes for accesslist buffer. May succeed later.\n", capacity * sizeof(ot_hash)); | 176 | fprintf(stderr, "Warning: Not enough memory to allocate %zd bytes for accesslist buffer. May succeed later.\n", capacity * sizeof(ot_hash)); |
| 169 | munmap((void *)map, maplen); | 177 | if (map) |
| 178 | munmap((void *)map, maplen); | ||
| 170 | return; | 179 | return; |
| 171 | } | 180 | } |
| 172 | 181 | ||
| 173 | found = accesslist_parse_hashes(accesslist_new->list, capacity, map, maplen); | 182 | found = maplen ? accesslist_parse_hashes(accesslist_new->list, capacity, map, maplen) : 0; |
| 174 | #ifdef _DEBUG | 183 | #ifdef _DEBUG |
| 175 | fprintf(stderr, "Added %zd info_hashes to accesslist\n", found); | 184 | fprintf(stderr, "Added %zd info_hashes to accesslist\n", found); |
| 176 | #endif | 185 | #endif |
| 177 | 186 | ||
| 178 | munmap((void *)map, maplen); | 187 | if (map) |
| 188 | munmap((void *)map, maplen); | ||
| 179 | 189 | ||
| 180 | qsort(accesslist_new->list, found, sizeof(ot_hash), vector_compare_hash); | 190 | qsort(accesslist_new->list, found, sizeof(ot_hash), vector_compare_hash); |
| 181 | accesslist_new->size = found; | 191 | accesslist_new->size = found; |
