From 82979d5ab57217502b34977b5e5e82895bd66dbb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 19 Mar 2012 20:47:17 +0000 Subject: 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. --- source/blender/blenkernel/intern/packedFile.c | 2 +- source/blender/blenlib/intern/fileops.c | 42 +++++++++++++++------------ 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index aaf15d683d8..4230510dac9 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -497,7 +497,7 @@ int unpackImage(ReportList *reports, Image *ima, int how) 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); diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 1c1637915fc..ab7beeeb8f1 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -363,13 +363,12 @@ static char *strip_last_slash(const char *dir) 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 @@ static int recursive_operation(const char *startfrom, const char *startto, recur 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 @@ static int recursive_operation(const char *startfrom, const char *startto, recur } } - 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 @@ static int recursive_operation(const char *startfrom, const char *startto, recur 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) { -- cgit v1.2.3