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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-08-07 23:29:15 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-08-07 23:29:15 +0400
commit9a80fc62d415c86fafa4e9238b54f7232f341df3 (patch)
tree1dea774a307f9d7a6a171e84e0745082408993ad
parent9d9c64582b3b781d9e709e3d87791ea730a2352f (diff)
Fix crashes that could still happen opening files with the outliner bug that existed
between revision 58855 and 58959. Now it ensures the memory is not freed before reading.
-rw-r--r--source/blender/blenloader/intern/readfile.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b1c89846e90..261a6416f84 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -328,7 +328,7 @@ void blo_do_versions_oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newad
oldnewmap_insert(onm, oldaddr, newaddr, nr);
}
-static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
+static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_users)
{
int i;
@@ -338,7 +338,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
OldNew *entry = &onm->entries[++onm->lasthit];
if (entry->old == addr) {
- entry->nr++;
+ if (increase_users)
+ entry->nr++;
return entry->newp;
}
}
@@ -349,7 +350,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
if (entry->old == addr) {
onm->lasthit = i;
- entry->nr++;
+ if (increase_users)
+ entry->nr++;
return entry->newp;
}
}
@@ -1201,34 +1203,39 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
{
- return oldnewmap_lookup_and_inc(fd->datamap, adr);
+ return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
+}
+
+static void *newdataadr_no_us(FileData *fd, void *adr) /* only direct databocks */
+{
+ return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
}
static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
{
- return oldnewmap_lookup_and_inc(fd->globmap, adr);
+ return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
}
static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
{
if (fd->imamap && adr)
- return oldnewmap_lookup_and_inc(fd->imamap, adr);
+ return oldnewmap_lookup_and_inc(fd->imamap, adr, true);
return NULL;
}
static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
{
if (fd->movieclipmap && adr)
- return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
+ return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true);
return NULL;
}
static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
{
if (fd->packedmap && adr)
- return oldnewmap_lookup_and_inc(fd->packedmap, adr);
+ return oldnewmap_lookup_and_inc(fd->packedmap, adr, true);
- return oldnewmap_lookup_and_inc(fd->datamap, adr);
+ return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
}
@@ -6301,10 +6308,14 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
else if (sl->spacetype == SPACE_OUTLINER) {
SpaceOops *soops = (SpaceOops *) sl;
- TreeStore *ts = newdataadr(fd, soops->treestore);
+ /* use newdataadr_no_us and do not free old memory avoidign double
+ * frees and use of freed memory. this could happen because of a
+ * bug fixed in revision 58959 where the treestore memory address
+ * was not unique */
+ TreeStore *ts = newdataadr_no_us(fd, soops->treestore);
soops->treestore = NULL;
if (ts) {
- TreeStoreElem *elems = newdataadr(fd, ts->data);
+ TreeStoreElem *elems = newdataadr_no_us(fd, ts->data);
soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem,
512, BLI_MEMPOOL_ALLOW_ITER);
@@ -6314,12 +6325,9 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore);
*new_elem = elems[i];
}
- MEM_freeN(elems);
}
/* we only saved what was used */
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
-
- MEM_freeN(ts);
}
soops->treehash = NULL;
soops->tree.first = soops->tree.last= NULL;