diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-02-16 19:35:47 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-02-16 19:35:47 +0300 |
commit | b7af3d2cbd8dc39e1d133f9c7251cb70cf1aa75b (patch) | |
tree | 005fbfa62faf9a152c7975c1f52ac2cd662ee5f1 | |
parent | 97a28c52b488f8385598d67be9b7e8a1eee66b26 (diff) |
fix for [#8257] double-freeing pointers from sculpt code
http://projects.blender.org/tracker/index.php?func=detail&aid=8257&group_id=9&atid=125
Cleaned up scene_copy, and moved some scene copying into this function that was inline in the user interface.
Also moved malloc error prints onto separate lines so you can set breakpoints.
-rw-r--r-- | intern/guardedalloc/intern/mallocn.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Scene.c | 8 | ||||
-rw-r--r-- | source/blender/src/header_info.c | 149 |
4 files changed, 83 insertions, 84 deletions
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index c1ddfa71a10..20d3a5b07fc 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -529,8 +529,10 @@ short MEM_freeN(void *vmemh) /* anders compileertie niet meer */ } else{ error = -1; name = check_memlist(memh); - if (name == 0) MemorY_ErroR("free","pointer not in memlist"); - else MemorY_ErroR(name,"error in header"); + if (name == 0) + MemorY_ErroR("free","pointer not in memlist"); + else + MemorY_ErroR(name,"error in header"); } totblock--; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index dd6dae84cc5..8ec8b7251dd 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -596,8 +596,10 @@ void sculptdata_init(Scene *sce) sd= &sce->sculptdata; - if(sd->cumap) + if(sd->cumap) { curvemapping_free(sd->cumap); + sd->cumap = NULL; + } memset(sd, 0, sizeof(SculptData)); diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 397cee0ad5e..38903a74d7d 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -774,16 +774,16 @@ static PyObject *Scene_oldsetLayers( BPy_Scene * self, PyObject * args ) /*-----------------------Scene.copy()------------------------------------*/ static PyObject *Scene_copy( BPy_Scene * self, PyObject * args ) { - short dup_objs = 1; + short dup_objs = 2; Scene *scene = self->scene; SCENE_DEL_CHECK_PY(self); - if( !PyArg_ParseTuple( args, "|h", &dup_objs ) ) + if( !PyArg_ParseTuple( args, "|h", &dup_objs ) || dup_objs < 0 || dup_objs > 2) return EXPP_ReturnPyObjError( PyExc_TypeError, "expected int in [0,2] or nothing as argument" ); - - return Scene_CreatePyObject( copy_scene( scene, dup_objs ) ); + + return Scene_CreatePyObject( copy_scene( scene, dup_objs+1 ) ); } /*-----------------------Scene.makeCurrent()-----------------------------*/ diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 08895fe941a..57388bbca68 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -283,46 +283,82 @@ int buttons_do_unpack() Scene *copy_scene(Scene *sce, int level) { - /* level 0: al objects shared - * level 1: al object-data shared - * level 2: full copy + /* + * level 0: empty, only copy minimal stuff + * level 1: all objects shared + * level 2: all object-data shared + * level 3: full copy */ + Scene *scen; Base *base, *obase; - - /* level 0 */ - scen= copy_libblock(sce); - duplicatelist(&(scen->base), &(sce->base)); - clear_id_newpoins(); + if (level==0) { /* Add Empty, minimal copy */ + ListBase lb; + scen= add_scene(sce->id.name+2); + + lb= scen->r.layers; + scen->r= sce->r; + scen->r.layers= lb; + + } else { + /* level 1+, but not level 0 */ + scen= copy_libblock(sce); + duplicatelist(&(scen->base), &(sce->base)); + + clear_id_newpoins(); + + id_us_plus((ID *)scen->world); + id_us_plus((ID *)scen->set); - id_us_plus((ID *)scen->world); - id_us_plus((ID *)scen->set); - - scen->ed= NULL; - scen->radio= NULL; - scen->theDag= NULL; - scen->toolsettings= MEM_dupallocN(sce->toolsettings); - - duplicatelist(&(scen->markers), &(sce->markers)); - duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces)); - duplicatelist(&(scen->r.layers), &(sce->r.layers)); + scen->ed= NULL; + scen->radio= NULL; + scen->theDag= NULL; + scen->toolsettings= MEM_dupallocN(sce->toolsettings); - scen->nodetree= ntreeCopyTree(sce->nodetree, 0); + duplicatelist(&(scen->markers), &(sce->markers)); + duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces)); + duplicatelist(&(scen->r.layers), &(sce->r.layers)); + + scen->nodetree= ntreeCopyTree(sce->nodetree, 0); + + obase= sce->base.first; + base= scen->base.first; + while(base) { + id_us_plus(&base->object->id); + if(obase==sce->basact) scen->basact= base; + + obase= obase->next; + base= base->next; + } + BPY_copy_scriptlink(&sce->scriptlink); + + /* sculpt data */ + if (sce->sculptdata.cumap) { + scen->sculptdata.cumap = curvemapping_copy( sce->sculptdata.cumap ); + } + } - obase= sce->base.first; - base= scen->base.first; - while(base) { - id_us_plus(&base->object->id); - if(obase==sce->basact) scen->basact= base; - - obase= obase->next; - base= base->next; + // make a private copy of the avicodecdata + + if (sce->r.avicodecdata) { + + scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata); + scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat); + scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms); } + + // make a private copy of the qtcodecdata + + if (sce->r.qtcodecdata) { + scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata); + scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms); + } + + + if(level==0 || level==1) return scen; - if(level==0) return scen; - - /* level 1 */ + /* level 2 */ G.scene= scen; single_object_users(0); @@ -330,8 +366,8 @@ Scene *copy_scene(Scene *sce, int level) /* camera */ ID_NEW(G.scene->camera); - /* level 2 */ - if(level>=2) { + /* level 3 */ + if(level>=3) { if(scen->world) { id_us_plus(&scen->world->id); scen->world= copy_world(scen->world); @@ -345,24 +381,6 @@ Scene *copy_scene(Scene *sce, int level) } clear_id_newpoins(); - - BPY_copy_scriptlink(&sce->scriptlink); - // make a private copy of the avicodecdata - - if (sce->r.avicodecdata) { - - scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata); - scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat); - scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms); - } - - // make a private copy of the qtcodecdata - - if (sce->r.qtcodecdata) { - scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata); - scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms); - } - return scen; } @@ -448,32 +466,9 @@ void do_info_buttons(unsigned short event) } /* last item: NEW SCENE */ if(sce==0) { - nr= pupmenu("Add scene%t|Empty|Link Objects|Link ObData|Full Copy"); - if(nr<= 0) return; - if(nr==1) { - ListBase lb; - - sce= add_scene(G.scene->id.name+2); - /* pretty bad ass copying here. we should use copy_scene to do all (ton) */ - lb= sce->r.layers; - sce->r= G.scene->r; - sce->r.layers= lb; -#ifdef _WIN32 - if (sce->r.avicodecdata) { - sce->r.avicodecdata = MEM_dupallocN(G.scene->r.avicodecdata); - sce->r.avicodecdata->lpFormat = MEM_dupallocN(G.scene->r.avicodecdata->lpFormat); - sce->r.avicodecdata->lpParms = MEM_dupallocN(G.scene->r.avicodecdata->lpParms); - } -#endif -#ifdef WITH_QUICKTIME - if (sce->r.qtcodecdata) { - sce->r.qtcodecdata = MEM_dupallocN(G.scene->r.qtcodecdata); - sce->r.qtcodecdata->cdParms = MEM_dupallocN(G.scene->r.qtcodecdata->cdParms); - } -#endif - } - else sce= copy_scene(G.scene, nr-2); - + nr= pupmenu("Add scene%t|Empty%x0|Link Objects%x1|Link ObData%x2|Full Copy%x3"); + if(nr<0) return; + sce= copy_scene(G.scene, nr); set_scene(sce); } countall(); |