diff --git a/src/hdf5_drv/silo_hdf5.c b/src/hdf5_drv/silo_hdf5.c index e10714e3..f0617605 100644 --- a/src/hdf5_drv/silo_hdf5.c +++ b/src/hdf5_drv/silo_hdf5.c @@ -13014,7 +13014,7 @@ db_hdf5_PutMaterial( m.guihide = _ma._guihide; m.datatype = (DB_FLOAT==datatype || DB_DOUBLE==datatype)?0:datatype; strcpy(m.meshid, OPT(mname)); - for (nels=1, i=0; i0?segment_lengths[i]:0); if (tot_len) { intArray = (int *) malloc(tot_len * sizeof(int)); @@ -16694,7 +16694,11 @@ db_hdf5_PutGroupelmap(DBfile *_dbfile, char const *name, intArray = (int *) malloc(num_segments * sizeof(int)); for (i = 0; i < num_segments; i++) { - int len = segment_fracs[i] == 0 ? 0 : segment_lengths[i]; + int len; + if (segment_fracs[i] == 0) + len = 0; + else + len = (segment_lengths[i]>0?segment_lengths[i]:0); intArray[i] = len; tot_len += len; } @@ -16703,7 +16707,7 @@ db_hdf5_PutGroupelmap(DBfile *_dbfile, char const *name, FREE(intArray); /* build and write out fractional data array */ - fracsArray = (void *) malloc(tot_len * ((fracs_data_type==DB_FLOAT)?sizeof(float):sizeof(double))); + fracsArray = (void *) calloc(tot_len, ((fracs_data_type==DB_FLOAT)?sizeof(float):sizeof(double))); tot_len = 0; for (i = 0; i < num_segments; i++) { @@ -16774,7 +16778,9 @@ db_hdf5_GetGroupelmap(DBfile *_dbfile, char const *name) hid_t o=-1, attr=-1; int _objtype, i, j, n; int *intArray = 0; + int intArray_size; void *fracsArray = 0; + int fracsArray_size; DBgroupelmap *gm=NULL; DBgroupelmap_mt m; @@ -16819,18 +16825,30 @@ db_hdf5_GetGroupelmap(DBfile *_dbfile, char const *name) gm->segment_ids = (int *)db_hdf5_comprd(dbfile, m.segment_ids, 1); /* read the map segment data */ - gm->segment_data = (int **) malloc(m.num_segments * sizeof(int*)); + gm->segment_data = (int **) calloc(m.num_segments, sizeof(int*)); intArray = (int *)db_hdf5_comprd(dbfile, m.segment_data, 1); + + /* Acquire actual file size of segment_data */ + intArray_size = db_hdf5_GetVarLength(_dbfile, m.segment_data); + n = 0; for (i = 0; (i < m.num_segments) && intArray && gm->segment_lengths; i++) { int sl = gm->segment_lengths[i]; - gm->segment_data[i] = 0; if (sl > 0) { gm->segment_data[i] = (int*) malloc(sl * sizeof(int)); for (j = 0; j < sl; j++) + { + if (n >= intArray_size) + { + FREE(intArray); + DBFreeGroupelmap(gm); + db_perror("segment_lengths", E_MALFORMED, me); + return NULL; + } gm->segment_data[i][j] = intArray[n++]; + } } } FREE(intArray); @@ -16838,22 +16856,29 @@ db_hdf5_GetGroupelmap(DBfile *_dbfile, char const *name) intArray = (int *)db_hdf5_comprd(dbfile, m.frac_lengths, 1); if (intArray) { - gm->segment_fracs = (void **)malloc(m.num_segments * sizeof(void*)); + gm->segment_fracs = (void **)calloc(m.num_segments, sizeof(void*)); fracsArray = db_hdf5_comprd(dbfile, m.segment_fracs, 1); + + /* Acquire actual file size of segment_data */ + fracsArray_size = db_hdf5_GetVarLength(_dbfile, m.segment_fracs); n = 0; for (i = 0; (i < m.num_segments) && fracsArray; i++) { int len = intArray[i]; - if (len <= 0) - { - gm->segment_fracs[i] = 0; continue; - } gm->segment_fracs[i] = malloc(len * ((gm->fracs_data_type==DB_FLOAT)?sizeof(float):sizeof(double))); for (j = 0; j < len; j++) { + if (n >= fracsArray_size) + { + FREE(intArray); + FREE(fracsArray); + DBFreeGroupelmap(gm); + db_perror("segment_fracs", E_MALFORMED, me); + return NULL; + } if (gm->fracs_data_type == DB_FLOAT) { float *pfa = (float *) fracsArray; diff --git a/src/pdb_drv/silo_pdb.c b/src/pdb_drv/silo_pdb.c index 1250cbba..55cc7103 100644 --- a/src/pdb_drv/silo_pdb.c +++ b/src/pdb_drv/silo_pdb.c @@ -640,8 +640,7 @@ PJ_GetObject(PDBfile *file_in, char const *objname_in, PJcomplist *tobj, int exp sprintf(err_str,"PJ_get_group: Probably no such object \"%s\".",objname); FREE(varname); FREE(filename); - db_perror(err_str, E_CALLFAIL, me); - return -1; + return db_perror(err_str, E_CALLFAIL, me); } /* Check object type before we do any allocations */ @@ -665,8 +664,7 @@ PJ_GetObject(PDBfile *file_in, char const *objname_in, PJcomplist *tobj, int exp cached_group->type, objname_in, DBGetObjtypeName(expected_dbtype)); FREE(varname); FREE(filename); - db_perror(error, E_NOTFOUND, me); - return -1; + return db_perror(error, E_NOTFOUND, me); } } @@ -706,7 +704,8 @@ PJ_GetObject(PDBfile *file_in, char const *objname_in, PJcomplist *tobj, int exp /* Walk through the object, putting the data into the appropriate memory * locations. */ - for (i = 0; i < tobj->num; i++) + error = 0; + for (i = 0; i < tobj->num && error == 0; i++) { for (j = 0; j < cached_group->ncomponents; j++) { @@ -719,12 +718,17 @@ PJ_GetObject(PDBfile *file_in, char const *objname_in, PJcomplist *tobj, int exp * pointer (i.e., ptr[i]). If not alloced, address * is already in the ptr[i] element. */ - PJ_ReadVariable(file, cached_group->pdb_names[j], - tobj->type[i], (int)tobj->alloced[i], - (tobj->alloced[i]) ? - (char **)&tobj->ptr[i] : - (char **)tobj->ptr[i]); - + if (!PJ_ReadVariable(file, cached_group->pdb_names[j], + tobj->type[i], (int)tobj->alloced[i], + tobj->nelmts[i], + (tobj->alloced[i]) ? + (char **)&tobj->ptr[i] : + (char **)tobj->ptr[i])) + { + error = 1; + db_perror(cached_group->pdb_names[j], E_CALLFAIL, me); + break; + } } } } @@ -740,7 +744,7 @@ PJ_GetObject(PDBfile *file_in, char const *objname_in, PJcomplist *tobj, int exp FREE (varname); - return 0; + return error==1?-1:0; } /*---------------------------------------------------------------------- @@ -974,7 +978,8 @@ INTERNAL int PJ_ReadVariable(PDBfile *file, char *name_in, /*Name of variable to read */ int req_datatype, /*Requested datatype for variable */ - int alloced, /*has space already been allocated? */ + int alloced, /*Has space already been allocated? */ + int nelmts, /*Size of allocation in # elements */ char **var) /*Address of ptr to store data into */ { int num, size, i, okay; @@ -1101,6 +1106,12 @@ PJ_ReadVariable(PDBfile *file, (void)pdb_getvarinfo(file, name, tname, &num, &size, 0); + if (alloced && nelmts >= 0 && num > nelmts) + { + FREE(name); + return FALSE; + } + /* If not already allocated, and is not a pointered var, allocate */ if (!alloced && num > 0) { if (forcing) @@ -3302,7 +3313,7 @@ db_pdb_GetMaterial(DBfile *_dbfile, /*DB file pointer */ INIT_OBJ(&tmp_obj); DEFINE_OBJ("ndims", &tmpmm.ndims, DB_INT); - DEFINE_OBJ("dims", tmpmm.dims, DB_INT); + DEFINE_OBN("dims", tmpmm.dims, DB_INT, NELMTS(tmpmm.dims)); DEFINE_OBJ("major_order", &tmpmm.major_order, DB_INT); DEFINE_OBJ("origin", &tmpmm.origin, DB_INT); DEFALL_OBJ("meshid", &tmpmm.meshname, DB_CHAR); @@ -3339,6 +3350,13 @@ db_pdb_GetMaterial(DBfile *_dbfile, /*DB file pointer */ } *mm = tmpmm; + if (mm->ndims < 0 || mm->ndims > NELMTS(mm->dims)) + { + DBFreeMaterial(mm); + db_perror("ndims", E_BADARGS, me); + return NULL; + } + _DBQQCalcStride(mm->stride, mm->dims, mm->ndims, mm->major_order); /* If we have material names, restore it to an array of names. In the @@ -3452,7 +3470,7 @@ db_pdb_GetMatspecies (DBfile *_dbfile, /*DB file pointer */ DEFALL_OBJ("matname", &tmpmm.matname, DB_CHAR); DEFINE_OBJ("ndims", &tmpmm.ndims, DB_INT); - DEFINE_OBJ("dims", tmpmm.dims, DB_INT); + DEFINE_OBN("dims", tmpmm.dims, DB_INT, NELMTS(tmpmm.dims)); DEFINE_OBJ("major_order", &tmpmm.major_order, DB_INT); DEFINE_OBJ("datatype", &tmpmm.datatype, DB_INT); DEFINE_OBJ("nmat", &tmpmm.nmat, DB_INT); @@ -4772,8 +4790,8 @@ db_pdb_GetPointmesh (DBfile *_dbfile, char const *objname) DEFINE_OBJ("origin", &tmppm.origin, DB_INT); DEFINE_OBJ("gnznodtype", &tmppm.gnznodtype, DB_INT); - DEFINE_OBJ("min_extents", tmppm.min_extents, DB_FLOAT); - DEFINE_OBJ("max_extents", tmppm.max_extents, DB_FLOAT); + DEFINE_OBN("min_extents", tmppm.min_extents, DB_FLOAT, NELMTS(tmppm.min_extents)); + DEFINE_OBN("max_extents", tmppm.max_extents, DB_FLOAT, NELMTS(tmppm.max_extents)); DEFINE_OBJ("guihide", &tmppm.guihide, DB_INT); DEFALL_OBJ("mrgtree_name", &tmppm.mrgtree_name, DB_CHAR); @@ -4934,6 +4952,13 @@ db_pdb_GetPointvar (DBfile *_dbfile, char const *objname) return NULL; *mv = tmpmv; + if (mv->nvals < 0 || (mv->nvals > 1 && (mv->nvals > NELMTS(_ptvalstr)))) + { + DBFreeMeshvar(mv); + db_perror("nvals", E_MALFORMED, me); + return NULL; + } + /* * Read the remainder of the object: loop over all values * associated with this variable. @@ -5084,12 +5109,12 @@ db_pdb_GetQuadmesh (DBfile *_dbfile, char const *objname) DEFALL_OBJ("units1", &tmpqm.units[1], DB_CHAR); DEFALL_OBJ("units2", &tmpqm.units[2], DB_CHAR); - DEFINE_OBJ("dims", tmpqm.dims, DB_INT); - DEFINE_OBJ("min_index", tmpqm.min_index, DB_INT); - DEFINE_OBJ("max_index", tmpqm.max_index, DB_INT); - DEFINE_OBJ("min_extents", tmpqm.min_extents, DB_FLOAT); - DEFINE_OBJ("max_extents", tmpqm.max_extents, DB_FLOAT); - DEFINE_OBJ("baseindex", tmpqm.base_index, DB_INT); + DEFINE_OBN("dims", tmpqm.dims, DB_INT, NELMTS(tmpqm.dims)); + DEFINE_OBN("min_index", tmpqm.min_index, DB_INT, NELMTS(tmpqm.min_index)); + DEFINE_OBN("max_index", tmpqm.max_index, DB_INT, NELMTS(tmpqm.max_index)); + DEFINE_OBN("min_extents", tmpqm.min_extents, DB_FLOAT, NELMTS(tmpqm.min_extents)); + DEFINE_OBN("max_extents", tmpqm.max_extents, DB_FLOAT, NELMTS(tmpqm.max_extents)); + DEFINE_OBN("baseindex", tmpqm.base_index, DB_INT, NELMTS(tmpqm.base_index)); DEFINE_OBJ("guihide", &tmpqm.guihide, DB_INT); DEFALL_OBJ("mrgtree_name", &tmpqm.mrgtree_name, DB_CHAR); @@ -5108,6 +5133,12 @@ db_pdb_GetQuadmesh (DBfile *_dbfile, char const *objname) return NULL; *qm = tmpqm; + if (qm->ndims < 0 || qm->ndims > NELMTS(qm->dims)) + { + DBFreeQuadmesh(qm); + return NULL; + } + if (tmpannum) { qm->alt_nodenum_vars = DBStringListToStringArray(tmpannum, 0, !skipFirstSemicolon); @@ -5239,10 +5270,10 @@ db_pdb_GetQuadvar (DBfile *_dbfile, char const *objname) DEFINE_OBJ("missing_value", &tmpqv.missing_value, DB_DOUBLE); /* Arrays */ - DEFINE_OBJ("min_index", tmpqv.min_index, DB_INT); - DEFINE_OBJ("max_index", tmpqv.max_index, DB_INT); - DEFINE_OBJ("dims", tmpqv.dims, DB_INT); - DEFINE_OBJ("align", tmpqv.align, DB_FLOAT); + DEFINE_OBN("min_index", tmpqv.min_index, DB_INT, NELMTS(tmpqv.min_index)); + DEFINE_OBN("max_index", tmpqv.max_index, DB_INT, NELMTS(tmpqv.max_index)); + DEFINE_OBN("dims", tmpqv.dims, DB_INT, NELMTS(tmpqv.dims)); + DEFINE_OBN("align", tmpqv.align, DB_FLOAT, NELMTS(tmpqv.align)); DEFALL_OBJ("region_pnames", &rpnames, DB_CHAR); /* Arrays that PJ_GetObject must allocate. */ @@ -5260,6 +5291,20 @@ db_pdb_GetQuadvar (DBfile *_dbfile, char const *objname) return NULL; *qv = tmpqv; + if (qv->ndims < 0 || qv->ndims > NELMTS(qv->dims)) + { + DBFreeQuadvar(qv); + db_perror("ndims", E_MALFORMED, me); + return NULL; + } + + if (qv->nvals < 0 || qv->nvals > NELMTS(_valstr)) + { + DBFreeQuadvar(qv); + db_perror("nvals", E_MALFORMED, me); + return NULL; + } + /* * Read the remainder of the object: loop over all values * associated with this variable. @@ -5286,7 +5331,7 @@ db_pdb_GetQuadvar (DBfile *_dbfile, char const *objname) if (PJ_InqForceSingle()) qv->datatype = DB_FLOAT; - for (i = 0; i < qv->nvals; i++) { + for (i = 0; i < MIN(NELMTS(_valstr),qv->nvals); i++) { DEFALL_OBJ(_valstr[i], &qv->vals[i], DB_FLOAT); if (qv->mixlen > 0) { @@ -5410,8 +5455,8 @@ db_pdb_GetUcdmesh (DBfile *_dbfile, char const *meshname) DEFINE_OBJ("nnodes", &tmpum.nnodes, DB_INT); DEFINE_OBJ("origin", &tmpum.origin, DB_INT); - DEFINE_OBJ("min_extents", tmpum.min_extents, DB_FLOAT); - DEFINE_OBJ("max_extents", tmpum.max_extents, DB_FLOAT); + DEFINE_OBN("min_extents", tmpum.min_extents, DB_FLOAT, NELMTS(tmpum.min_extents)); + DEFINE_OBN("max_extents", tmpum.max_extents, DB_FLOAT, NELMTS(tmpum.max_extents)); if (DBGetDataReadMask2File(_dbfile) & DBUMCoords) { @@ -5747,6 +5792,13 @@ db_pdb_GetUcdvar (DBfile *_dbfile, char const *objname) return NULL; *uv = tmpuv; + if (uv->nvals < 0 || uv->nvals > NELMTS(_valstr)) + { + DBFreeUcdvar(uv); + db_perror("nvals", E_MALFORMED, me); + return NULL; + } + /* * Read the remainder of the object: loop over all values * associated with this variable. @@ -5846,8 +5898,8 @@ db_pdb_GetCsgmesh (DBfile *_dbfile, char const *meshname) DEFINE_OBJ("ndims", &tmpcsgm.ndims, DB_INT); DEFINE_OBJ("nbounds", &tmpcsgm.nbounds, DB_INT); DEFINE_OBJ("origin", &tmpcsgm.origin, DB_INT); - DEFINE_OBJ("min_extents", tmpcsgm.min_extents, DB_DOUBLE); - DEFINE_OBJ("max_extents", tmpcsgm.max_extents, DB_DOUBLE); + DEFINE_OBN("min_extents", tmpcsgm.min_extents, DB_DOUBLE, NELMTS(tmpcsgm.min_extents)); + DEFINE_OBN("max_extents", tmpcsgm.max_extents, DB_DOUBLE, NELMTS(tmpcsgm.max_extents)); DEFALL_OBJ("label0", &tmpcsgm.labels[0], DB_CHAR); DEFALL_OBJ("label1", &tmpcsgm.labels[1], DB_CHAR); DEFALL_OBJ("label2", &tmpcsgm.labels[2], DB_CHAR); @@ -5935,9 +5987,9 @@ db_pdb_GetCsgvar (DBfile *_dbfile, char const *objname) DBfile_pdb *dbfile = (DBfile_pdb *) _dbfile; PJcomplist tmp_obj; char tmp[256]; - static char *me = "db_pdb_GetCsgvar"; + static char *me = "db_pdb_GetCsgvar"; char *rpnames = NULL; - DBcsgvar tmpcsgv; + DBcsgvar tmpcsgv; PJcomplist *_tcl; memset(&tmpcsgv, 0, sizeof(DBcsgvar)); @@ -5960,30 +6012,40 @@ db_pdb_GetCsgvar (DBfile *_dbfile, char const *objname) if (PJ_GetObject(dbfile->pdb, (char*) objname, &tmp_obj, DB_CSGVAR) < 0) return NULL; + if ((csgv = DBAllocCsgvar()) == NULL) + return NULL; + *csgv = tmpcsgv; + + if (csgv->nvals < 0 || csgv->nvals > NELMTS(_valstr)) + { + DBFreeCsgvar(csgv); + db_perror("nvals", E_MALFORMED, me); + return NULL; + } /* * Read the remainder of the object: loop over all values * associated with this variable. */ - if ((tmpcsgv.nvals > 0) && (DBGetDataReadMask2File(_dbfile) & DBCSGVData)) { + if ((csgv->nvals > 0) && (DBGetDataReadMask2File(_dbfile) & DBCSGVData)) { INIT_OBJ(&tmp_obj); - tmpcsgv.vals = ALLOC_N(void *, tmpcsgv.nvals); + csgv->vals = ALLOC_N(void *, csgv->nvals); - if (tmpcsgv.datatype == 0) { + if (csgv->datatype == 0) { strcpy(tmp, objname); strcat(tmp, "_data"); - if ((tmpcsgv.datatype = db_pdb_GetVarDatatype(dbfile->pdb, tmp)) < 0) { + if ((csgv->datatype = db_pdb_GetVarDatatype(dbfile->pdb, tmp)) < 0) { /* Not found. Assume float. */ - tmpcsgv.datatype = DB_FLOAT; + csgv->datatype = DB_FLOAT; } } - if ((tmpcsgv.datatype == DB_DOUBLE) && PJ_InqForceSingle()) - tmpcsgv.datatype = DB_FLOAT; + if ((csgv->datatype == DB_DOUBLE) && PJ_InqForceSingle()) + csgv->datatype = DB_FLOAT; - for (i = 0; i < tmpcsgv.nvals; i++) { - DEFALL_OBJ(_valstr[i], &tmpcsgv.vals[i], tmpcsgv.datatype); + for (i = 0; i < csgv->nvals; i++) { + DEFALL_OBJ(_valstr[i], &csgv->vals[i], csgv->datatype); } PJ_GetObject(dbfile->pdb, (char*) objname, &tmp_obj, 0); @@ -5991,20 +6053,16 @@ db_pdb_GetCsgvar (DBfile *_dbfile, char const *objname) if (rpnames != NULL) { - tmpcsgv.region_pnames = DBStringListToStringArray(rpnames, 0, !skipFirstSemicolon); + csgv->region_pnames = DBStringListToStringArray(rpnames, 0, !skipFirstSemicolon); FREE(rpnames); } - if (tmpcsgv.missing_value == DB_MISSING_VALUE_NOT_SET) - tmpcsgv.missing_value = 0.0; - else if (tmpcsgv.missing_value == 0.0) - tmpcsgv.missing_value = DB_MISSING_VALUE_NOT_SET; - - if ((csgv = DBAllocCsgvar()) == NULL) - return NULL; + if (csgv->missing_value == DB_MISSING_VALUE_NOT_SET) + csgv->missing_value = 0.0; + else if (csgv->missing_value == 0.0) + csgv->missing_value = DB_MISSING_VALUE_NOT_SET; - tmpcsgv.name = STRDUP(objname); - *csgv = tmpcsgv; + csgv->name = STRDUP(objname); return (csgv); } @@ -7396,6 +7454,8 @@ db_pdb_GetGroupelmap(DBfile *_dbfile, char const *name) void *fracsArray = NULL; DBgroupelmap tmpgm; PJcomplist *_tcl; + int segData_size = 0; + int fracsArray_size = 0; memset(&tmpgm, 0, sizeof(DBgroupelmap)); INIT_OBJ(&tmp_obj); @@ -7414,18 +7474,36 @@ db_pdb_GetGroupelmap(DBfile *_dbfile, char const *name) gm = (DBgroupelmap*) calloc(1,sizeof(DBgroupelmap)); *gm = tmpgm; + /* Independently acquire size of segment_data */ + if (gm->num_segments > 0) + { + char compname[256]; + snprintf(compname, sizeof(compname), "%s_%s", name, "segment_data"); + segData_size = db_pdb_GetVarLength(_dbfile, compname); + } + /* unflatten the segment data */ - gm->segment_data = (int **) malloc(gm->num_segments * sizeof(int*)); + gm->segment_data = (int **) calloc(gm->num_segments, sizeof(int*)); n = 0; for (i = 0; i < gm->num_segments; i++) { int sl = gm->segment_lengths[i]; - gm->segment_data[i] = 0; if (sl > 0) { gm->segment_data[i] = (int*) malloc(sl * sizeof(int)); for (j = 0; j < sl; j++) + { + if (n >= segData_size) + { + db_perror("segment_data", E_MALFORMED, me); + DBFreeGroupelmap(gm); + FREE(segData); + FREE(fracLengths); + FREE(fracsArray); + return NULL; + } gm->segment_data[i][j] = segData[n++]; + } } } FREE(segData); @@ -7433,21 +7511,29 @@ db_pdb_GetGroupelmap(DBfile *_dbfile, char const *name) /* unflatten frac data if we have it */ if (fracLengths != NULL) { - gm->segment_fracs = (void **)malloc(gm->num_segments * sizeof(void*)); + /* Independently acquire size of segment_fracs */ + char compname[256]; + snprintf(compname, sizeof(compname), "%s_%s", name, "segment_fracs"); + fracsArray_size = db_pdb_GetVarLength(_dbfile, compname); + + gm->segment_fracs = (void **)calloc(gm->num_segments, sizeof(void*)); n = 0; for (i = 0; i < gm->num_segments; i++) { int len = fracLengths[i]; - if (len <= 0) - { - gm->segment_fracs[i] = 0; - continue; - } - gm->segment_fracs[i] = malloc(len * ((gm->fracs_data_type==DB_FLOAT)?sizeof(float):sizeof(double))); for (j = 0; j < len; j++) { + if (n >= fracsArray_size) + { + db_perror("segment_fracs", E_MALFORMED, me); + DBFreeGroupelmap(gm); + FREE(fracLengths); + FREE(fracsArray); + return NULL; + } + if (gm->fracs_data_type == DB_FLOAT) { float *pfa = (float *) fracsArray; @@ -7524,6 +7610,13 @@ db_pdb_GetMrgvar(DBfile *_dbfile, char const *objname) mrgv = (DBmrgvar *) calloc(1, sizeof(DBmrgvar)); *mrgv = tmpmrgv; + if (mrgv->ncomps < 0 || mrgv->ncomps > NELMTS(_valstr)) + { + DBFreeMrgvar(mrgv); + db_perror("ncomps", E_MALFORMED, me); + return NULL; + } + INIT_OBJ(&tmp_obj); mrgv->data = ALLOC_N(void *, mrgv->ncomps); @@ -12140,7 +12233,7 @@ db_pdb_PutGroupelmap(DBfile *dbfile, char const *name, tot_len = 0; for (i = 0; i < num_segments; i++) - tot_len += segment_lengths[i]; + tot_len += (segment_lengths[i]>0?segment_lengths[i]:0); if (tot_len) { intArray = (int *) malloc(tot_len * sizeof(int)); @@ -12165,7 +12258,11 @@ db_pdb_PutGroupelmap(DBfile *dbfile, char const *name, intArray = (int *) malloc(num_segments * sizeof(int)); for (i = 0; i < num_segments; i++) { - int len = segment_fracs[i] == 0 ? 0 : segment_lengths[i]; + int len; + if (segment_fracs[i] == 0) + len = 0; + else + len = (segment_lengths[i]>0?segment_lengths[i]:0); intArray[i] = len; tot_len += len; } @@ -12177,7 +12274,7 @@ db_pdb_PutGroupelmap(DBfile *dbfile, char const *name, /* build and write out fractional data array */ if (tot_len) { - fracsArray = (void *) malloc(tot_len * ((fracs_data_type==DB_FLOAT)?sizeof(float):sizeof(double))); + fracsArray = (void *) calloc(tot_len, ((fracs_data_type==DB_FLOAT)?sizeof(float):sizeof(double))); tot_len = 0; for (i = 0; i < num_segments; i++) { @@ -12210,7 +12307,7 @@ db_pdb_PutGroupelmap(DBfile *dbfile, char const *name, } /*------------------------------------------------------------- - * Write material object to output file. Request that underlying + * Write object to output file. Request that underlying * memory be freed (the 'TRUE' argument.) *-------------------------------------------------------------*/ DBWriteObject(dbfile, obj, TRUE); diff --git a/src/pdb_drv/silo_pdb_private.h b/src/pdb_drv/silo_pdb_private.h index 175180fa..5c7c660d 100644 --- a/src/pdb_drv/silo_pdb_private.h +++ b/src/pdb_drv/silo_pdb_private.h @@ -99,6 +99,7 @@ typedef struct { void *ptr[80]; /* Address of component value */ int type[80]; /* Datatype of component */ unsigned char alloced[80]; /* Sentinel: 1 == space already alloc'd */ + int nelmts[80]; /* Size of allocation in # of elements */ int num; /* Number of components */ } PJcomplist; @@ -327,13 +328,15 @@ PRIVATE void db_InitDefvars (DBoptlist const *); */ #define MAXNAME 256 #define INIT_OBJ(A) (_tcl=(A),_tcl->num=0) -#define DEFINE_OBJ(NM,PP,TYP) DEF_OBJ(NM,PP,TYP,1) -#define DEFALL_OBJ(NM,PP,TYP) DEF_OBJ(NM,PP,TYP,0) -#define DEF_OBJ(NM,PP,TYP,AL) { \ +#define DEFINE_OBJ(NM,PP,TYP) DEF_OBJ(NM,PP,TYP,1,1) +#define DEFALL_OBJ(NM,PP,TYP) DEF_OBJ(NM,PP,TYP,0,0) +#define DEFINE_OBN(NM,PP,TYP,N) DEF_OBJ(NM,PP,TYP,1,N) +#define DEF_OBJ(NM,PP,TYP,AL,N) { \ (_tcl->name[_tcl->num]=(NM), \ _tcl->ptr[_tcl->num]=(void*)(PP), \ _tcl->type[_tcl->num]=(TYP), \ - _tcl->alloced[_tcl->num]=(AL)); \ + _tcl->alloced[_tcl->num]=(AL), \ + _tcl->nelmts[_tcl->num]=(N)); \ _tcl->num++;} /*------------------------------------------------------------------------- @@ -357,7 +360,7 @@ PRIVATE int PJ_InqForceSingle (void); PRIVATE void PJ_NoCache ( void ); PRIVATE void *PJ_GetComponent (PDBfile *, char const *, char const *); PRIVATE int PJ_GetComponentType (PDBfile *, char const *, char const *); -PRIVATE int PJ_ReadVariable (PDBfile *, char *, int, int, char **); +PRIVATE int PJ_ReadVariable (PDBfile *, char *, int, int, int, char **); PRIVATE int PJ_get_group (PDBfile *, char const *, PJgroup **); PRIVATE PJgroup *PJ_make_group (char *, char *, char **, char **, int); diff --git a/src/silo/silo.c b/src/silo/silo.c index 63ca9e0e..5e415269 100644 --- a/src/silo/silo.c +++ b/src/silo/silo.c @@ -212,7 +212,8 @@ PUBLIC char *_db_err_list[] = "Although this appears to be an HDF5 file,\n" "it does not appear to be one produced by Silo\n" "and so cannot be open and read by Silo.", /* 36 */ - "File locking has prevented an operation." /* 37 */ + "File locking has prevented an operation.", /* 37 */ + "Object read from file is malformed." /* 38 */ }; /* Table of contents object count */ @@ -9515,6 +9516,8 @@ DBPutMaterial( { int i, retval, is_empty = 1; int const zdims[10] = {0,0,0,0,0,0,0,0,0,0}; + DBmaterial dummy_mat; + char emsg[64]; API_BEGIN2("DBPutMaterial", int, -1, name) { if (!dbfile) @@ -9529,8 +9532,14 @@ DBPutMaterial( API_ERROR("overwrite not allowed", E_NOOVERWRITE); if (nmat < 0) API_ERROR("nmat<0", E_BADARGS); - if (ndims < 0) - API_ERROR("ndims<0", E_BADARGS); + if (ndims < 0 || ndims > NELMTS(dummy_mat.dims)) + { + snprintf(emsg, sizeof(emsg), "ndims (%d) out of range [0...%d]", + ndims, NELMTS(dummy_mat.dims)); + API_ERROR(emsg, E_BADARGS); + } + if (ndims > NELMTS(dummy_mat.dims)) + API_ERROR("ndims>max", E_BADARGS); if (!dims) API_ERROR("dims=0", E_BADARGS); for (i = 0; i < ndims; i++) diff --git a/src/silo/silo.h.in b/src/silo/silo.h.in index 0afc9ee5..6737a82f 100644 --- a/src/silo/silo.h.in +++ b/src/silo/silo.h.in @@ -606,6 +606,7 @@ typedef enum { #define E_OBJBUFFULL 35 /*No more temp. buffer space for object */ #define E_NOSILOHDF5 36 /*Not HDF5 file produced by silo */ #define E_FILELOCKING 37 /*File locking prevented operation */ +#define E_MALFORMED 38 /*Object in file is malformed */ #define E_NERRORS 50 /* Definitions for MAJOR_ORDER */ diff --git a/src/silo/silo_private.h b/src/silo/silo_private.h index 05cf3700..aa7ccaba 100644 --- a/src/silo/silo_private.h +++ b/src/silo/silo_private.h @@ -367,7 +367,7 @@ typedef struct context_t { #define MAXDIMS_VARWRITE 7 #define OVER_WRITE 0x0001 /*overwrite DBobject */ #define FREE_MEM 0x0002 /*free DBobject memory */ -#define NELMTS(X) (sizeof(X)/sizeof(X[0])) /*Number of elements */ +#define NELMTS(X) ((int)(sizeof(X)/sizeof((X)[0]))) /*Number of elements */ #define STR_EQUAL(S1,S2) (!strcmp((S1),(S2))) #define STR_BEGINSWITH(S,P) ((strstr((S),(P))==(S))?1:0) diff --git a/tests/buf_overrun_objs.c b/tests/buf_overrun_objs.c new file mode 100644 index 00000000..d84ff928 --- /dev/null +++ b/tests/buf_overrun_objs.c @@ -0,0 +1,142 @@ +/* +Copyright (C) 1994-2016 Lawrence Livermore National Security, LLC. +LLNL-CODE-425250. +All rights reserved. + +This file is part of Silo. For details, see silo.llnl.gov. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the disclaimer below. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the disclaimer (as noted + below) in the documentation and/or other materials provided with + the distribution. + * Neither the name of the LLNS/LLNL nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE +LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This work was produced at Lawrence Livermore National Laboratory under +Contract No. DE-AC52-07NA27344 with the DOE. + +Neither the United States Government nor Lawrence Livermore National +Security, LLC nor any of their employees, makes any warranty, express +or implied, or assumes any liability or responsibility for the +accuracy, completeness, or usefulness of any information, apparatus, +product, or process disclosed, or represents that its use would not +infringe privately-owned rights. + +Any reference herein to any specific commercial products, process, or +services by trade name, trademark, manufacturer or otherwise does not +necessarily constitute or imply its endorsement, recommendation, or +favoring by the United States Government or Lawrence Livermore +National Security, LLC. The views and opinions of authors expressed +herein do not necessarily state or reflect those of the United States +Government or Lawrence Livermore National Security, LLC, and shall not +be used for advertising or product endorsement purposes. +*/ + +#include "silo.h" +#include +#include +#ifdef _WIN32 +#include +#endif +#include + +static void build_objs(DBfile *dbfile); + +int main(int argc, char **argv) +{ + DBfile *dbfile; + int i, driver = DB_PDB; + char *filename = "buf_overrun_objs.pdb"; + int show_all_errors = FALSE; + + for (i=1; i 0) + segData[i] = (int *) calloc(segLens[i], sizeof(int)); + else + segData[i] = 0; + } + + DBPutGroupelmap(dbfile, "glmap", numsegs, segTypes, segLens, + 0, (int const * const *) segData, 0, 0, 0); + + free(segTypes); + free(segLens); + free(segData); + } +} diff --git a/tests/obj.c b/tests/obj.c index 4fe45060..37f0567f 100644 --- a/tests/obj.c +++ b/tests/obj.c @@ -66,17 +66,17 @@ int main(int argc, char **argv) { DBfile *dbfile; int i, driver = DB_PDB; - char *filename = "ucd.pdb"; + char *filename = "userdef_obj.pdb"; int show_all_errors = FALSE; int allow_long_str_components = FALSE; for (i=1; i