From 0f936f39d8a10779d1220dc54ddc13549da8b45d Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 29 May 2017 12:20:30 +0300 Subject: [PATCH] Rewrote directory creation function for Windows Previous implementation had several security issues https://forum.zdoom.org/viewtopic.php?t=56622 --- src/cmdlib.cpp | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index 7013c6a60..f667610c0 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -477,16 +477,45 @@ const char *myasctime () void DoCreatePath(const char *fn) { char drive[_MAX_DRIVE]; - char path[PATH_MAX]; - char p[PATH_MAX]; - int i; + char dir[_MAX_DIR]; + _splitpath_s(fn, drive, sizeof drive, dir, sizeof dir, nullptr, 0, nullptr, 0); - _splitpath(fn,drive,path,NULL,NULL); - _makepath(p,drive,path,NULL,NULL); - i=(int)strlen(p); - if (p[i-1]=='/' || p[i-1]=='\\') p[i-1]=0; - if (*path) DoCreatePath(p); - _mkdir(p); + if ('\0' == *dir) + { + // Root/current/parent directory always exists + return; + } + + char path[PATH_MAX]; + _makepath_s(path, sizeof path, drive, dir, nullptr, nullptr); + + if ('\0' == *path) + { + // No need to process empty relative path + return; + } + + // Remove trailing path separator(s) + for (size_t i = strlen(path); 0 != i; --i) + { + char& lastchar = path[i - 1]; + + if ('/' == lastchar || '\\' == lastchar) + { + lastchar = '\0'; + } + else + { + break; + } + } + + // Create all directories for given path + if ('\0' != *path) + { + DoCreatePath(path); + _mkdir(path); + } } void CreatePath(const char *fn)