dir2list

generate a list of files shuffled by directory
git clone anongit@rnpnr.xyz:dir2list.git
Log | Files | Refs | Feed | README | LICENSE

Commit: d2f205d03e38f3fc7408b546653b4335b5984fd5
Parent: 6fc13c8a0dc3bf8d368d5612f5e6c3db3f59902e
Author: 0x766F6964
Date:   Tue,  5 May 2020 13:31:51 -0600

add reallocarray() and use it to simplify file list creation

this also added bounds checking on the multiplication

Diffstat:
Mdir2list.c | 43++++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/dir2list.c b/dir2list.c @@ -1,6 +1,7 @@ #include <dirent.h> #include <stdarg.h> #include <stdio.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> @@ -8,6 +9,9 @@ #include "config.h" +/* sqrt(SIZE_MAX + 1): for (a < this; b < this) a * b <= SIZE_MAX */ +#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) + struct node { char *path; /* Path containing media files */ int a; /* Applied */ @@ -51,6 +55,16 @@ xmalloc(size_t s) return p; } +static void * +reallocarray(void *p, size_t n, size_t s) +{ + if ((n >= MUL_NO_OVERFLOW || s >= MUL_NO_OVERFLOW) + && n > 0 && SIZE_MAX / n < s) + die("reallocarray(): Out of Memory\n"); + + return realloc(p, n * s); +} + static int namecmp(const void *va, const void *vb) { @@ -85,7 +99,7 @@ addfiles(const char *path, struct list *list) { DIR *dir; struct dirent *dent; - struct entry *fents; + struct entry *fents = NULL; char *s; int i; size_t len, n = 0; @@ -93,35 +107,22 @@ addfiles(const char *path, struct list *list) if (!(dir = opendir(path))) die("opendir(): failed to open: %s\n", path); - while ((dent = readdir(dir))) - if (valid_file(dent->d_name)) - n++; - - if (!n) { - closedir(dir); - return list; - } - - rewinddir(dir); - - fents = xmalloc(sizeof(struct entry) * n); - - for (i = 0; i < n;) { - if (!(dent = readdir(dir))) - die("readdir(): end of dir: %s\n", path); - + while ((dent = readdir(dir))) { if (!valid_file(dent->d_name)) continue; + fents = reallocarray(fents, n + 1, sizeof(struct entry)); + len = strlen(path) + strlen(dent->d_name) + 2; s = xmalloc(len); snprintf(s, len, "%s/%s", path, dent->d_name); - fents[i].name = s; - - i++; + fents[n++].name = s; } closedir(dir); + if (!n) + return list; + qsort(fents, n, sizeof(struct entry), namecmp); for (i = 0; i < n; i++) {