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:
M | dir2list.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++) {