=ID Property Bugfix=
authorJoseph Eagar <joeedh@gmail.com>
Sat, 23 Feb 2008 02:12:50 +0000 (02:12 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sat, 23 Feb 2008 02:12:50 +0000 (02:12 +0000)
There was an extraneous line causing ID property groups
to have the wrong length, causing crashes in code that
relied on it.

This commit both fixes that and adds a version check to
fix group lengths for older .blends.  The subversion
was incremented to 15 for this change.

source/blender/blenkernel/intern/idprop.c
source/blender/blenloader/intern/readfile.c
source/blender/python/api2_2x/IDProp.c

index 85144a535d3047afb48833713151dfa78ea09cf3..8ac0ff77832e527964bea1096767b282d4d6f2ee 100644 (file)
@@ -228,10 +228,11 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
                if (BSTR_EQ(loop->name, prop->name)) {
                        if (loop->next) BLI_insertlinkbefore(&group->data.group, loop->next, prop);
                        else BLI_addtail(&group->data.group, prop);
+                       
                        BLI_remlink(&group->data.group, loop);
                        IDP_FreeProperty(loop);
                        MEM_freeN(loop);
-                       group->len++;
+                       
                        return;
                }
        }
index f9a5c419adc3db6377bb2dca0f954911f0890c1a..ae7e3b273b31132c9be6a52f69208f3711e3aad5 100644 (file)
@@ -4665,6 +4665,31 @@ static void ntree_version_245(bNodeTree *ntree)
        }
 }
 
+void idproperties_fix_groups_lengths_recurse(IDProperty *prop)
+{
+       IDProperty *loop;
+       int i;
+       
+       for (loop=prop->data.group.first, i=0; loop; loop=loop->next, i++) {
+               if (loop->type == IDP_GROUP) idproperties_fix_groups_lengths_recurse(loop);
+       }
+       
+       if (prop->len != i) {
+               printf("Found and fixed bad id property group length.\n");
+               prop->len = i;
+       }
+}
+
+void idproperties_fix_group_lengths(ListBase idlist)
+{
+       ID *id;
+       
+       for (id=idlist.first; id; id=id->next) {
+               if (id->properties) {
+                       idproperties_fix_groups_lengths_recurse(id->properties);
+               }
+       }
+}
 
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
@@ -7449,6 +7474,37 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        sce= sce->id.next;
                }
        }
+       
+       /*fix broken group lengths in id properties*/
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 15)) {
+               idproperties_fix_group_lengths(main->scene);
+               idproperties_fix_group_lengths(main->library);
+               idproperties_fix_group_lengths(main->object);
+               idproperties_fix_group_lengths(main->mesh);
+               idproperties_fix_group_lengths(main->curve);
+               idproperties_fix_group_lengths(main->mball);
+               idproperties_fix_group_lengths(main->mat);
+               idproperties_fix_group_lengths(main->tex);
+               idproperties_fix_group_lengths(main->image);
+               idproperties_fix_group_lengths(main->wave);
+               idproperties_fix_group_lengths(main->latt);
+               idproperties_fix_group_lengths(main->lamp);
+               idproperties_fix_group_lengths(main->camera);
+               idproperties_fix_group_lengths(main->ipo);
+               idproperties_fix_group_lengths(main->key);
+               idproperties_fix_group_lengths(main->world);
+               idproperties_fix_group_lengths(main->screen);
+               idproperties_fix_group_lengths(main->script);
+               idproperties_fix_group_lengths(main->vfont);
+               idproperties_fix_group_lengths(main->text);
+               idproperties_fix_group_lengths(main->sound);
+               idproperties_fix_group_lengths(main->group);
+               idproperties_fix_group_lengths(main->armature);
+               idproperties_fix_group_lengths(main->action);
+               idproperties_fix_group_lengths(main->nodetree);
+               idproperties_fix_group_lengths(main->brush);
+               idproperties_fix_group_lengths(main->particle);         
+       }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
index cf5cf42de5d0895a869c69d08a7c705d3e65d7cf..3358b06d30b4e4e1737672901f67ce7ddb4ed9c2 100644 (file)
@@ -433,7 +433,7 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
 {
        PyObject *seq = PyList_New(self->prop->len);
        IDProperty *loop;
-       int i;
+       int i, j;
 
        if (!seq) 
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -442,6 +442,25 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
        for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++)
                PyList_SetItem(seq, i, PyString_FromString(loop->name));
        
+       if (i != self->prop->len) {
+               printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys!\n");
+               
+               /*fill rest of list with valid references to None*/
+               for (j=i; j<self->prop->len; j++) {
+                       Py_INCREF(Py_None);
+                       PyList_SetItem(seq, j, Py_None);
+               }
+               
+               /*set correct group length*/
+               self->prop->len = i;
+               
+               /*free the old list*/
+               Py_DECREF(seq);
+               
+               /*call self again*/
+               return BPy_IDGroup_GetKeys(self);               
+       }
+       
        return seq;
 }
 
@@ -449,7 +468,7 @@ PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
 {
        PyObject *seq = PyList_New(self->prop->len);
        IDProperty *loop;
-       int i;
+       int i, j;
 
        if (!seq) 
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -458,7 +477,26 @@ PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
        for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) {
                PyList_SetItem(seq, i, BPy_IDGroup_WrapData(self->id, loop));
        }
-       
+
+       if (i != self->prop->len) {
+               printf("ID Property Error found and corrected in BPy_IDGroup_GetValues!\n");
+               
+               /*fill rest of list with valid references to None*/
+               for (j=i; j<self->prop->len; j++) {
+                       Py_INCREF(Py_None);
+                       PyList_SetItem(seq, j, Py_None);
+               }
+               
+               /*set correct group length*/
+               self->prop->len = i;
+               
+               /*free the old list*/
+               Py_DECREF(seq);
+               
+               /*call self again*/
+               return BPy_IDGroup_GetValues(self);             
+       }
+               
        return seq;
 }