Fix memory leaks re utf8_normalize

This commit is contained in:
Dennis Heimbigner 2018-02-27 15:46:19 -07:00
parent 1f6264273e
commit 225453f12f
3 changed files with 118 additions and 141 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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