mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
Fix memory leaks re utf8_normalize
This commit is contained in:
parent
1f6264273e
commit
225453f12f
138
libsrc/attr.m4
138
libsrc/attr.m4
@ -118,29 +118,29 @@ new_NC_attr(
|
||||
nc_type type,
|
||||
size_t nelems)
|
||||
{
|
||||
NC_string *strp;
|
||||
NC_attr *attrp;
|
||||
char *name;
|
||||
int stat;
|
||||
NC_string *strp = NULL;
|
||||
NC_attr *attrp = NULL;
|
||||
char *name = NULL;
|
||||
int stat = NC_NOERR;
|
||||
|
||||
stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
|
||||
if(stat != NC_NOERR)
|
||||
return NULL;
|
||||
goto done;
|
||||
assert(name != NULL && *name != 0);
|
||||
|
||||
strp = new_NC_string(strlen(name), name);
|
||||
free(name);
|
||||
if(strp == NULL)
|
||||
return NULL;
|
||||
goto done;
|
||||
|
||||
attrp = new_x_NC_attr(strp, type, nelems);
|
||||
if(attrp == NULL)
|
||||
{
|
||||
free_NC_string(strp);
|
||||
return NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return(attrp);
|
||||
done:
|
||||
if(name) free(name);
|
||||
return (attrp);
|
||||
}
|
||||
|
||||
|
||||
@ -345,36 +345,34 @@ NC_attrarray0(NC3_INFO* ncp, int varid)
|
||||
NC_attr **
|
||||
NC_findattr(const NC_attrarray *ncap, const char *uname)
|
||||
{
|
||||
NC_attr **attrpp;
|
||||
NC_attr **attrpp = NULL;
|
||||
size_t attrid;
|
||||
size_t slen;
|
||||
char *name;
|
||||
int stat;
|
||||
char *name = NULL;
|
||||
int stat = NC_NOERR;
|
||||
|
||||
assert(ncap != NULL);
|
||||
|
||||
if(ncap->nelems == 0)
|
||||
return NULL;
|
||||
|
||||
attrpp = (NC_attr **) ncap->value;
|
||||
goto done;
|
||||
|
||||
/* normalized version of uname */
|
||||
stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
|
||||
if(stat != NC_NOERR)
|
||||
return NULL; /* TODO: need better way to indicate no memory */
|
||||
goto done; /* TODO: need better way to indicate no memory */
|
||||
slen = strlen(name);
|
||||
|
||||
attrpp = (NC_attr **) ncap->value;
|
||||
for(attrid = 0; attrid < ncap->nelems; attrid++, attrpp++)
|
||||
{
|
||||
if(strlen((*attrpp)->name->cp) == slen &&
|
||||
strncmp((*attrpp)->name->cp, name, slen) == 0)
|
||||
{
|
||||
free(name);
|
||||
return(attrpp); /* Normal return */
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
free(name);
|
||||
return(NULL);
|
||||
attrpp = NULL; /* not found */
|
||||
done:
|
||||
if(name) free(name);
|
||||
return (attrpp); /* Normal return */
|
||||
}
|
||||
|
||||
|
||||
@ -501,71 +499,65 @@ NC3_inq_att(int ncid,
|
||||
int
|
||||
NC3_rename_att( int ncid, int varid, const char *name, const char *unewname)
|
||||
{
|
||||
int status;
|
||||
NC *nc;
|
||||
NC3_INFO* ncp;
|
||||
NC_attrarray *ncap;
|
||||
NC_attr **tmp;
|
||||
NC_attr *attrp;
|
||||
int status = NC_NOERR;
|
||||
NC *nc = NULL;
|
||||
NC3_INFO* ncp = NULL;
|
||||
NC_attrarray *ncap = NULL;
|
||||
NC_attr **tmp = NULL;
|
||||
NC_attr *attrp = NULL;
|
||||
NC_string *newStr, *old;
|
||||
char *newname; /* normalized version */
|
||||
char *newname = NULL; /* normalized version */
|
||||
|
||||
/* start sortof inline clone of NC_lookupattr() */
|
||||
|
||||
/* sortof inline clone of NC_lookupattr() */
|
||||
status = NC_check_id(ncid, &nc);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
ncp = NC3_DATA(nc);
|
||||
|
||||
if(NC_readonly(ncp))
|
||||
return NC_EPERM;
|
||||
{status = NC_EPERM; goto done;}
|
||||
|
||||
ncap = NC_attrarray0(ncp, varid);
|
||||
if(ncap == NULL)
|
||||
return NC_ENOTVAR;
|
||||
{status = NC_ENOTVAR; goto done;}
|
||||
|
||||
status = NC_check_name(unewname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
|
||||
tmp = NC_findattr(ncap, name);
|
||||
if(tmp == NULL)
|
||||
return NC_ENOTATT;
|
||||
{status = NC_ENOTATT; goto done;}
|
||||
attrp = *tmp;
|
||||
/* end inline clone NC_lookupattr() */
|
||||
/* end inline clone NC_lookupattr() */
|
||||
|
||||
if(NC_findattr(ncap, unewname) != NULL)
|
||||
{
|
||||
/* name in use */
|
||||
return NC_ENAMEINUSE;
|
||||
}
|
||||
{status = NC_ENAMEINUSE; goto done;} /* name in use */
|
||||
|
||||
old = attrp->name;
|
||||
status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char**)&newname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
if(NC_indef(ncp))
|
||||
{
|
||||
newStr = new_NC_string(strlen(newname), newname);
|
||||
free(newname);
|
||||
if( newStr == NULL)
|
||||
return NC_ENOMEM;
|
||||
{status = NC_ENOMEM; goto done;}
|
||||
attrp->name = newStr;
|
||||
free_NC_string(old);
|
||||
return NC_NOERR;
|
||||
goto done;
|
||||
}
|
||||
/* else not in define mode */
|
||||
|
||||
/* If new name is longer than old, then complain,
|
||||
but otherwise, no change (test is same as set_NC_string)*/
|
||||
if(old->nchars < strlen(newname)) {
|
||||
free(newname);
|
||||
return NC_ENOTINDEFINE;
|
||||
}
|
||||
if(old->nchars < strlen(newname))
|
||||
{status = NC_ENOTINDEFINE; goto done;}
|
||||
|
||||
status = set_NC_string(old, newname);
|
||||
free(newname);
|
||||
if( status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
|
||||
set_NC_hdirty(ncp);
|
||||
|
||||
@ -573,43 +565,43 @@ NC3_rename_att( int ncid, int varid, const char *name, const char *unewname)
|
||||
{
|
||||
status = NC_sync(ncp);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return NC_NOERR;
|
||||
done:
|
||||
if(newname) free(newname);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
NC3_del_att(int ncid, int varid, const char *uname)
|
||||
{
|
||||
int status;
|
||||
NC *nc;
|
||||
NC3_INFO* ncp;
|
||||
NC_attrarray *ncap;
|
||||
NC_attr **attrpp;
|
||||
int status = NC_NOERR;
|
||||
NC *nc = NULL;
|
||||
NC3_INFO* ncp = NULL;
|
||||
NC_attrarray *ncap = NULL;
|
||||
NC_attr **attrpp = NULL;
|
||||
NC_attr *old = NULL;
|
||||
int attrid;
|
||||
size_t slen;
|
||||
char* name = NULL;
|
||||
|
||||
status = NC_check_id(ncid, &nc);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
ncp = NC3_DATA(nc);
|
||||
|
||||
if(!NC_indef(ncp))
|
||||
return NC_ENOTINDEFINE;
|
||||
{status = NC_ENOTINDEFINE; goto done;}
|
||||
|
||||
ncap = NC_attrarray0(ncp, varid);
|
||||
if(ncap == NULL)
|
||||
return NC_ENOTVAR;
|
||||
{status = NC_ENOTVAR; goto done;}
|
||||
|
||||
{
|
||||
char* name;
|
||||
int stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
|
||||
if(stat != NC_NOERR)
|
||||
return stat;
|
||||
status = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
|
||||
if(status != NC_NOERR)
|
||||
goto done;
|
||||
|
||||
/* sortof inline NC_findattr() */
|
||||
/* start sortof inline NC_findattr() */
|
||||
slen = strlen(name);
|
||||
|
||||
attrpp = (NC_attr **) ncap->value;
|
||||
@ -622,11 +614,9 @@ NC3_del_att(int ncid, int varid, const char *uname)
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
if( (size_t) attrid == ncap->nelems )
|
||||
return NC_ENOTATT;
|
||||
/* end inline NC_findattr() */
|
||||
{status = NC_ENOTATT; goto done;}
|
||||
/* end inline NC_findattr() */
|
||||
|
||||
/* shuffle down */
|
||||
for(attrid++; (size_t) attrid < ncap->nelems; attrid++)
|
||||
@ -640,7 +630,9 @@ NC3_del_att(int ncid, int varid, const char *uname)
|
||||
|
||||
free_NC_attr(old);
|
||||
|
||||
return NC_NOERR;
|
||||
done:
|
||||
if(name) free(name);
|
||||
return status;
|
||||
}
|
||||
|
||||
dnl
|
||||
|
51
libsrc/dim.c
51
libsrc/dim.c
@ -55,28 +55,29 @@ static NC_dim *
|
||||
new_NC_dim(const char *uname, size_t size)
|
||||
{
|
||||
NC_string *strp;
|
||||
NC_dim *dimp;
|
||||
int stat;
|
||||
char* name;
|
||||
NC_dim *dimp = NULL;
|
||||
int stat = NC_NOERR;
|
||||
char* name = NULL;
|
||||
|
||||
stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char **)&name);
|
||||
if(stat != NC_NOERR)
|
||||
return NULL;
|
||||
goto done;
|
||||
strp = new_NC_string(strlen(name), name);
|
||||
free(name);
|
||||
if(strp == NULL)
|
||||
return NULL;
|
||||
{stat = NC_ENOMEM; goto done;}
|
||||
|
||||
dimp = new_x_NC_dim(strp);
|
||||
if(dimp == NULL)
|
||||
{
|
||||
free_NC_string(strp);
|
||||
return NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dimp->size = size;
|
||||
|
||||
return(dimp);
|
||||
done:
|
||||
if(name) free(name);
|
||||
return (dimp);
|
||||
}
|
||||
|
||||
|
||||
@ -432,46 +433,45 @@ NC3_inq_dim(int ncid, int dimid, char *name, size_t *sizep)
|
||||
int
|
||||
NC3_rename_dim( int ncid, int dimid, const char *unewname)
|
||||
{
|
||||
int status;
|
||||
int status = NC_NOERR;
|
||||
NC *nc;
|
||||
NC3_INFO* ncp;
|
||||
int existid;
|
||||
NC_dim *dimp;
|
||||
char *newname; /* normalized */
|
||||
char *newname = NULL; /* normalized */
|
||||
NC_string *old = NULL;
|
||||
uintptr_t intdata;
|
||||
|
||||
|
||||
status = NC_check_id(ncid, &nc);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
ncp = NC3_DATA(nc);
|
||||
|
||||
if(NC_readonly(ncp))
|
||||
return NC_EPERM;
|
||||
{status = NC_EPERM; goto done;}
|
||||
|
||||
status = NC_check_name(unewname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
|
||||
existid = NC_finddim(&ncp->dims, unewname, &dimp);
|
||||
if(existid != -1)
|
||||
return NC_ENAMEINUSE;
|
||||
{status = NC_ENAMEINUSE; goto done;}
|
||||
|
||||
dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid);
|
||||
if(dimp == NULL)
|
||||
return NC_EBADDIM;
|
||||
{status = NC_EBADDIM; goto done;}
|
||||
|
||||
old = dimp->name;
|
||||
status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char **)&newname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
if(NC_indef(ncp))
|
||||
{
|
||||
NC_string *newStr = new_NC_string(strlen(newname), newname);
|
||||
free(newname);
|
||||
if(newStr == NULL)
|
||||
return NC_ENOMEM;
|
||||
{status = NC_ENOMEM; goto done;}
|
||||
|
||||
/* Remove old name from hashmap; add new... */
|
||||
NC_hashmapremove(ncp->dims.hashmap, old->cp, strlen(old->cp), NULL);
|
||||
@ -480,8 +480,7 @@ NC3_rename_dim( int ncid, int dimid, const char *unewname)
|
||||
intdata = dimid;
|
||||
NC_hashmapadd(ncp->dims.hashmap, intdata, newStr->cp, strlen(newStr->cp));
|
||||
free_NC_string(old);
|
||||
|
||||
return NC_NOERR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* else, not in define mode */
|
||||
@ -489,8 +488,7 @@ NC3_rename_dim( int ncid, int dimid, const char *unewname)
|
||||
/* If new name is longer than old, then complain,
|
||||
but otherwise, no change (test is same as set_NC_string)*/
|
||||
if(dimp->name->nchars < strlen(newname)) {
|
||||
free(newname);
|
||||
return NC_ENOTINDEFINE;
|
||||
{status = NC_ENOTINDEFINE; goto done;}
|
||||
}
|
||||
|
||||
/* Remove old name from hashmap; add new... */
|
||||
@ -499,9 +497,8 @@ NC3_rename_dim( int ncid, int dimid, const char *unewname)
|
||||
|
||||
/* WARNING: strlen(NC_string.cp) may be less than NC_string.nchars */
|
||||
status = set_NC_string(dimp->name, newname);
|
||||
free(newname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
|
||||
intdata = (uintptr_t)dimid;
|
||||
NC_hashmapadd(ncp->dims.hashmap, intdata, dimp->name->cp, strlen(dimp->name->cp));
|
||||
@ -512,8 +509,10 @@ NC3_rename_dim( int ncid, int dimid, const char *unewname)
|
||||
{
|
||||
status = NC_sync(ncp);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return NC_NOERR;
|
||||
done:
|
||||
if(newname) free(newname);
|
||||
return status;
|
||||
}
|
||||
|
70
libsrc/var.c
70
libsrc/var.c
@ -353,34 +353,32 @@ elem_NC_vararray(const NC_vararray *ncap, size_t elem)
|
||||
* Step thru NC_VARIABLE array, seeking match on name.
|
||||
* Return varid or -1 on not found.
|
||||
* *varpp is set to the appropriate NC_var.
|
||||
* Formerly (sort of)
|
||||
NC_hvarid
|
||||
* Formerly (sort of) NC_hvarid
|
||||
*/
|
||||
int
|
||||
NC_findvar(const NC_vararray *ncap, const char *uname, NC_var **varpp)
|
||||
{
|
||||
uintptr_t hash_var_id;
|
||||
int hash_var_id = -1;
|
||||
uintptr_t data;
|
||||
char *name;
|
||||
int stat;
|
||||
char *name = NULL;
|
||||
|
||||
assert(ncap != NULL);
|
||||
|
||||
if(ncap->nelems == 0)
|
||||
return -1;
|
||||
|
||||
goto done;
|
||||
|
||||
/* normalized version of uname */
|
||||
stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char **)&name);
|
||||
if(stat != NC_NOERR)
|
||||
return stat;
|
||||
if(nc_utf8_normalize((const unsigned char *)uname,(unsigned char **)&name))
|
||||
goto done;
|
||||
|
||||
if(NC_hashmapget(ncap->hashmap, name, strlen(name), &data) == 0)
|
||||
return -1;
|
||||
hash_var_id = data;
|
||||
free(name);
|
||||
goto done;
|
||||
|
||||
hash_var_id = (int)data;
|
||||
if (varpp != NULL)
|
||||
*varpp = ncap->value[hash_var_id];
|
||||
done:
|
||||
if(name != NULL) free(name);
|
||||
return(hash_var_id); /* Normal return */
|
||||
}
|
||||
|
||||
@ -734,71 +732,60 @@ NC3_inq_var(int ncid,
|
||||
int
|
||||
NC3_rename_var(int ncid, int varid, const char *unewname)
|
||||
{
|
||||
int status;
|
||||
int status = NC_NOERR;
|
||||
NC *nc;
|
||||
NC3_INFO* ncp;
|
||||
uintptr_t intdata;
|
||||
NC_var *varp;
|
||||
NC_string *old, *newStr;
|
||||
int other;
|
||||
char *newname; /* normalized */
|
||||
char *newname = NULL; /* normalized */
|
||||
|
||||
status = NC_check_id(ncid, &nc);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
ncp = NC3_DATA(nc);
|
||||
|
||||
if(NC_readonly(ncp))
|
||||
{
|
||||
return NC_EPERM;
|
||||
}
|
||||
{status = NC_EPERM; goto done;}
|
||||
|
||||
status = NC_check_name(unewname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
|
||||
/* check for name in use */
|
||||
other = NC_findvar(&ncp->vars, unewname, &varp);
|
||||
if(other != -1)
|
||||
{
|
||||
return NC_ENAMEINUSE;
|
||||
}
|
||||
{status = NC_ENAMEINUSE; goto done;}
|
||||
|
||||
status = NC_lookupvar(ncp, varid, &varp);
|
||||
if(status != NC_NOERR)
|
||||
{
|
||||
/* invalid varid */
|
||||
return status;
|
||||
}
|
||||
|
||||
goto done; /* invalid varid */
|
||||
|
||||
old = varp->name;
|
||||
status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char **)&newname);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
if(NC_indef(ncp))
|
||||
{
|
||||
/* Remove old name from hashmap; add new... */
|
||||
/* WARNING: strlen(NC_string.cp) may be less than NC_string.nchars */
|
||||
NC_hashmapremove(ncp->vars.hashmap,old->cp,strlen(old->cp),NULL);
|
||||
newStr = new_NC_string(strlen(newname),newname);
|
||||
free(newname);
|
||||
if(newStr == NULL)
|
||||
return(-1);
|
||||
{status = NC_ENOMEM; goto done;}
|
||||
varp->name = newStr;
|
||||
intdata = (uintptr_t)varid;
|
||||
NC_hashmapadd(ncp->vars.hashmap, intdata, varp->name->cp, strlen(varp->name->cp));
|
||||
free_NC_string(old);
|
||||
return NC_NOERR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* else, not in define mode */
|
||||
/* If new name is longer than old, then complain,
|
||||
but otherwise, no change (test is same as set_NC_string)*/
|
||||
if(varp->name->nchars < strlen(newname)) {
|
||||
free(newname);
|
||||
return NC_ENOTINDEFINE;
|
||||
}
|
||||
if(varp->name->nchars < strlen(newname))
|
||||
{status = NC_ENOTINDEFINE; goto done;}
|
||||
|
||||
/* WARNING: strlen(NC_string.cp) may be less than NC_string.nchars */
|
||||
/* Remove old name from hashmap; add new... */
|
||||
@ -806,10 +793,8 @@ NC3_rename_var(int ncid, int varid, const char *unewname)
|
||||
|
||||
/* WARNING: strlen(NC_string.cp) may be less than NC_string.nchars */
|
||||
status = set_NC_string(varp->name, newname);
|
||||
free(newname);
|
||||
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
|
||||
intdata = (uintptr_t)varid;
|
||||
NC_hashmapadd(ncp->vars.hashmap, intdata, varp->name->cp, strlen(varp->name->cp));
|
||||
@ -820,10 +805,11 @@ NC3_rename_var(int ncid, int varid, const char *unewname)
|
||||
{
|
||||
status = NC_sync(ncp);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return NC_NOERR;
|
||||
done:
|
||||
if(newname) free(newname);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user