Fix assert with temporary directories beginning with "//"

- Skip leading forward slashes when setting the temp directory.
- Add a utility function to set the temporary directory
  which is used for the user preferences & environment variables.

This issue was raised by #95411 where "//" resolves to "/",
then asserts when passed to Blender's file-system functions.
However the crash referenced in this report looks to be caused
by Collada failing to write to the temporary directory which
can be handled separately.

Ref !118872
This commit is contained in:
Campbell Barton
2024-02-29 09:35:03 +11:00
parent a96f1208cc
commit c19cdc343f
3 changed files with 40 additions and 15 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}