[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42583] trunk/blender/source/blender: fix [#29537] file/save crashes when target path isnt found

Campbell Barton ideasman42 at gmail.com
Mon Dec 12 19:06:39 CET 2011


Revision: 42583
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42583
Author:   campbellbarton
Date:     2011-12-12 18:06:36 +0000 (Mon, 12 Dec 2011)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_fileops.h
    trunk/blender/source/blender/blenlib/intern/storage.c
    trunk/blender/source/blender/editors/interface/interface_regions.c
    trunk/blender/source/blender/editors/space_file/file_ops.c
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Modified: trunk/blender/source/blender/blenlib/BLI_fileops.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_fileops.h	2011-12-12 14:54:28 UTC (rev 42582)
+++ trunk/blender/source/blender/blenlib/BLI_fileops.h	2011-12-12 18:06:36 UTC (rev 42583)
@@ -56,6 +56,7 @@
 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);

Modified: trunk/blender/source/blender/blenlib/intern/storage.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/storage.c	2011-12-12 14:54:28 UTC (rev 42582)
+++ trunk/blender/source/blender/blenlib/intern/storage.c	2011-12-12 18:06:36 UTC (rev 42583)
@@ -471,6 +471,12 @@
 	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");

Modified: trunk/blender/source/blender/editors/interface/interface_regions.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_regions.c	2011-12-12 14:54:28 UTC (rev 42582)
+++ trunk/blender/source/blender/editors/interface/interface_regions.c	2011-12-12 18:06:36 UTC (rev 42583)
@@ -2481,22 +2481,14 @@
 	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, ...)

Modified: trunk/blender/source/blender/editors/space_file/file_ops.c
===================================================================
--- trunk/blender/source/blender/editors/space_file/file_ops.c	2011-12-12 14:54:28 UTC (rev 42582)
+++ trunk/blender/source/blender/editors/space_file/file_ops.c	2011-12-12 18:06:36 UTC (rev 42583)
@@ -715,7 +715,7 @@
 			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 @@
 			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));

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2011-12-12 14:54:28 UTC (rev 42582)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2011-12-12 18:06:36 UTC (rev 42583)
@@ -597,7 +597,9 @@
 	
 }
 
-/* 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);

Modified: trunk/blender/source/blender/windowmanager/intern/wm_operators.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2011-12-12 14:54:28 UTC (rev 42582)
+++ trunk/blender/source/blender/windowmanager/intern/wm_operators.c	2011-12-12 18:06:36 UTC (rev 42583)
@@ -2003,6 +2003,7 @@
 {
 	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 @@
 			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)




More information about the Bf-blender-cvs mailing list