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.
This commit is contained in:
Brecht Van Lommel 2013-08-07 19:29:15 +00:00
parent 9d9c64582b
commit 9a80fc62d4

@ -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;