Commit: 4db1db327a0613abee950ffe12b013afdec2c111
Author: Campbell Barton
Date:   Tue Jul 12 12:23:48 2016 +1000
Branches: master
https://developer.blender.org/rB4db1db327a0613abee950ffe12b013afdec2c111

readfile: report SDNA decoding errors on file read

This was printed to the stdout, however the error case wasn't checked or well 
supported.
Also, errors decoding SDNA would sometimes call exit(1).

===================================================================

M       source/blender/blenloader/intern/readfile.c
M       source/blender/blenloader/intern/writefile.c
M       source/blender/makesdna/DNA_genfile.h
M       source/blender/makesdna/intern/dna_genfile.c
M       source/blender/makesrna/intern/rna_define.c

===================================================================

diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index 27a119a..eeb8a5d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -909,7 +909,10 @@ static void decode_blender_header(FileData *fd)
        }
 }
 
-static int read_file_dna(FileData *fd)
+/**
+ * \return Success if the file is read correctly, else set \a r_error_message.
+ */
+static bool read_file_dna(FileData *fd, const char **r_error_message)
 {
        BHead *bhead;
        
@@ -917,20 +920,25 @@ static int read_file_dna(FileData *fd)
                if (bhead->code == DNA1) {
                        const bool do_endian_swap = (fd->flags & 
FD_FLAGS_SWITCH_ENDIAN) != 0;
                        
-                       fd->filesdna = DNA_sdna_from_data(&bhead[1], 
bhead->len, do_endian_swap, true);
+                       fd->filesdna = DNA_sdna_from_data(&bhead[1], 
bhead->len, do_endian_swap, true, r_error_message);
                        if (fd->filesdna) {
                                fd->compflags = 
DNA_struct_get_compareflags(fd->filesdna, fd->memsdna);
                                /* used to retrieve ID names from (bhead+1) */
                                fd->id_name_offs = 
DNA_elem_offset(fd->filesdna, "ID", "char", "name[]");
+
+                               return true;
+                       }
+                       else {
+                               return false;
                        }
                        
-                       return 1;
                }
                else if (bhead->code == ENDB)
                        break;
        }
        
-       return 0;
+       *r_error_message = "Missing DNA block";
+       return false;
 }
 
 static int *read_file_thumbnail(FileData *fd)
@@ -1077,7 +1085,7 @@ static FileData *filedata_new(void)
         * but it keeps us re-entrant,  remove once we have
         * a lib that provides a nice lock. - zr
         */
-       fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false);
+       fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
        
        fd->datamap = oldnewmap_new();
        fd->globmap = oldnewmap_new();
@@ -1091,8 +1099,11 @@ static FileData *blo_decode_and_check(FileData *fd, 
ReportList *reports)
        decode_blender_header(fd);
        
        if (fd->flags & FD_FLAGS_FILE_OK) {
-               if (!read_file_dna(fd)) {
-                       BKE_reportf(reports, RPT_ERROR, "Failed to read blend 
file '%s', incomplete", fd->relabase);
+               const char *error_message = NULL;
+               if (read_file_dna(fd, &error_message) == false) {
+                       BKE_reportf(reports, RPT_ERROR,
+                                   "Failed to read blend file '%s': %s",
+                                   fd->relabase, error_message);
                        blo_freefiledata(fd);
                        fd = NULL;
                }
diff --git a/source/blender/blenloader/intern/writefile.c 
b/source/blender/blenloader/intern/writefile.c
index bd19f2a..f898eea 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -325,7 +325,7 @@ static WriteData *writedata_new(WriteWrap *ww)
 {
        WriteData *wd = MEM_callocN(sizeof(*wd), "writedata");
 
-       wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false);
+       wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
 
        wd->ww = ww;
 
diff --git a/source/blender/makesdna/DNA_genfile.h 
b/source/blender/makesdna/DNA_genfile.h
index 1b558b1..27a3ff8 100644
--- a/source/blender/makesdna/DNA_genfile.h
+++ b/source/blender/makesdna/DNA_genfile.h
@@ -76,7 +76,8 @@ enum eSDNA_StructCompare {
 
 struct SDNA *DNA_sdna_from_data(
         const void *data, const int datalen,
-        bool do_endian_swap, bool data_alloc);
+        bool do_endian_swap, bool data_alloc,
+        const char **r_error_message);
 void DNA_sdna_free(struct SDNA *sdna);
 
 int DNA_struct_find_nr_ex(const struct SDNA *sdna, const char *str, unsigned 
int *index_last);
diff --git a/source/blender/makesdna/intern/dna_genfile.c 
b/source/blender/makesdna/intern/dna_genfile.c
index 1d9e971..f1d48c0 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -341,7 +341,9 @@ int DNA_struct_find_nr(const SDNA *sdna, const char *str)
 /**
  * In sdna->data the data, now we convert that to something understandable
  */
-static void init_structDNA(SDNA *sdna, bool do_endian_swap)
+static bool init_structDNA(
+        SDNA *sdna, bool do_endian_swap,
+        const char **r_error_message)
 {
        int *data, *verg, gravity_fix = -1;
        short *sp;
@@ -350,10 +352,18 @@ static void init_structDNA(SDNA *sdna, bool 
do_endian_swap)
        verg = (int *)str;
        data = (int *)sdna->data;
 
+       /* clear pointers incase of error */
+       sdna->names = NULL;
+       sdna->types = NULL;
+       sdna->structs = NULL;
+#ifdef WITH_DNA_GHASH
+       sdna->structs_map = NULL;
+#endif
+
        strcpy(str, "SDNA");
        if (*data != *verg) {
-               printf("SDNA error in SDNA file\n");
-               return;
+               *r_error_message = "SDNA error in SDNA file";
+               return false;
        }
        else {
                intptr_t nr;
@@ -373,8 +383,8 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
                        sdna->names = MEM_callocN(sizeof(void *) * 
sdna->nr_names, "sdnanames");
                }
                else {
-                       printf("NAME error in SDNA file\n");
-                       return;
+                       *r_error_message = "NAME error in SDNA file";
+                       return false;
                }
                
                nr = 0;
@@ -413,8 +423,8 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
                        sdna->types = MEM_callocN(sizeof(void *) * 
sdna->nr_types, "sdnatypes");
                }
                else {
-                       printf("TYPE error in SDNA file\n");
-                       return;
+                       *r_error_message = "TYPE error in SDNA file";
+                       return false;
                }
                
                nr = 0;
@@ -459,8 +469,8 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
                        sp += sdna->nr_types;
                }
                else {
-                       printf("TLEN error in SDNA file\n");
-                       return;
+                       *r_error_message = "TLEN error in SDNA file";
+                       return false;
                }
                if (sdna->nr_types & 1) sp++;   /* prevent BUS error */
 
@@ -477,8 +487,8 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
                        sdna->structs = MEM_callocN(sizeof(void *) * 
sdna->nr_structs, "sdnastrcs");
                }
                else {
-                       printf("STRC error in SDNA file\n");
-                       return;
+                       *r_error_message = "STRC error in SDNA file";
+                       return false;
                }
                
                nr = 0;
@@ -537,8 +547,8 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
 
                /* should never happen, only with corrupt file for example */
                if (UNLIKELY(nr == -1)) {
-                       printf("ListBase struct error! Not found.\n");
-                       exit(1);
+                       *r_error_message = "ListBase struct error! Not found.";
+                       return false;
                }
 
                /* finally pointerlen: use struct ListBase to test it, never 
change the size of it! */
@@ -548,11 +558,13 @@ static void init_structDNA(SDNA *sdna, bool 
do_endian_swap)
                sdna->pointerlen = sdna->typelens[sp[0]] / 2;
 
                if (sp[1] != 2 || (sdna->pointerlen != 4 && sdna->pointerlen != 
8)) {
-                       printf("ListBase struct error! Needs it to calculate 
pointerize.\n");
-                       exit(1);
+                       *r_error_message = "ListBase struct error! Needs it to 
calculate pointerize.";
                        /* well, at least sizeof(ListBase) is error proof! 
(ton) */
+                       return false;
                }
        }
+
+       return true;
 }
 
 /**
@@ -560,9 +572,11 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap)
  */
 SDNA *DNA_sdna_from_data(
         const void *data, const int datalen,
-        bool do_endian_swap, bool data_alloc)
+        bool do_endian_swap, bool data_alloc,
+        const char **r_error_message)
 {
        SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna");
+       const char *error_message = NULL;
 
        sdna->datalen = datalen;
        if (data_alloc) {
@@ -575,9 +589,20 @@ SDNA *DNA_sdna_from_data(
        }
        sdna->data_alloc = data_alloc;
        
-       init_structDNA(sdna, do_endian_swap);
-       
-       return sdna;
+
+       if (init_structDNA(sdna, do_endian_swap, &error_message)) {
+               return sdna;
+       }
+       else {
+               if (r_error_message == NULL) {
+                       fprintf(stderr, "Error decoding blend file SDNA: %s\n", 
error_message);
+               }
+               else {
+                       *r_error_message = error_message;
+               }
+               DNA_sdna_free(sdna);
+               return NULL;
+       }
 }
 
 /* ******************** END READ DNA ********************** */
diff --git a/source/blender/makesrna/intern/rna_define.c 
b/source/blender/makesrna/intern/rna_define.c
index bf2b091..7ff4eae 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -531,12 +531,18 @@ BlenderRNA *RNA_create(void)
        BlenderRNA *brna;
 
        brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
+       const char *error_message = NULL;
 
-       DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false);
        BLI_listbase_clear(&DefRNA.structs);
        DefRNA.error = 0;
        DefRNA.preprocess = 1;
 
+       DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, 
&error_message);
+       if (DefRNA.sdna == NULL) {
+               fprintf(stderr, "Error decoding SDNA: %s\n", error_message);
+               DefRNA.error = 1;
+       }
+
        return brna;
 }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to