Avoid a DNA parsing bug that would parse "float gravity [3];" as two
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 13 Feb 2010 23:18:28 +0000 (23:18 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 13 Feb 2010 23:18:28 +0000 (23:18 +0000)
struct members "gravity" and "[3]". Now it throws an error in this case,
safer than trying to fix the parsing code. Also patches the old DNA of
ClothSimSettings which had this problem .. very ugly code.

Fixes #20330: cloth sim settings getting corrupted when read from 2.49.

source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/intern/dna_genfile.c
source/blender/makesdna/intern/makesdna.c

index 777c2ec874700f12c9ef92b5207289866b28223c..06ace29dbfecaf0a5263ebfab50c118a70d97888 100644 (file)
@@ -47,10 +47,7 @@ typedef struct ClothSimSettings
        float   mingoal;        /* see SB */
        float   Cdis;           /* Mechanical damping of springs.               */
        float   Cvi;            /* Viscous/fluid damping.                       */
-       /* XXX the extra space here results in wrong DNA parsing,
-        * and reconstruct fails and gives corrupt settings when
-        * removing it because the old dna is wrong ... */
-       float   gravity [3];    /* Gravity/external force vector.               */
+       float   gravity[3];     /* Gravity/external force vector.               */
        float   dt;             /* This is the duration of our time step, computed.     */
        float   mass;           /* The mass of the entire cloth.                */
        float   structural;     /* Structural spring stiffness.                 */
@@ -79,6 +76,7 @@ typedef struct ClothSimSettings
        short   vgroup_struct;  /* vertex group for scaling structural stiffness */
        short   presets; /* used for presets on GUI */
        short   reset;
+       int             pad;
 
        struct EffectorWeights *effector_weights;
 } ClothSimSettings;
index cbc433ed722e9384eb5e9a2c8cabe1b5f631ebc4..89219b114da41c703fe946014d0982b860c52f52 100644 (file)
@@ -297,7 +297,7 @@ int DNA_struct_find_nr(SDNA *sdna, const char *str)
 static void init_structDNA(SDNA *sdna, int do_endian_swap)
 /* in sdna->data the data, now we convert that to something understandable */
 {
-       int *data, *verg;
+       int *data, *verg, gravity_fix= -1;
        intptr_t nr;
        short *sp;
        char str[8], *cp;
@@ -330,6 +330,17 @@ static void init_structDNA(SDNA *sdna, int do_endian_swap)
                cp= (char *)data;
                while(nr<sdna->nr_names) {
                        sdna->names[nr]= cp;
+
+                       /* "float gravity [3]" was parsed wrong giving both "gravity" and
+                          "[3]"  members. we rename "[3]", and later set the type of
+                          "gravity" to "void" so the offsets work out correct */
+                       if(*cp == '[' && strcmp(cp, "[3]")==0) {
+                               if(nr && strcmp(sdna->names[nr-1], "Cvi") == 0) {
+                                       sdna->names[nr]= "gravity[3]";
+                                       gravity_fix= nr;
+                               }
+                       }
+
                        while( *cp) cp++;
                        cp++;
                        nr++;
@@ -444,7 +455,7 @@ static void init_structDNA(SDNA *sdna, int do_endian_swap)
                        
                        nr++;
                }
-               
+
                /* finally pointerlen: use struct ListBase to test it, never change the size of it! */
                sp= findstruct_name(sdna, "ListBase");
                /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */
@@ -457,6 +468,14 @@ static void init_structDNA(SDNA *sdna, int do_endian_swap)
                        /* well, at least sizeof(ListBase) is error proof! (ton) */
                }
                
+               /* second part of gravity problem, setting "gravity" type to void */
+               if(gravity_fix > -1) {
+                       for(nr=0; nr<sdna->nr_structs; nr++) {
+                               sp= sdna->structs[nr];
+                               if(strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0)
+                                       sp[10]= 9;
+                       }
+               }
        }
 }
 
index 4ccabc95a32ca7e3a688c4794aec713e713f89c9..2d62b81e81b965040086c67052bfcbbad1c941ec 100644 (file)
@@ -699,7 +699,7 @@ static int calculate_structlens(int firststruct)
                                for(b=0; b<structpoin[1]; b++, sp+=2) {
                                        type= sp[0];
                                        cp= names[sp[1]];
-                                       
+
                                        namelen= (int) strlen(cp);
                                        /* is it a pointer or function pointer? */
                                        if(cp[0]=='*' || cp[1]=='*') {
@@ -729,6 +729,10 @@ static int calculate_structlens(int firststruct)
                                                len += sizeof(void *) * mul;
                                                alphalen += 8 * mul;
 
+                                       } else if(cp[0]=='[') {
+                                               /* parsing can cause names "var" and "[3]" to be found for "float var [3]" ... */
+                                               printf("Parse error in struct, invalid member name: %s %s\n", types[structtype], cp);
+                                               dna_error = 1;
                                        } else if( typelens[type] ) {
                                                /* has the name an extra length? (array) */
                                                mul= 1;