From 22d00ce23f0c39789d146e440d8b251b0c6b2268 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 25 Aug 2004 03:30:32 -0500 Subject: [svn-r9155] Purpose: Bug fix (sorta) Description: Change reading of "missing" chunks from datasets with undefined fill values to not overwrite the application buffer with random garbage from memory. Note that this is almost the same, since whatever garbage the application had in those locations will still be there... Platforms tested: FreeBSD 4.10 (sleipnir) IRIX64 6.5 (modi4) h5committested --- release_docs/RELEASE.txt | 3 ++ src/H5Distore.c | 82 +++++++++++++++++++++++++++++++++++- test/dsets.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++ test/istore.c | 14 +++---- 4 files changed, 196 insertions(+), 9 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 9f6ec10..888590c 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -174,6 +174,9 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - Changed H5Dread() to not overwrite data in an application's buffer + with garbage when accessing a chunked dataset with an undefined + fill value and an unwritten chunk is uncountered. QAK - 2004/08/25 - Fixed error which could cause a core dump when a type conversion routine was registered after a compound datatype had been converted and then an equivalment compound datatype was converted diff --git a/src/H5Distore.c b/src/H5Distore.c index cbd7a0f..5182d29 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1821,9 +1821,7 @@ H5D_istore_readvv(H5F_t *f, const struct H5D_dxpl_cache_t *dxpl_cache, hid_t dxp { H5D_istore_ud1_t udata; /*B-tree pass-through */ haddr_t chunk_addr; /* Chunk address on disk */ -#ifndef NDEBUG size_t u; /* Local index variables */ -#endif ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5D_istore_readvv, FAIL); @@ -1886,6 +1884,86 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a unsigned idx_hint=0; /* Cache index hint */ ssize_t naccessed; /* Number of bytes accessed in chunk */ + /* If the chunk address is not defined, check if the fill value is + * undefined also. If both situations hold, don't bother copying + * values to the destination buffer, since they will just be + * garbage. + * + * Ideally, this will eventually be checked at a higher level and + * the entire I/O operation on the chunk will be skipped. -QAK + */ + if(!H5F_addr_defined(chunk_addr)) { + const H5O_fill_t *fill=&(dset->dcpl_cache.fill); /* Fill value info */ + H5D_fill_time_t fill_time=dset->dcpl_cache.fill_time; /* Fill time */ + H5D_fill_value_t fill_status; + H5D_rdcc_t *rdcc = &(dset->cache.chunk);/*raw data chunk cache*/ + hbool_t found = FALSE; /*already in cache? */ + + /* Check if the chunk is in the cache (but hasn't been written to disk yet) */ + if (rdcc->nslots>0) { + unsigned idx=H5D_HASH(dset,store->chunk.index); /* Cache entry index */ + H5D_rdcc_ent_t *ent = rdcc->slot[idx]; /* Cache entry */ + + /* Potential match... */ + if (ent) { + for (u=0, found=TRUE; ulayout.u.chunk.ndims; u++) { + if (store->chunk.offset[u]!=ent->offset[u]) { + found = FALSE; + break; + } /* end if */ + } /* end for */ + } /* end if */ + } /* end if */ + + /* If the chunk is in the cache, then it must have valid data */ + if(!found) { + /* Check if the fill value is defined */ + if (H5P_is_fill_value_defined(fill, &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined"); + + /* If we are never to return fill values, or if we would return them + * but they aren't set, process the entire set of I/O vectors and + * get out now. + */ + if(fill_time==H5D_FILL_TIME_NEVER || + (fill_time==H5D_FILL_TIME_IFSET && fill_status!=H5D_FILL_VALUE_USER_DEFINED)) { + size_t size; /* Size of sequence in bytes */ + size_t v; /* Local index variable */ + ssize_t bytes_processed=0; /* Eventual return value */ + + /* Work through all the sequences */ + for(u=*mem_curr_seq, v=*chunk_curr_seq; u=5) { + if(rdata[u]!=911) { + printf(" Line %d: Incorrect value, rdata[%u]=%d\n",__LINE__,(unsigned)u,rdata[u]); + TEST_ERROR; + } /* end if */ + } /* end if */ + else { + if(rdata[u]!=wdata[u]) { + printf(" Line %d: Incorrect value, wdata[%u]=%d, rdata[%u]=%d\n",__LINE__,(unsigned)u,wdata[u],(unsigned)u,rdata[u]); + TEST_ERROR; + } /* end if */ + } /* end else */ + } /* end for */ + + /* Close everything */ + if(H5Pclose(dcpl)<0) TEST_ERROR; + if(H5Sclose(s)<0) TEST_ERROR; + if(H5Dclose(d)<0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dcpl); + H5Dclose(d); + H5Sclose(s); + } H5E_END_TRY; + return -1; +} /* end test_zero_dims() */ + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests the dataset interface (H5D) @@ -3745,6 +3850,7 @@ main(void) nerrors += test_filter_delete(file)<0 ?1:0; nerrors += test_filters_endianess()<0 ?1:0; nerrors += test_zero_dims(file)<0 ?1:0; + nerrors += test_missing_chunk(file)<0 ?1:0; if (H5Fclose(file)<0) goto error; if (nerrors) goto error; diff --git a/test/istore.c b/test/istore.c index 0830ff4..f7baf31 100644 --- a/test/istore.c +++ b/test/istore.c @@ -298,17 +298,17 @@ test_extend(hid_t f, const char *prefix, #if 0 if (0 == ctr) fprintf(stderr,"\n"); - fprintf(stderr," Insert: ctr=%d, corner=(%d", ctr, offset[0]); + fprintf(stderr," Insert: ctr=%lu, corner=(%ld", (unsigned long)ctr, (long)offset[0]); if (ndims > 1) - fprintf(stderr,",%d", offset[1]); + fprintf(stderr,",%ld", (long)offset[1]); if (ndims > 2) - fprintf(stderr,",%d", offset[2]); - fprintf(stderr,"), size=(%d", size[0]); + fprintf(stderr,",%ld", (long)offset[2]); + fprintf(stderr,"), size=(%lu", (unsigned long)size[0]); if (ndims > 1) - fprintf(stderr,",%d", size[1]); + fprintf(stderr,",%lu", (unsigned long)size[1]); if (ndims > 2) - fprintf(stderr,",%d", size[2]); - fprintf(stderr,"), %d element%s", nelmts, 1 == nelmts ? "" : "s"); + fprintf(stderr,",%lu", (unsigned long)size[2]); + fprintf(stderr,"), %lu element%s", (unsigned long)nelmts, 1 == nelmts ? "" : "s"); if (0 == nelmts) fprintf(stderr," *SKIPPED*"); fprintf(stderr,"\n"); -- cgit v0.12