diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-07-12 05:23:48 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-07-12 05:28:06 +0300 |
commit | 4db1db327a0613abee950ffe12b013afdec2c111 (patch) | |
tree | 2655c39b4ad6478e02f89d9361309e5ddc10ef97 | |
parent | 0b3183d13cdbdcb06317fd1dd9b04ccd93a767c1 (diff) |
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).
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 25 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_genfile.h | 3 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_genfile.c | 63 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_define.c | 8 |
5 files changed, 72 insertions, 29 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 27a119a4532..eeb8a5d8dbd 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 bd19f2aeb74..f898eea566d 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 1b558b11cf0..27a3ff8f8cb 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 1d9e9718528..f1d48c07de1 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 bf2b091576e..7ff4eaea169 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; } |