From 05232615a64143a456ec51a337ab71b101f78ca7 Mon Sep 17 00:00:00 2001 From: MysterD Date: Tue, 15 Mar 2022 23:28:46 -0700 Subject: [PATCH] Add portability check to mod filenames --- src/pc/mods/mods_utils.c | 33 +++++++++++++++++++++++++++++++++ src/pc/mods/mods_utils.h | 1 + 2 files changed, 34 insertions(+) diff --git a/src/pc/mods/mods_utils.c b/src/pc/mods/mods_utils.c index 6be20be3..ab635f6d 100644 --- a/src/pc/mods/mods_utils.c +++ b/src/pc/mods/mods_utils.c @@ -167,6 +167,36 @@ char* extract_lua_field(char* fieldName, char* buffer) { ////////////////////////////////////////////////////////////////////////////////////////// +bool path_is_portable_filename(char* string) { + char* s = string; + while (*s != '\0') { + char c = *s; + + if (c < ' ' || c > '~') { + // outside of printable range + return false; + } + + switch (c) { + // unallowed in filenames + case '/': + case '\\': + case '<': + case '>': + case ':': + case '"': + case '|': + case '?': + case '*': + return false; + } + + s++; + } + + return true; +} + bool path_exists(char* path) { struct stat sb = { 0 }; return (stat(path, &sb) == 0); @@ -208,6 +238,9 @@ char* path_basename(char* path) { } bool directory_sanity_check(struct dirent* dir, char* dirPath, char* outPath) { + // skip non-portable filenames + if (!path_is_portable_filename(dir->d_name)) { return false; } + // skip anything that contains \ or / if (strchr(dir->d_name, '/') != NULL) { return false; } if (strchr(dir->d_name, '\\') != NULL) { return false; } diff --git a/src/pc/mods/mods_utils.h b/src/pc/mods/mods_utils.h index b8467905..2e5bc2ba 100644 --- a/src/pc/mods/mods_utils.h +++ b/src/pc/mods/mods_utils.h @@ -16,6 +16,7 @@ bool str_ends_with(char* string, char* suffix); char* extract_lua_field(char* fieldName, char* buffer); +bool path_is_portable_filename(char* string); bool path_exists(char* path); bool is_directory(char* path); void normalize_path(char* path);