mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
Fixed bug "adding a bad _FillValue" bug (NCF-190). Fixed minor bugs
reported by static analysis, including memory leak in ncdump, missing size_t cast for chunk cache. Fixed various doc problems, including byte vs. char issues, missing NC_UBYTE in type list, needed link to "Building with Windows" page.
This commit is contained in:
parent
9e8146f873
commit
8d53da4826
@ -10,6 +10,11 @@ VERSION COMMENTS
|
||||
|
||||
Replaced the oc library with oc2.0
|
||||
|
||||
Prevented adding an invalid _FillValue attribute to a
|
||||
variable (with nonmatching type or multiple values),
|
||||
to avoid later error when any record variable is
|
||||
extended.
|
||||
[NCF-190]
|
||||
|
||||
4.2.1 Released 2012-07-18
|
||||
|
||||
|
@ -43,7 +43,7 @@ extern "C" {
|
||||
|
||||
/* The following are use internally in support of user-defines
|
||||
* types. They are also the class returned by nc_inq_user_type. */
|
||||
#define NC_VLEN 13 /**< vlen types */
|
||||
#define NC_VLEN 13 /**< vlen (variable-length) types */
|
||||
#define NC_OPAQUE 14 /**< opaque types */
|
||||
#define NC_ENUM 15 /**< enum types */
|
||||
#define NC_COMPOUND 16 /**< compound types */
|
||||
|
@ -37,7 +37,7 @@ apply.
|
||||
\param value Pointer to one or more values.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
\returns ::NC_EINVAL Trying to set global _FillValue.
|
||||
\returns ::NC_EINVAL More than one value for _FillValue or trying to set global _FillValue.
|
||||
\returns ::NC_ENOTVAR Couldn't find varid.
|
||||
\returns ::NC_EBADTYPE Fill value and var must be same type.
|
||||
\returns ::NC_ENOMEM Out of memory
|
||||
@ -85,7 +85,7 @@ apply.
|
||||
\param value Pointer to one or more values.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
\returns ::NC_EINVAL Trying to set global _FillValue.
|
||||
\returns ::NC_EINVAL More than one value for _FillValue or trying to set global _FillValue.
|
||||
\returns ::NC_ENOTVAR Couldn't find varid.
|
||||
\returns ::NC_EBADTYPE Fill value and var must be same type.
|
||||
\returns ::NC_ENOMEM Out of memory
|
||||
@ -153,8 +153,11 @@ or if the space required to store the attribute is greater than
|
||||
before, the netCDF dataset must be in define mode.
|
||||
|
||||
With netCDF-4 files, nc_put_att will notice if you are writing a
|
||||
_Fill_Value_ attribute, and will tell the HDF5 layer to use the
|
||||
specified fill value for that variable.
|
||||
_FillValue attribute, and will tell the HDF5 layer to use the
|
||||
specified fill value for that variable. With either classic or
|
||||
netCDF-4 files, a _FillValue attribute will be checked for validity,
|
||||
to make sure it has only one value and that its type matches the type
|
||||
of the associated variable.
|
||||
|
||||
Although it's possible to create attributes of all types, text and
|
||||
double attributes are adequate for most purposes.
|
||||
@ -176,7 +179,7 @@ apply.
|
||||
\param value Pointer to one or more values.
|
||||
|
||||
\returns ::NC_NOERR No error.
|
||||
\returns ::NC_EINVAL Trying to set global _FillValue.
|
||||
\returns ::NC_EINVAL More than one value for _FillValue or trying to set global _FillValue.
|
||||
\returns ::NC_ENOTVAR Couldn't find varid.
|
||||
\returns ::NC_EBADTYPE Fill value and var must be same type.
|
||||
\returns ::NC_ENOMEM Out of memory
|
||||
|
@ -322,8 +322,10 @@ nc4_put_att(int ncid, NC_FILE_INFO_T *nc, int varid, const char *name,
|
||||
NC_TYPE_INFO_T *type_info;
|
||||
int size;
|
||||
|
||||
/* Fill value must be same type. */
|
||||
/* Fill value must be same type and have exactly one value */
|
||||
if (att->xtype != var->xtype)
|
||||
return NC_EBADTYPE;
|
||||
if (att->len != 1)
|
||||
return NC_EINVAL;
|
||||
|
||||
/* If we already wrote to the dataset, then return an error. */
|
||||
|
@ -129,7 +129,7 @@ nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems,
|
||||
float real_preemption = H5D_CHUNK_CACHE_W0_DEFAULT;
|
||||
|
||||
if (size >= 0)
|
||||
real_size = size * MEGABYTE;
|
||||
real_size = ((size_t) size) * MEGABYTE;
|
||||
|
||||
if (nelems >= 0)
|
||||
real_nelems = nelems;
|
||||
|
@ -2932,8 +2932,8 @@ The length of an attribute is the number of data values assigned to
|
||||
it. Multiple values are assigned to non-character attributes by
|
||||
separating the values with commas (','). All values assigned to an
|
||||
attribute must be of the same type. In the classic data model,
|
||||
character arrays are used for textual information, so the length of a
|
||||
character attribute is the number of character values, and an array of
|
||||
character arrays are used for textual information. The length of a
|
||||
character attribute is the number of bytes, and an array of
|
||||
character values can be represented in string notation. In the
|
||||
enhanced data model of netCDF-4, variable-length strings are available
|
||||
as a primitive type, and the length of a string attribute is the
|
||||
|
@ -2,7 +2,7 @@
|
||||
Documentation for getting and building netCDF
|
||||
|
||||
This document is for getting and building the netCDF C library and
|
||||
utilities, version 4.2.1. Other libraries that depend on the netCDF C
|
||||
utilities, version 4.2.1.1. Other libraries that depend on the netCDF C
|
||||
library, such as the Fortran and C++ libraries, are available as
|
||||
separate distributions that can be built and installed after the C
|
||||
library is successfully installed. The netCDF-Java library is also a
|
||||
@ -47,6 +47,7 @@ full functionality. (See \ref architecture).
|
||||
- \ref build_classic
|
||||
- \ref build_hdf4
|
||||
- \ref build_parallel
|
||||
- \ref build_windows
|
||||
- \ref configure_options
|
||||
|
||||
\page build_default Building with NetCDF-4 and the Remote Data Client
|
||||
@ -238,6 +239,12 @@ netCDF-4 libraries:
|
||||
cc -o myapp myapp.c `nc-config --cflags --libs`
|
||||
\endverbatim
|
||||
|
||||
\page build_windows Building with Windows
|
||||
|
||||
See the <a href="http://www.unidata.ucar.edu/netcdf/windows_netcdf/"
|
||||
>NetCDF for Windows </a> page for Current information about building
|
||||
netCDF on Windows or downloading prebuilt Windows binaries.
|
||||
|
||||
\page configure_options ./configure options
|
||||
|
||||
Note: --disable prefix indicates that the option is normally enabled.
|
||||
|
@ -1703,7 +1703,7 @@ The atomic external types supported by the netCDF interface are:
|
||||
@end multitable
|
||||
|
||||
* These types are available only for netCDF-4 format files. All the
|
||||
unsigned ints (except NC_CHAR), the 64-bit ints, and string
|
||||
unsigned ints, the 64-bit ints, and string
|
||||
type are for netCDF-4 files only.
|
||||
|
||||
These types were chosen to provide a reasonably wide range of
|
||||
|
@ -10,7 +10,8 @@ a user-defined data type (see \ref user_defined_types).
|
||||
|
||||
The atomic external types supported by the netCDF interface are:
|
||||
- ::NC_BYTE 8-bit signed integer
|
||||
- ::NC_CHAR 8-bit unsigned integer
|
||||
- ::NC_UBYTE 8-bit unsigned integer
|
||||
- ::NC_CHAR 8-bit character byte
|
||||
- ::NC_SHORT 16-bit signed integer
|
||||
- ::NC_USHORT 16-bit unsigned integer *
|
||||
- ::NC_INT (or ::NC_LONG) 32-bit signed integer
|
||||
@ -285,4 +286,4 @@ precision value you can write to a double variable is the largest
|
||||
double-precision number representable on your system that is less than
|
||||
2 to the 1024th power.
|
||||
|
||||
*/
|
||||
*/
|
||||
|
@ -2370,6 +2370,23 @@ main(int argc, char **argv)
|
||||
if (nc_inq_varnatts(ncid, 0, &natts)) ERR;
|
||||
if (natts != 2) ERR;
|
||||
if (nc_copy_att(ncid, NC_GLOBAL, A1_NAME, ncid, 0)) ERR;
|
||||
|
||||
/* Also test for fix of another bug, allowing invalid _FillValue
|
||||
* attribute (not of same type as variable or with 0 values or more
|
||||
* than 1 value) to be created. */
|
||||
{
|
||||
static const int var_FillValue_atts[] = {42, -99} ;
|
||||
float var_FillValue_att = -99 ;
|
||||
/* This should return error, because attribute has too many values */
|
||||
if (nc_put_att_int(ncid, varid, "_FillValue", NC_INT, 2, var_FillValue_atts)
|
||||
!= NC_EINVAL) ERR;
|
||||
/* This also should return error, because types don't match */
|
||||
if (nc_put_att_float(ncid, varid, "_FillValue", NC_FLOAT, 1, &var_FillValue_att)
|
||||
!= NC_EBADTYPE) ERR;
|
||||
/* This should succeed, _FillValue is valid */
|
||||
if (nc_put_att_int(ncid, varid, "_FillValue", NC_INT, 1, var_FillValue_atts)) ERR;
|
||||
}
|
||||
|
||||
if (nc_close(ncid)) ERR;
|
||||
|
||||
/* Reopen the file and check it. */
|
||||
|
@ -53,7 +53,21 @@ main()
|
||||
if (nc_inq_var(ncid, 1, NULL, NULL, &ndims, dimids_in, NULL)) ERR;
|
||||
if (ndims != 3 || dimids_in[0] != 0 || dimids_in[1] != 2 || dimids_in[2] != 1) ERR;
|
||||
|
||||
/* Read the record of non-existant data. */
|
||||
/* Also test for fix of another bug, allowing invalid _FillValue
|
||||
* attribute (not of same type as variable or with 0 values or more
|
||||
* than 1 value) to be created. */
|
||||
{
|
||||
static const float p_FillValue_atts[] = {NC_FILL_FLOAT, -99} ;
|
||||
int p_FillValue_att = -99 ;
|
||||
/* This should returns error, too many attribute vals */
|
||||
if (nc_put_att_float(ncid, p_id, "_FillValue", NC_FLOAT, 2, p_FillValue_atts) != NC_EINVAL) ERR;
|
||||
/* This also should return error, wrong type */
|
||||
if (nc_put_att_int(ncid, p_id, "_FillValue", NC_INT, 1, &p_FillValue_att) != NC_EBADTYPE) ERR;
|
||||
/* This should succeed, _FillValue is valid */
|
||||
if (nc_put_att_float(ncid, p_id, "_FillValue", NC_FLOAT, 1, p_FillValue_atts)) ERR;
|
||||
}
|
||||
|
||||
/* Read the record of non-existent data. */
|
||||
if (nc_get_vara(ncid, 1, cor, edg, P_data)) ERR;
|
||||
for (i = 0; i < LEN; i++)
|
||||
if (P_data[i] != NC_FILL_FLOAT) ERR;
|
||||
|
@ -1147,6 +1147,7 @@ chars_tostring(
|
||||
*cp++ = '"';
|
||||
*cp++ = '\0';
|
||||
sbuf_cpy(sbuf, sout);
|
||||
free(sout);
|
||||
return sbuf_len(sbuf);
|
||||
}
|
||||
|
||||
@ -1885,7 +1886,7 @@ get_type_name(int ncid, nc_type type, char *name)
|
||||
{
|
||||
#ifdef USE_NETCDF4
|
||||
if (is_user_defined_type(type)) {
|
||||
nc_inq_user_type(ncid, type, name, NULL, NULL, NULL, NULL);
|
||||
NC_CHECK(nc_inq_user_type(ncid, type, name, NULL, NULL, NULL, NULL));
|
||||
} else {
|
||||
strncpy(name, prim_type_name(type), NC_MAX_NAME + 1);
|
||||
}
|
||||
@ -1907,7 +1908,7 @@ void
|
||||
print_type_name(int locid, int typeid) {
|
||||
char *ename;
|
||||
#ifdef USE_NETCDF4
|
||||
char name[NC_MAX_NAME];
|
||||
char name[NC_MAX_NAME+1];
|
||||
int type_inherited = 0;
|
||||
int curlocid; /* group we are searching in */
|
||||
int parent_groupid = locid;
|
||||
@ -1921,6 +1922,7 @@ print_type_name(int locid, int typeid) {
|
||||
if(is_user_defined_type(typeid)) {
|
||||
/* determine if type is inherited, that is if defined in this
|
||||
* group or any ancestor group */
|
||||
name[NC_MAX_NAME] = '\0';
|
||||
strncpy(name,nctypes[typeid]->name,NC_MAX_NAME);
|
||||
do {
|
||||
curlocid = parent_groupid;
|
||||
|
Loading…
Reference in New Issue
Block a user