Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-12-12 22:06:36 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-12-12 22:06:36 +0400
commit3e7ad0e2714009509004669d8da8ea8c71fa0d04 (patch)
tree9448ca11bb4325aedda01e9aa418b981ebc7d278 /source
parentcd0608aff5958e6fc59aad10730255d3cac48622 (diff)
fix [#29537] file/save crashes when target path isnt found
bug was that uiPupMenuSaveOver(...) could run the WM API call function which freed the operator, within the low level invoke function which kept using the freed memory. Changed uiPupMenuSaveOver(...) to only show a popup so the caller needs to check if the file exists and should be immediately written (which was done everywhere except for blend saving anyway). * added note that operators invoke/exec funcs cant call WM_operator_call(...) on themselves, ends up using freed memory. * added BLI_is_file(path), checks the file exists and isnt a directory.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/intern/storage.c6
-rw-r--r--source/blender/editors/interface/interface_regions.c20
-rw-r--r--source/blender/editors/space_file/file_ops.c6
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c13
6 files changed, 28 insertions, 22 deletions
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 712429716a6..2e8f1a5512e 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -56,6 +56,7 @@ int BLI_create_symlink(const char *path, const char *to);
struct direntry;
int BLI_is_dir(const char *path);
+int BLI_is_file(const char *path);
void BLI_dir_create_recursive(const char *dir);
double BLI_dir_free_space(const char *dir);
char *BLI_current_working_dir(char *dir, const int maxlen);
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 1ef254d355f..001b191155d 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -471,6 +471,12 @@ int BLI_is_dir(const char *file)
return S_ISDIR(BLI_exists(file));
}
+int BLI_is_file(const char *path)
+{
+ int mode= BLI_exists(path);
+ return (mode && !S_ISDIR(mode));
+}
+
LinkNode *BLI_file_read_as_lines(const char *name)
{
FILE *fp= fopen(name, "r");
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 58c3c0130b8..b89a80bb0d7 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2481,22 +2481,14 @@ void uiPupMenuOkee(bContext *C, const char *opname, const char *str, ...)
va_end(ap);
}
+/* note, only call this is the file exists,
+ * the case where the file does not exist so can be saved without a
+ * popup must be checked for already, since saving from here
+ * will free the operator which will break invoke().
+ * The operator state for this is implicitly OPERATOR_RUNNING_MODAL */
void uiPupMenuSaveOver(bContext *C, wmOperator *op, const char *filename)
{
- size_t len= strlen(filename);
-
- if(len==0)
- return;
-
- if(filename[len-1]=='/' || filename[len-1]=='\\') {
- uiPupMenuError(C, "Cannot overwrite a directory");
- WM_operator_free(op);
- return;
- }
- if(BLI_exists(filename)==0)
- operator_cb(C, op, 1);
- else
- confirm_operator(C, op, "Save Over", filename);
+ confirm_operator(C, op, "Save Over", filename);
}
void uiPupMenuNotice(bContext *C, const char *str, ...)
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 69c192b077b..daa2031bb5f 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -715,7 +715,7 @@ int file_draw_check_exists(SpaceFile *sfile)
if(RNA_boolean_get(sfile->op->ptr, "check_existing")) {
char filepath[FILE_MAX];
BLI_join_dirfile(filepath, sizeof(filepath), sfile->params->dir, sfile->params->file);
- if(BLI_exists(filepath) && !BLI_is_dir(filepath)) {
+ if(BLI_is_file(filepath)) {
return TRUE;
}
}
@@ -1143,8 +1143,8 @@ int file_directory_exec(bContext *C, wmOperator *UNUSED(unused))
BLI_dir_create_recursive(sfile->params->dir);
}
- /* special case, user may have pasted a fulepath into the directory */
- if(BLI_exists(sfile->params->dir) && BLI_is_dir(sfile->params->dir) == 0) {
+ /* special case, user may have pasted a filepath into the directory */
+ if(BLI_is_file(sfile->params->dir)) {
char path[sizeof(sfile->params->dir)];
BLI_strncpy(path, sfile->params->dir, sizeof(path));
BLI_split_dirfile(path, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file));
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 9d8f68115cf..38f26897998 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -597,7 +597,9 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
}
-/* for running operators with frozen context (modal handlers, menus) */
+/* for running operators with frozen context (modal handlers, menus)
+ *
+ * warning: do not use this within an operator to call its self! [#29537] */
int WM_operator_call(bContext *C, wmOperator *op)
{
return wm_operator_exec(C, op, 0);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 31d276fee01..fb375f1d61f 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2003,6 +2003,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
{
char name[FILE_MAX];
int check_existing=1;
+ int ret;
/* cancel if no active window */
if (CTX_wm_window(C) == NULL)
@@ -2027,16 +2028,20 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
check_existing = 0;
if (G.save_over) {
- if (check_existing)
+ if (check_existing && BLI_exists(name)) {
uiPupMenuSaveOver(C, op, name);
+ ret= OPERATOR_RUNNING_MODAL;
+ }
else {
- wm_save_as_mainfile_exec(C, op);
+ ret= wm_save_as_mainfile_exec(C, op);
}
- } else {
+ }
+ else {
WM_event_add_fileselect(C, op);
+ ret= OPERATOR_RUNNING_MODAL;
}
- return OPERATOR_RUNNING_MODAL;
+ return ret;
}
static void WM_OT_save_mainfile(wmOperatorType *ot)