Fix recursive folder creation with mixed slashes and drive letters

The function `fs_makedir_rec_for` for recursively creating folders did not handle paths containing backslashes correctly and only created folders after every occurrence of a regular slash. This could cause the recursive folder creation to fail when a parent folder is not created before the child folder. For example when recursively creating folders for the path `D:\Games/DDNet\downloadedskins`, the `DDNet` folder was not being created because this path segment does not end in a forward slash. Now, backslashes are handled the same as regular slashes, which is consistent with the other filesystem functions.

Additionally, the function tried to create folders for drive letters on Windows (e.g. `C:` and `D:`). Trying to create a system drive as a folder will fail due to access being denied, whereas it seems to work for already existing non-system drives. For example when recursively creating folders for the path `C:/Games/DDNet/downloadedskins`, the `C:` "folder" could not be created which caused the entire operation to fail. Now, the function will not try to create folders for drive letters anymore, i.e. if the name of the to be created folder ends with `:`.

Closes #8148.
This commit is contained in:
Robert Müller 2024-03-23 20:39:52 +01:00
parent 7e8dc57194
commit 015390a51e
2 changed files with 11 additions and 8 deletions

View file

@ -2293,17 +2293,20 @@ int fs_storage_path(const char *appname, char *path, int max)
int fs_makedir_rec_for(const char *path)
{
char buffer[1024 * 2];
char *p;
char buffer[IO_MAX_PATH_LENGTH];
str_copy(buffer, path);
for(p = buffer + 1; *p != '\0'; p++)
for(int index = 1; buffer[index] != '\0'; ++index)
{
if(*p == '/' && *(p + 1) != '\0')
// Do not try to create folder for drive letters on Windows,
// as this is not necessary and may fail for system drives.
if((buffer[index] == '/' || buffer[index] == '\\') && buffer[index + 1] != '\0' && buffer[index - 1] != ':')
{
*p = '\0';
buffer[index] = '\0';
if(fs_makedir(buffer) < 0)
{
return -1;
*p = '/';
}
buffer[index] = '/';
}
}
return 0;

View file

@ -1839,11 +1839,11 @@ int fs_makedir(const char *path);
int fs_removedir(const char *path);
/**
* Recursively create directories for a file.
* Recursively creates parent directories for a file or directory.
*
* @ingroup Filesystem
*
* @param path - File for which to create directories.
* @param path File or directory for which to create parent directories.
*
* @return 0 on success. Negative value on failure.
*