From 121ff469561a69449204792eae18afecbaaa2b56 Mon Sep 17 00:00:00 2001 From: wkliao Date: Tue, 12 Mar 2024 18:21:55 -0500 Subject: [PATCH 1/3] check header size against INT_MAX --- src/drivers/ncmpio/ncmpio_header_put.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/drivers/ncmpio/ncmpio_header_put.c b/src/drivers/ncmpio/ncmpio_header_put.c index ca6591933..bc09ac870 100644 --- a/src/drivers/ncmpio/ncmpio_header_put.c +++ b/src/drivers/ncmpio/ncmpio_header_put.c @@ -14,6 +14,7 @@ #include #endif #include +#include /* INT_MAX */ #include @@ -80,7 +81,8 @@ hdr_put_NC_dim(bufferinfo *pbp, /* copy dim_length */ if (pbp->version < 5) { /* TODO: Isn't checking dimension size already done in def_dim()? */ - if (dimp->size != (uint)dimp->size) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) + if (dimp->size > INT_MAX) + DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) err = ncmpix_put_uint32((void**)(&pbp->pos), (uint)dimp->size); } else @@ -174,7 +176,8 @@ hdr_put_NC_attrV(bufferinfo *pbp, sz = attrp->nelems * xsz; padding = attrp->xsz - sz; - if (sz != (size_t) sz) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) + if (sz > INT_MAX) + DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) memcpy(pbp->pos, attrp->xvalue, (size_t)sz); pbp->pos = (void *)((char *)pbp->pos + sz); @@ -212,7 +215,7 @@ hdr_put_NC_attr(bufferinfo *pbp, /* copy nelems */ if (pbp->version < 5) { - if (attrp->nelems != (uint)attrp->nelems) + if (attrp->nelems > INT_MAX) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)attrp->nelems); } @@ -365,7 +368,8 @@ hdr_put_NC_var(bufferinfo *pbp, * in CDF-2 and CDF-5, it is a 64-bit integer */ if (pbp->version == 1) { - if (varp->begin != (uint)varp->begin) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) + if (varp->begin > INT_MAX) + DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)varp->begin); } else @@ -473,7 +477,8 @@ ncmpio_hdr_put_NC(NC *ncp, void *buf) /* copy numrecs, number of records */ nrecs = ncp->numrecs; if (ncp->format < 5) { - if (nrecs != (uint)nrecs) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) + if (nrecs > INT_MAX) + DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) status = ncmpix_put_uint32((void**)(&putbuf.pos), (uint)nrecs); } else { @@ -535,7 +540,7 @@ int ncmpio_write_header(NC *ncp) /* copy header object to write buffer */ status = ncmpio_hdr_put_NC(ncp, buf); - if (ncp->xsz != (int)ncp->xsz) { + if (ncp->xsz > INT_MAX) { NCI_Free(buf); DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) } From 830295ccc20e75d01b2626ae8ac6bae15c8079be Mon Sep 17 00:00:00 2001 From: wkliao Date: Tue, 12 Mar 2024 18:22:21 -0500 Subject: [PATCH 2/3] Dimension size limit should be INT_MAX According to NetCDF CDF 1 and 2 file format specification, the maximal dimension size should be INT_MAX, i.e. 2^31-1, . NetCDF file format specification: netcdf_file = header data header = magic numrecs dim_list gatt_list var_list dim_list = ABSENT | NC_DIMENSION nelems [dim ...] dim = name dim_length dim_length = NON_NEG NON_NEG = INT = <32-bit signed integer, Bigendian, two's complement> Note for variable size, the maximal is 2^31-3 for CDF-1 2^32-3 for CDF-2 2^63-3 for CDF-5 Variable size is calculated internally in PnetCDF. Therefor, the variable size is limited to the space available in bytes. -3 is due to the 4-byte upward alignment. Also, note vsize defined in the file header format is not used. --- src/dispatchers/dimension.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/dispatchers/dimension.c b/src/dispatchers/dimension.c index b48d73421..8a662e08b 100644 --- a/src/dispatchers/dimension.c +++ b/src/dispatchers/dimension.c @@ -10,6 +10,7 @@ #include #include +#include /* INT_MAX */ #include #include @@ -57,9 +58,8 @@ ncmpi_def_dim(int ncid, /* IN: file ID */ /* MPI_Offset is usually a signed value, but serial netcdf uses size_t. * In 1999 ISO C standard, size_t is an unsigned integer type of at least * 16 bit. */ - if (pncp->format == NC_FORMAT_CDF2) { /* CDF-2 format, max is 2^32-4 */ - if (size > NC_MAX_UINT - 3 || (size < 0)) - /* "-3" handles rounded-up size */ + if (pncp->format == NC_FORMAT_CDF2) { /* CDF-2 format, max is INT_MAX */ + if (size > INT_MAX || (size < 0)) err = NC_EDIMSIZE; } else if (pncp->format == NC_FORMAT_CDF5) { /* CDF-5 format */ if (size < 0) @@ -68,9 +68,8 @@ ncmpi_def_dim(int ncid, /* IN: file ID */ pncp->format == NC_FORMAT_NETCDF4_CLASSIC) { /* NetCDF-4 format */ if (size < 0) err = NC_EDIMSIZE; - } else { /* CDF-1 format, max is 2^31-4 */ - if (size > NC_MAX_INT - 3 || (size < 0)) - /* "-3" handles rounded-up size */ + } else { /* CDF-1 format, max is INT_MAX */ + if (size > NC_MAX_INT || (size < 0)) err = NC_EDIMSIZE; } if (err != NC_NOERR) { From 117d1096565c449080329362386f5c8ff8d59558 Mon Sep 17 00:00:00 2001 From: wkliao Date: Tue, 12 Mar 2024 18:32:11 -0500 Subject: [PATCH 3/3] test dimension size limits --- src/dispatchers/dimension.c | 7 ++- src/drivers/ncmpio/ncmpio_header_put.c | 13 +++-- test/cdf_format/dim_cdf12.c | 71 +++++++++++++------------- test/testcases/tst_dimsizes.c | 24 ++++++--- 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/dispatchers/dimension.c b/src/dispatchers/dimension.c index 8a662e08b..d1a912926 100644 --- a/src/dispatchers/dimension.c +++ b/src/dispatchers/dimension.c @@ -10,7 +10,6 @@ #include #include -#include /* INT_MAX */ #include #include @@ -58,8 +57,8 @@ ncmpi_def_dim(int ncid, /* IN: file ID */ /* MPI_Offset is usually a signed value, but serial netcdf uses size_t. * In 1999 ISO C standard, size_t is an unsigned integer type of at least * 16 bit. */ - if (pncp->format == NC_FORMAT_CDF2) { /* CDF-2 format, max is INT_MAX */ - if (size > INT_MAX || (size < 0)) + if (pncp->format == NC_FORMAT_CDF2) { /* CDF-2 format, max is NC_MAX_INT */ + if (size > NC_MAX_INT || (size < 0)) err = NC_EDIMSIZE; } else if (pncp->format == NC_FORMAT_CDF5) { /* CDF-5 format */ if (size < 0) @@ -68,7 +67,7 @@ ncmpi_def_dim(int ncid, /* IN: file ID */ pncp->format == NC_FORMAT_NETCDF4_CLASSIC) { /* NetCDF-4 format */ if (size < 0) err = NC_EDIMSIZE; - } else { /* CDF-1 format, max is INT_MAX */ + } else { /* CDF-1 format, max is NC_MAX_INT */ if (size > NC_MAX_INT || (size < 0)) err = NC_EDIMSIZE; } diff --git a/src/drivers/ncmpio/ncmpio_header_put.c b/src/drivers/ncmpio/ncmpio_header_put.c index bc09ac870..0dac72b63 100644 --- a/src/drivers/ncmpio/ncmpio_header_put.c +++ b/src/drivers/ncmpio/ncmpio_header_put.c @@ -14,7 +14,6 @@ #include #endif #include -#include /* INT_MAX */ #include @@ -81,7 +80,7 @@ hdr_put_NC_dim(bufferinfo *pbp, /* copy dim_length */ if (pbp->version < 5) { /* TODO: Isn't checking dimension size already done in def_dim()? */ - if (dimp->size > INT_MAX) + if (dimp->size > NC_MAX_INT) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) err = ncmpix_put_uint32((void**)(&pbp->pos), (uint)dimp->size); } @@ -176,7 +175,7 @@ hdr_put_NC_attrV(bufferinfo *pbp, sz = attrp->nelems * xsz; padding = attrp->xsz - sz; - if (sz > INT_MAX) + if (sz > NC_MAX_INT) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) memcpy(pbp->pos, attrp->xvalue, (size_t)sz); pbp->pos = (void *)((char *)pbp->pos + sz); @@ -215,7 +214,7 @@ hdr_put_NC_attr(bufferinfo *pbp, /* copy nelems */ if (pbp->version < 5) { - if (attrp->nelems > INT_MAX) + if (attrp->nelems > NC_MAX_INT) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)attrp->nelems); } @@ -368,7 +367,7 @@ hdr_put_NC_var(bufferinfo *pbp, * in CDF-2 and CDF-5, it is a 64-bit integer */ if (pbp->version == 1) { - if (varp->begin > INT_MAX) + if (varp->begin > NC_MAX_INT) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)varp->begin); } @@ -477,7 +476,7 @@ ncmpio_hdr_put_NC(NC *ncp, void *buf) /* copy numrecs, number of records */ nrecs = ncp->numrecs; if (ncp->format < 5) { - if (nrecs > INT_MAX) + if (nrecs > NC_MAX_INT) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) status = ncmpix_put_uint32((void**)(&putbuf.pos), (uint)nrecs); } @@ -540,7 +539,7 @@ int ncmpio_write_header(NC *ncp) /* copy header object to write buffer */ status = ncmpio_hdr_put_NC(ncp, buf); - if (ncp->xsz > INT_MAX) { + if (ncp->xsz > NC_MAX_INT) { NCI_Free(buf); DEBUG_RETURN_ERROR(NC_EINTOVERFLOW) } diff --git a/test/cdf_format/dim_cdf12.c b/test/cdf_format/dim_cdf12.c index d3405f86e..70ca26a7a 100644 --- a/test/cdf_format/dim_cdf12.c +++ b/test/cdf_format/dim_cdf12.c @@ -55,7 +55,6 @@ #include #include /* strcpy() */ #include /* basename() */ -#include #include #include #include @@ -98,27 +97,27 @@ int main(int argc, char** argv) /* create a new CDF-1 file ----------------------------------------------*/ cmode = NC_CLOBBER; - /* max dimension size for CDF-1 file is 2^31-3 = 2147483647 - 3 */ + /* max dimension size for CDF-1 file is NC_MAX_INT */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); + err = ncmpi_def_dim(ncid, "Y", (MPI_Offset)1+NC_MAX_INT, &dimid[0]); EXP_ERR(NC_EDIMSIZE) - err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR /* use the max dimension size to define a 1D variable */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR /* use the max dimension size to define a 1D variable, followed by - * another variable to make the file size > 2147483647 */ + * another variable to make the file size > NC_MAX_INT */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR @@ -129,8 +128,8 @@ int main(int argc, char** argv) /* use the max dimension size - 1024 to define a 1D variable, followed * by another variable to make the file size < 2147483647 */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX-1024, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT-1024, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR @@ -138,11 +137,11 @@ int main(int argc, char** argv) err = ncmpi_close(ncid); CHECK_ERR /* define the first variable of type short that makes the file size > - * 2147483647. error should be reported in ncmpi_enddef() or + * NC_MAX_INT. error should be reported in ncmpi_enddef() or * ncmpi_close() */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_CHAR, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); @@ -150,16 +149,16 @@ int main(int argc, char** argv) /* define two variables to make the file size just < 2147483647 */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX-3-512-8, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT-512-8, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR - /* define two variables to make the file size just > 2147483647 */ + /* define two variables to make the file size just > NC_MAX_INT */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT/2+1, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); @@ -168,27 +167,27 @@ int main(int argc, char** argv) /* create a new CDF-2 file ----------------------------------------------*/ cmode = NC_CLOBBER | NC_64BIT_OFFSET; - /* max dimension size for CDF-2 file is 2^32-3 = 4294967295 - 3 */ + /* max dimension size for CDF-2 file is NC_MAX_INT */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", UINT_MAX, &dimid[0]); + err = ncmpi_def_dim(ncid, "Y", (MPI_Offset)1+NC_MAX_INT, &dimid[0]); EXP_ERR(NC_EDIMSIZE) - err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR /* use the max dimension size to define a 1D variable */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR /* use the max dimension size to define a 1D variable, followed by - * another variable to make the file size > 4294967295 */ + * another variable to make the file size > 2 * NC_MAX_INT */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR @@ -200,25 +199,25 @@ int main(int argc, char** argv) * 4294967295. error should be reported in ncmpi_enddef() or * ncmpi_close() */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); EXP_ERR(NC_EVARSIZE) - /* define 2 1D int variables of dimension size > max */ + /* define 2 1D int variables of dimension size > NC_MAX_INT */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); EXP_ERR(NC_EVARSIZE) err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT/2+1, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); @@ -229,8 +228,8 @@ int main(int argc, char** argv) */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR err = ncmpi_def_dim(ncid, "Z", NC_UNLIMITED, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX/64, &dimid[1]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 64, &dimid[2]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT/64, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 64, &dimid[2]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_INT, 3, dimid, &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 3, dimid, &varid); CHECK_ERR err = ncmpi_close(ncid); @@ -239,8 +238,8 @@ int main(int argc, char** argv) /* test large record variable that is not defined last */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR err = ncmpi_def_dim(ncid, "Z", NC_UNLIMITED, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX/64, &dimid[1]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 64, &dimid[2]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT/64, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 64, &dimid[2]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_INT, 3, dimid, &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 2, dimid, &varid); CHECK_ERR err = ncmpi_close(ncid); @@ -250,8 +249,8 @@ int main(int argc, char** argv) * output file can be tested by ncvalidator in wrap_runs.sh */ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR - err = ncmpi_def_dim(ncid, "Y", INT_MAX/2, &dimid[0]); CHECK_ERR - err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR + err = ncmpi_def_dim(ncid, "Y", NC_MAX_INT/2, &dimid[0]); CHECK_ERR + err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); CHECK_ERR err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR err = ncmpi_close(ncid); CHECK_ERR diff --git a/test/testcases/tst_dimsizes.c b/test/testcases/tst_dimsizes.c index 5e06c483e..13a8e6fad 100644 --- a/test/testcases/tst_dimsizes.c +++ b/test/testcases/tst_dimsizes.c @@ -25,14 +25,24 @@ #include -#define DIMMAXCLASSIC (NC_MAX_INT - 3) -#define DIMMAX64OFFSET (NC_MAX_UINT - 3) +#define DIMMAXCLASSIC NC_MAX_INT +#define DIMMAX64OFFSET NC_MAX_INT #define DIMMAX64DATA NC_MAX_INT64 /* - * NC_CLASSIC => NC_INT_MAX - 3 - * NC_64BIT_OFFSET => NC_UINT_MAX - 3 - * NC_64BIT_DATA => NC_INT64_MAX + * NetCDF file format specification: + * netcdf_file = header data + * header = magic numrecs dim_list gatt_list var_list + * dim_list = ABSENT | NC_DIMENSION nelems [dim ...] + * dim = name dim_length + * dim_length = NON_NEG + * NON_NEG = + * INT = <32-bit signed integer, Bigendian, two's complement> + * + * Therefore, the max dimension size are: + * NC_CLASSIC Max dimension size is NC_INT_MAX + * NC_64BIT_OFFSET Max dimension size is NC_INT_MAX + * NC_64BIT_DATA Max dimension size is NC_INT64_MAX * Note that for NC_64BIT_DATA, the max dimension size is different from netCDF * library. This is because PnetCDF uses MPI_Offset for dimension size and * MPI_Offset is a signed long long. @@ -72,7 +82,7 @@ main(int argc, char **argv) err = ncmpi_def_dim(ncid, "testdim", dimsize, &dimid); CHECK_ERR dimsize = -1; err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE) - dimsize = DIMMAXCLASSIC+1; + dimsize = (MPI_Offset)DIMMAXCLASSIC+1; err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE) err = ncmpi_close(ncid); CHECK_ERR @@ -92,7 +102,7 @@ main(int argc, char **argv) err = ncmpi_def_dim(ncid, "testdim", dimsize, &dimid); CHECK_ERR dimsize = -1; err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE) - dimsize = DIMMAX64OFFSET+1; + dimsize = (MPI_Offset)DIMMAX64OFFSET+1; err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE) err = ncmpi_close(ncid); CHECK_ERR