diff --git a/source/blender/blenkernel/intern/appdir.cc b/source/blender/blenkernel/intern/appdir.cc index e0f63b147df..120a095a1cc 100644 --- a/source/blender/blenkernel/intern/appdir.cc +++ b/source/blender/blenkernel/intern/appdir.cc @@ -1118,16 +1118,9 @@ void BKE_appdir_app_templates(ListBase *templates) */ static void where_is_temp(char *tempdir, const size_t tempdir_maxncpy, const char *userdir) { - - tempdir[0] = '\0'; - - if (userdir && userdir[0] != '\0' && BLI_is_dir(userdir)) { - BLI_strncpy(tempdir, userdir, tempdir_maxncpy); - /* Add a trailing slash if needed. */ - BLI_path_slash_ensure(tempdir, tempdir_maxncpy); + if (BLI_temp_directory_path_copy_if_valid(tempdir, tempdir_maxncpy, userdir)) { return; } - BLI_temp_directory_path_get(tempdir, tempdir_maxncpy); } diff --git a/source/blender/blenlib/BLI_tempfile.h b/source/blender/blenlib/BLI_tempfile.h index c22da8a662e..c62e8b36635 100644 --- a/source/blender/blenlib/BLI_tempfile.h +++ b/source/blender/blenlib/BLI_tempfile.h @@ -14,6 +14,14 @@ extern "C" { #endif +/** + * Sets `temp_directory` from `dirpath` when it's a valid directory. + * Simple sanitize operations are performed and a trailing slash is ensured. + */ +bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, + const size_t buffer_size, + const char *dirpath); + /* Get the path to a directory suitable for temporary files. * * The return path is guaranteed to exist and to be a directory, as well as to contain a trailing diff --git a/source/blender/blenlib/intern/tempfile.c b/source/blender/blenlib/intern/tempfile.c index 02d973a2e16..dfb68403e11 100644 --- a/source/blender/blenlib/intern/tempfile.c +++ b/source/blender/blenlib/intern/tempfile.c @@ -8,6 +8,34 @@ #include "BLI_path_util.h" #include "BLI_string.h" +bool BLI_temp_directory_path_copy_if_valid(char *temp_directory, + const size_t buffer_size, + const char *dirpath) +{ + if (dirpath == NULL) { + return false; + } + + /* Disallow paths starting with two forward slashes. While they are valid paths, + * Blender interprets them as relative in situations relative paths aren't supported, + * see #95411. */ + while (UNLIKELY(dirpath[0] == '/' && dirpath[1] == '/')) { + dirpath++; + } + if (dirpath[0] == '\0') { + return false; + } + if (!BLI_is_dir(dirpath)) { + return false; + } + + BLI_strncpy(temp_directory, dirpath, buffer_size); + + /* Add a trailing slash if needed. */ + BLI_path_slash_ensure(temp_directory, buffer_size); + return true; +} + void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size) { temp_directory[0] = '\0'; @@ -24,9 +52,9 @@ void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size) }; for (int i = 0; i < ARRAY_SIZE(env_vars); i++) { - const char *tmp = BLI_getenv(env_vars[i]); - if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) { - BLI_strncpy(temp_directory, tmp, buffer_size); + if (BLI_temp_directory_path_copy_if_valid( + temp_directory, buffer_size, BLI_getenv(env_vars[i]))) + { break; } } @@ -34,10 +62,6 @@ void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size) if (temp_directory[0] == '\0') { BLI_strncpy(temp_directory, "/tmp/", buffer_size); } - else { - /* Add a trailing slash if needed. */ - BLI_path_slash_ensure(temp_directory, buffer_size); - } BLI_dir_create_recursive(temp_directory); }