summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMichael Smith <mikesmiffy128@gmail.com>2022-05-16 20:23:39 +0100
committerMichael Smith <mikesmiffy128@gmail.com>2022-05-16 20:23:39 +0100
commite8843dba3eb1c7a67f6ff7b920046ae36a12acd0 (patch)
treeaa1ecd11a720ba66508000b2cdd08fa09ed4b4ac
parent9009f75bf5fd33e13abae5762d31968b39f233c3 (diff)
Make the demo directory check more robust
This is how it should've been to begin with, but I was lazy.
-rw-r--r--src/demorec.c28
-rw-r--r--src/os-win32.h3
-rw-r--r--src/os.h1
3 files changed, 28 insertions, 4 deletions
diff --git a/src/demorec.c b/src/demorec.c
index 2108436..c8871bd 100644
--- a/src/demorec.c
+++ b/src/demorec.c
@@ -88,7 +88,8 @@ static void hook_record_cb(const struct con_cmdargs *args) {
bool was = *recording;
if (!was && args->argc == 2 || args->argc == 3) {
// safety check: make sure a directory exists, otherwise recording
- // silently fails
+ // silently fails. this is necessarily TOCTOU, but in practice it's
+ // way better than not doing it - just to have a sanity check.
const char *arg = args->argv[1];
const char *lastslash = 0;
for (const char *p = arg; *p; ++p) {
@@ -111,9 +112,28 @@ static void hook_record_cb(const struct con_cmdargs *args) {
*q = (uchar)*p;
}
q[argdirlen] = OS_LIT('\0');
- if (os_access(dir, X_OK) == -1) {
- con_warn("ERROR: can't record demo: subdirectory %.*s "
- "doesn't exist\n", argdirlen, arg);
+ // this is pretty ugly. the error cases would be way tidier if
+ // we could use open(O_DIRECTORY), but that's not a thing on
+ // windows, of course.
+ struct os_stat s;
+ if (os_stat(dir, &s) == -1) {
+ con_warn("ERROR: can't record demo: ");
+ if (errno == ENOENT) {
+ con_warn("subdirectory %.*s doesn't exist\n",
+ argdirlen, arg);
+ }
+ else {
+ con_warn("%s\n", strerror(errno)); // guess this'll do.
+ }
+ return;
+ }
+ if (!S_ISDIR(s.st_mode)) {
+ // duping this warning call to avoid duping the string data,
+ // very stupid, oh well. if/when we have New And Improved
+ // Logging this can be tidied up...
+ con_warn("ERROR: can't record demo: ");
+ con_warn("the path %.*s is not a directory\n",
+ argdirlen, arg);
return;
}
}
diff --git a/src/os-win32.h b/src/os-win32.h
index 8aeb93a..12720a9 100644
--- a/src/os-win32.h
+++ b/src/os-win32.h
@@ -109,6 +109,9 @@ static inline void os_randombytes(void *buf, int sz) {
#define W_OK 2
#define X_OK R_OK // there's no actual X bit, just pretend
+// windows doesn't define this for some reason!? note: add others as needed...
+#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+
// just dump this boilerplate here as well, I spose
#define OS_WINDOWS_ERROR(arrayname) \
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), \
diff --git a/src/os.h b/src/os.h
index c00eaf3..3d3ab00 100644
--- a/src/os.h
+++ b/src/os.h
@@ -46,6 +46,7 @@
#include <string.h>
#include <strings.h>
#include <sys/mman.h>
+#include <sys/stat.h>
#include <unistd.h>
#endif