From e8843dba3eb1c7a67f6ff7b920046ae36a12acd0 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Mon, 16 May 2022 20:23:39 +0100 Subject: Make the demo directory check more robust This is how it should've been to begin with, but I was lazy. --- src/demorec.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'src/demorec.c') 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; } } -- cgit v1.2.3