[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45000] trunk/blender/source/blender: Fix #30590: Crash in multires when undoing extrude [File incl.]

Sergey Sharybin sergey.vfx at gmail.com
Mon Mar 19 21:47:25 CET 2012


Revision: 45000
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45000
Author:   nazgul
Date:     2012-03-19 20:47:17 +0000 (Mon, 19 Mar 2012)
Log Message:
-----------
Fix #30590: Crash in multires when undoing extrude [File incl.]

- Crash was caused by recursively copying directory into itself, fixed
  by switching from opendir() to scandir().
- Also do not try to unpack images which doesn't have name.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/packedFile.c
    trunk/blender/source/blender/blenlib/intern/fileops.c

Modified: trunk/blender/source/blender/blenkernel/intern/packedFile.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/packedFile.c	2012-03-19 20:28:22 UTC (rev 44999)
+++ trunk/blender/source/blender/blenkernel/intern/packedFile.c	2012-03-19 20:47:17 UTC (rev 45000)
@@ -497,7 +497,7 @@
 	char *newname;
 	int ret_value = RET_ERROR;
 	
-	if (ima != NULL) {
+	if (ima != NULL && ima->name[0]) {
 		BLI_strncpy(localname, ima->name, sizeof(localname));
 		BLI_splitdirstring(localname, fi);
 		BLI_snprintf(localname, sizeof(localname), "//textures/%s", fi);

Modified: trunk/blender/source/blender/blenlib/intern/fileops.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/fileops.c	2012-03-19 20:28:22 UTC (rev 44999)
+++ trunk/blender/source/blender/blenlib/intern/fileops.c	2012-03-19 20:47:17 UTC (rev 45000)
@@ -363,13 +363,12 @@
 static int recursive_operation(const char *startfrom, const char *startto, recursiveOp_Callback callback_dir_pre,
                                recursiveOp_Callback callback_file, recursiveOp_Callback callback_dir_post)
 {
-	DIR *dir;
-	struct dirent *dirent;
+	struct dirent **dirlist;
 	struct stat st;
 	char *from = NULL, *to = NULL;
 	char *from_path = NULL, *to_path = NULL;
 	size_t from_alloc_len = -1, to_alloc_len = -1;
-	int ret = 0;
+	int i, n, ret = 0;
 
 	/* ensure there's no trailing slash in file path */
 	from = strip_last_slash(startfrom);
@@ -398,6 +397,18 @@
 		return ret;
 	}
 
+
+	n = scandir(startfrom, &dirlist, 0, alphasort);
+	if (n < 0) {
+		/* error opening directory for listing */
+		perror("scandir");
+
+		MEM_freeN(from);
+		if(to) MEM_freeN(to);
+
+		return -1;
+	}
+
 	if(callback_dir_pre) {
 		/* call pre-recursive walking directory callback */
 		ret = callback_dir_pre(from, to);
@@ -415,21 +426,13 @@
 		}
 	}
 
-	dir = opendir(startfrom);
+	for (i = 0; i < n; i++) {
+		struct dirent *dirent = dirlist[i];
 
-	if(!dir) {
-		/* error opening directory for listing */
-		perror("opendir");
-
-		MEM_freeN(from);
-		if(to) MEM_freeN(to);
-
-		return -1;
-	}
-
-	while((dirent = readdir((dir)))) {
-		if(!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
+		if(!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) {
+			free(dirent);
 			continue;
+		}
 
 		join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
 
@@ -447,11 +450,14 @@
 				ret = -1;
 		}
 
-		if(ret != 0)
+		if(ret != 0) {
+			while (i < n)
+				free(dirlist[i]);
 			break;
+		}
 	}
 
-	closedir(dir);
+	free(dirlist);
 
 	if(ret == 0) {
 		if(callback_dir_post) {




More information about the Bf-blender-cvs mailing list