libc: provide some bounds-checking through reallocarray(3).
reallocarray(3) is a non portable extension that originated in OpenBSD. Given that it is already in FreeBSD's libc it is useful for the cases where reallocation involves a multiplication. MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D9955
This commit is contained in:
parent
ab23521a49
commit
9f36610f9e
@ -850,7 +850,7 @@ globextend(const Char *path, glob_t *pglob, struct glob_limit *limit,
|
||||
const char *origpat)
|
||||
{
|
||||
char **pathv;
|
||||
size_t i, newsize, len;
|
||||
size_t i, newn, len;
|
||||
char *copy;
|
||||
const Char *p;
|
||||
|
||||
@ -860,9 +860,9 @@ globextend(const Char *path, glob_t *pglob, struct glob_limit *limit,
|
||||
return (GLOB_NOSPACE);
|
||||
}
|
||||
|
||||
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
|
||||
/* realloc(NULL, newsize) is equivalent to malloc(newsize). */
|
||||
pathv = realloc((void *)pglob->gl_pathv, newsize);
|
||||
newn = 2 + pglob->gl_pathc + pglob->gl_offs;
|
||||
/* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */
|
||||
pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv));
|
||||
if (pathv == NULL)
|
||||
return (GLOB_NOSPACE);
|
||||
|
||||
|
@ -116,8 +116,8 @@ scandir(const char *dirname, struct dirent ***namelist,
|
||||
if (numitems >= arraysz) {
|
||||
struct dirent **names2;
|
||||
|
||||
names2 = (struct dirent **)realloc((char *)names,
|
||||
(arraysz * 2) * sizeof(struct dirent *));
|
||||
names2 = reallocarray(names, arraysz,
|
||||
2 * sizeof(struct dirent *));
|
||||
if (names2 == NULL) {
|
||||
free(p);
|
||||
goto fail;
|
||||
|
@ -155,7 +155,7 @@ common: if (set->cmd2 & CMD2_CLR) {
|
||||
if (set >= endset) { \
|
||||
BITCMD *newset; \
|
||||
setlen += SET_LEN_INCR; \
|
||||
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
|
||||
newset = reallocarray(saveset, setlen, sizeof(BITCMD)); \
|
||||
if (newset == NULL) \
|
||||
goto out; \
|
||||
set = newset + (set - saveset); \
|
||||
|
@ -234,8 +234,8 @@ we_askshell(const char *words, wordexp_t *we, int flags)
|
||||
vofs += we->we_offs;
|
||||
we->we_wordc += nwords;
|
||||
we->we_nbytes += nbytes;
|
||||
if ((nwv = realloc(we->we_wordv, (we->we_wordc + 1 +
|
||||
(flags & WRDE_DOOFFS ? we->we_offs : 0)) *
|
||||
if ((nwv = reallocarray(we->we_wordv, (we->we_wordc + 1 +
|
||||
(flags & WRDE_DOOFFS ? we->we_offs : 0)),
|
||||
sizeof(char *))) == NULL) {
|
||||
error = WRDE_NOSPACE;
|
||||
goto cleanup;
|
||||
|
@ -347,7 +347,7 @@ _citrus_esdb_get_list(char ***rlist, size_t *rnum, bool sorted)
|
||||
ret = 0;
|
||||
/* XXX: why reallocing the list space posteriorly?
|
||||
shouldn't be done earlier? */
|
||||
q = realloc(list, num * sizeof(char *));
|
||||
q = reallocarray(list, num, sizeof(char *));
|
||||
if (!q) {
|
||||
ret = ENOMEM;
|
||||
goto quit3;
|
||||
|
@ -213,7 +213,7 @@ vector_append(const void *elem, void *vec, unsigned int *count, size_t esize)
|
||||
void *p;
|
||||
|
||||
if ((*count % ELEMSPERCHUNK) == 0) {
|
||||
p = realloc(vec, (*count + ELEMSPERCHUNK) * esize);
|
||||
p = reallocarray(vec, *count + ELEMSPERCHUNK, esize);
|
||||
if (p == NULL) {
|
||||
nss_log_simple(LOG_ERR, "memory allocation failure");
|
||||
return (vec);
|
||||
|
@ -1143,7 +1143,7 @@ allocset(struct parse *p)
|
||||
{
|
||||
cset *cs, *ncs;
|
||||
|
||||
ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof(*ncs));
|
||||
ncs = reallocarray(p->g->sets, p->g->ncsets + 1, sizeof(*ncs));
|
||||
if (ncs == NULL) {
|
||||
SETERROR(REG_ESPACE);
|
||||
return (NULL);
|
||||
@ -1206,7 +1206,7 @@ CHadd(struct parse *p, cset *cs, wint_t ch)
|
||||
if (ch < NC)
|
||||
cs->bmp[ch >> 3] |= 1 << (ch & 7);
|
||||
else {
|
||||
newwides = realloc(cs->wides, (cs->nwides + 1) *
|
||||
newwides = reallocarray(cs->wides, cs->nwides + 1,
|
||||
sizeof(*cs->wides));
|
||||
if (newwides == NULL) {
|
||||
SETERROR(REG_ESPACE);
|
||||
@ -1235,7 +1235,7 @@ CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max)
|
||||
CHadd(p, cs, min);
|
||||
if (min >= max)
|
||||
return;
|
||||
newranges = realloc(cs->ranges, (cs->nranges + 1) *
|
||||
newranges = reallocarray(cs->ranges, cs->nranges + 1,
|
||||
sizeof(*cs->ranges));
|
||||
if (newranges == NULL) {
|
||||
SETERROR(REG_ESPACE);
|
||||
@ -1259,7 +1259,7 @@ CHaddtype(struct parse *p, cset *cs, wctype_t wct)
|
||||
for (i = 0; i < NC; i++)
|
||||
if (iswctype(i, wct))
|
||||
CHadd(p, cs, i);
|
||||
newtypes = realloc(cs->types, (cs->ntypes + 1) *
|
||||
newtypes = reallocarray(cs->types, cs->ntypes + 1,
|
||||
sizeof(*cs->types));
|
||||
if (newtypes == NULL) {
|
||||
SETERROR(REG_ESPACE);
|
||||
@ -1382,7 +1382,7 @@ enlarge(struct parse *p, sopno size)
|
||||
if (p->ssize >= size)
|
||||
return 1;
|
||||
|
||||
sp = (sop *)realloc(p->strip, size*sizeof(sop));
|
||||
sp = reallocarray(p->strip, size, sizeof(sop));
|
||||
if (sp == NULL) {
|
||||
SETERROR(REG_ESPACE);
|
||||
return 0;
|
||||
@ -1400,7 +1400,7 @@ static void
|
||||
stripsnug(struct parse *p, struct re_guts *g)
|
||||
{
|
||||
g->nstates = p->slen;
|
||||
g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
|
||||
g->strip = reallocarray((char *)p->strip, p->slen, sizeof(sop));
|
||||
if (g->strip == NULL) {
|
||||
SETERROR(REG_ESPACE);
|
||||
g->strip = p->strip;
|
||||
|
@ -630,8 +630,8 @@ parse_ncp(char *stringp, struct netconfig *ncp)
|
||||
ncp->nc_lookups = NULL;
|
||||
ncp->nc_nlookups = 0;
|
||||
while ((cp = tokenp) != NULL) {
|
||||
if ((nc_lookups = realloc(ncp->nc_lookups,
|
||||
(ncp->nc_nlookups + 1) * sizeof *ncp->nc_lookups)) == NULL) {
|
||||
if ((nc_lookups = reallocarray(ncp->nc_lookups,
|
||||
ncp->nc_nlookups + 1, sizeof(*ncp->nc_lookups))) == NULL) {
|
||||
free(ncp->nc_lookups);
|
||||
ncp->nc_lookups = NULL;
|
||||
return (-1);
|
||||
|
@ -63,7 +63,7 @@ wmemstream_grow(struct wmemstream *ms, fpos_t newoff)
|
||||
else
|
||||
newsize = newoff;
|
||||
if (newsize > ms->len) {
|
||||
buf = realloc(*ms->bufp, (newsize + 1) * sizeof(wchar_t));
|
||||
buf = reallocarray(*ms->bufp, newsize + 1, sizeof(wchar_t));
|
||||
if (buf != NULL) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "WMS: %p growing from %zd to %zd\n",
|
||||
|
@ -655,7 +655,7 @@ __grow_type_table(struct typetable *types)
|
||||
return (-1);
|
||||
bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
|
||||
} else {
|
||||
newtable = realloc(oldtable, newsize * sizeof(enum typeid));
|
||||
newtable = reallocarray(oldtable, newsize, sizeof(enum typeid));
|
||||
if (newtable == NULL)
|
||||
return (-1);
|
||||
}
|
||||
|
@ -73,14 +73,14 @@ __submore(FILE *fp)
|
||||
return (0);
|
||||
}
|
||||
i = fp->_ub._size;
|
||||
p = realloc(fp->_ub._base, (size_t)(i << 1));
|
||||
p = reallocarray(fp->_ub._base, i, 2);
|
||||
if (p == NULL)
|
||||
return (EOF);
|
||||
/* no overlap (hence can use memcpy) because we doubled the size */
|
||||
(void)memcpy((void *)(p + i), (void *)p, (size_t)i);
|
||||
fp->_p = p + i;
|
||||
fp->_ub._base = p;
|
||||
fp->_ub._size = i << 1;
|
||||
fp->_ub._size = i * 2;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -272,8 +272,8 @@ __rebuild_environ(int newEnvironSize)
|
||||
/* Resize environ. */
|
||||
if (newEnvironSize > environSize) {
|
||||
tmpEnvironSize = newEnvironSize * 2;
|
||||
tmpEnviron = realloc(intEnviron, sizeof (*intEnviron) *
|
||||
(tmpEnvironSize + 1));
|
||||
tmpEnviron = reallocarray(intEnviron, tmpEnvironSize + 1,
|
||||
sizeof(*intEnviron));
|
||||
if (tmpEnviron == NULL)
|
||||
return (-1);
|
||||
environSize = tmpEnvironSize;
|
||||
@ -306,8 +306,8 @@ __enlarge_env(void)
|
||||
envVarsTotal++;
|
||||
if (envVarsTotal > envVarsSize) {
|
||||
newEnvVarsSize = envVarsTotal * 2;
|
||||
tmpEnvVars = realloc(envVars, sizeof (*envVars) *
|
||||
newEnvVarsSize);
|
||||
tmpEnvVars = reallocarray(envVars, newEnvVarsSize,
|
||||
sizeof(*envVars));
|
||||
if (tmpEnvVars == NULL) {
|
||||
envVarsTotal--;
|
||||
return (false);
|
||||
|
Loading…
Reference in New Issue
Block a user