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 /source/blender
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).
Diffstat (limited to 'source/blender')
-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;
}