WM: make all blend file paths absolute & normalized on read/write
Ensure the file path G.main->filepath is always absolute and normalized. - It was possible to call WM_OT_open_mainfile with only a filename, if this resolved from the CWD, Blender's internal filepath would not be absolute as expected. - It was possible to open files on UNIX with an additional forward slash causing the blend file path it's self to contain a '//' prefix, this is error prone as running BLI_path_abs(..) multiple times would add the blend file prefix each time. - Remove requirement for "filepath" to be an absolute path when saving. Instead, expand the path - making it absolute, as this constraint wasn't applied open opening files, prefer making save/open behave consistently. - Assert when BLI_path_abs/BLI_path_rel receive a basepath that has a "//" (relative) prefix itself.
This commit is contained in:
@@ -605,6 +605,8 @@ void BLI_path_normalize_unc_16(wchar_t *path_16)
|
||||
void BLI_path_rel(char path[FILE_MAX], const char *basepath)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(path, FILE_MAX);
|
||||
/* A `basepath` starting with `//` will be be made relative multiple times. */
|
||||
BLI_assert_msg(!BLI_path_is_rel(basepath), "The 'basepath' cannot start with '//'!");
|
||||
|
||||
const char *lslash;
|
||||
char temp[FILE_MAX];
|
||||
@@ -1043,6 +1045,8 @@ void BLI_path_to_display_name(char *display_name, int display_name_maxncpy, cons
|
||||
bool BLI_path_abs(char path[FILE_MAX], const char *basepath)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(path, FILE_MAX);
|
||||
/* A `basepath` starting with `//` will be be made absolute multiple times. */
|
||||
BLI_assert_msg(!BLI_path_is_rel(basepath), "The 'basepath' cannot start with '//'!");
|
||||
|
||||
const bool wasrelative = BLI_path_is_rel(path);
|
||||
char tmp[FILE_MAX];
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_path_util.h" /* Only for assertions. */
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
@@ -400,6 +401,9 @@ BlendFileData *BLO_read_from_file(const char *filepath,
|
||||
eBLOReadSkip skip_flags,
|
||||
BlendFileReadReport *reports)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
BLI_assert(BLI_path_is_abs_from_cwd(filepath));
|
||||
|
||||
BlendFileData *bfd = nullptr;
|
||||
FileData *fd;
|
||||
|
||||
|
||||
@@ -2797,6 +2797,8 @@ static int wm_open_mainfile__open(bContext *C, wmOperator *op)
|
||||
bool success;
|
||||
|
||||
RNA_string_get(op->ptr, "filepath", filepath);
|
||||
BLI_path_abs_from_cwd(filepath, sizeof(filepath));
|
||||
BLI_path_normalize_native(filepath);
|
||||
|
||||
/* re-use last loaded setting so we can reload a file without changing */
|
||||
wm_open_init_load_ui(op, false);
|
||||
@@ -3101,6 +3103,8 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
|
||||
bool success;
|
||||
|
||||
RNA_string_get(op->ptr, "filepath", filepath);
|
||||
BLI_path_abs_from_cwd(filepath, sizeof(filepath));
|
||||
BLI_path_normalize_native(filepath);
|
||||
|
||||
wm_open_init_use_scripts(op, true);
|
||||
SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC);
|
||||
@@ -3242,6 +3246,8 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
|
||||
const bool is_filepath_set = RNA_struct_property_is_set(op->ptr, "filepath");
|
||||
if (is_filepath_set) {
|
||||
RNA_string_get(op->ptr, "filepath", filepath);
|
||||
BLI_path_abs_from_cwd(filepath, sizeof(filepath));
|
||||
BLI_path_normalize_native(filepath);
|
||||
}
|
||||
else {
|
||||
STRNCPY(filepath, BKE_main_blendfile_path(bmain));
|
||||
@@ -3254,19 +3260,6 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* NOTE(@ideasman42): only check this for file-path properties so saving an already
|
||||
* saved file never fails with an error.
|
||||
* Even though this should never happen, there may be some corner case where a malformed
|
||||
* path is stored in `G.main->filepath`: when the file path is initialized from recovering
|
||||
* a blend file - for example, so in this case failing to save isn't ideal. */
|
||||
if (is_filepath_set && !BLI_path_is_abs_from_cwd(filepath)) {
|
||||
BKE_reportf(op->reports,
|
||||
RPT_ERROR,
|
||||
"The \"filepath\" property was not an absolute path: \"%s\"",
|
||||
filepath);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const int fileflags_orig = G.fileflags;
|
||||
int fileflags = G.fileflags;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user