Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-07-12 05:23:48 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-07-12 05:28:06 +0300
commit4db1db327a0613abee950ffe12b013afdec2c111 (patch)
tree2655c39b4ad6478e02f89d9361309e5ddc10ef97
parent0b3183d13cdbdcb06317fd1dd9b04ccd93a767c1 (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.c25
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/makesdna/DNA_genfile.h3
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c63
-rw-r--r--source/blender/makesrna/intern/rna_define.c8
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;
}