reallocarray() prevents overflow of the multiplication.
It also avoids issues with operator precedence like in libmount/src/context.c:
pids = realloc(cxt->children, sizeof(pid_t) * cxt->nchildren + 1);
This only allocated one additional byte, and not enough space for
another child.
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
if (entry->child) {
if (stack_entries >= stack_size) {
stack_size *= 2;
- entry_stack = xrealloc(entry_stack, stack_size * sizeof(struct entry *));
+ entry_stack = xreallocarray(entry_stack, stack_size, sizeof(struct entry *));
}
entry_stack[stack_entries] = entry;
stack_entries++;
int ul_buffer_save_pointer(struct ul_buffer *buf, unsigned short ptr_idx)
{
if (ptr_idx >= buf->nptrs) {
- char **tmp = realloc(buf->ptrs, (ptr_idx + 1) * sizeof(char *));
+ char **tmp = reallocarray(buf->ptrs, ptr_idx + 1, sizeof(char *));
if (!tmp)
return -EINVAL;
/* enlarge the array */
if (cc->nschemes == cc->schemes_sz) {
- void *tmp = realloc(cc->schemes, (cc->nschemes + 10)
- * sizeof(struct ul_color_scheme));
+ void *tmp = reallocarray(cc->schemes, cc->nschemes + 10,
+ sizeof(struct ul_color_scheme));
if (!tmp)
goto err;
cc->schemes = tmp;
arylen += 1;
- tmp = realloc(*ary, arylen * sizeof(int));
+ tmp = reallocarray(*ary, arylen, sizeof(int));
if (!tmp) {
free(*ary);
*ary = NULL;
if (m < n)
return -ENOMEM;
- c = realloc(*l, sizeof(char *) * m);
+ c = reallocarray(*l, m, sizeof(char *));
if (!c)
return -ENOMEM;
/* Linux kernel has DISK_MAX_PARTS=256, but it's too much for
* generic Linux machine -- let start with 32 partitions.
*/
- void *tmp = realloc(ls->parts, (ls->nparts_max + 32) *
- sizeof(struct blkid_struct_partition));
+ void *tmp = reallocarray(ls->parts, ls->nparts_max + 32,
+ sizeof(struct blkid_struct_partition));
if (!tmp)
return NULL;
ls->parts = tmp;
if (cache->nents == cache->nallocs) {
size_t sz = cache->nallocs + MNT_CACHE_CHUNKSZ;
- e = realloc(cache->ents, sz * sizeof(struct mnt_cache_entry));
+ e = reallocarray(cache->ents, sz, sizeof(struct mnt_cache_entry));
if (!e)
return -ENOMEM;
cache->ents = e;
if (!cxt)
return -EINVAL;
- pids = realloc(cxt->children, sizeof(pid_t) * cxt->nchildren + 1);
+ pids = reallocarray(cxt->children, cxt->nchildren + 1, sizeof(pid_t));
if (!pids)
return -ENOMEM;
if (n == 0 || !((n + 1) % MYCHUNK)) {
size_t items = ((n + 1 + MYCHUNK) / MYCHUNK) * MYCHUNK;
- char **x = realloc(*filesystems, items * sizeof(char *));
+ char **x = reallocarray(*filesystems, items, sizeof(char *));
if (!x)
goto err;
DBG(TAB, ul_debugobj(tb, " realocate grpset [sz: old=%zu, new=%zu, new_chunks=%d]",
tb->grpset_size, tb->grpset_size + wanted, chunks));
- tmp = realloc(tb->grpset, (tb->grpset_size + wanted) * sizeof(struct libscols_group *));
+ tmp = reallocarray(tb->grpset, tb->grpset_size + wanted, sizeof(struct libscols_group *));
if (!tmp)
return NULL;
DBG(LINE, ul_debugobj(ln, "alloc %zu cells", n));
- ce = realloc(ln->cells, n * sizeof(struct libscols_cell));
+ ce = reallocarray(ln->cells, n, sizeof(struct libscols_cell));
if (!ce)
return -errno;
break;
}
if (i == imax)
- ary = xrealloc(ary, (imax *= 2) * sizeof(struct utmpx));
+ ary = xreallocarray(ary, imax *= 2, sizeof(struct utmpx));
ary[i] = *u;
}
(*ar)[i++] = xstrdup(u);
if (i == *arsiz)
- *ar = xrealloc(*ar, sizeof(char *) * (*arsiz += 32));
+ *ar = xreallocarray(*ar, *arsiz += 32, sizeof(char *));
}
ctl->ulist_on = 1;
}
(*ar)[i++] = xstrdup(u);
if (i == *arsiz)
- *ar = xrealloc(*ar, sizeof(char *) * (*arsiz += 32));
+ *ar = xreallocarray(*ar, *arsiz += 32, sizeof(char *));
}
}
ctl->ulist_on = 1;
DBG(MISC, ul_debug("add %s group [name=%s, GID=%d]", name, gr->gr_name, (int) gr->gr_gid));
- *groups = xrealloc(*groups, sizeof(gid_t) * (*ngroups + 1));
+ *groups = xreallocarray(*groups, *ngroups + 1, sizeof(gid_t));
(*groups)[*ngroups] = gr->gr_gid;
(*ngroups)++;
if (vfy->fs_alloc == 0 || vfy->fs_num + 1 <= vfy->fs_alloc) {
vfy->fs_alloc = ((vfy->fs_alloc + 1 + MYCHUNK) / MYCHUNK) * MYCHUNK;
- vfy->fs_ary = xrealloc(vfy->fs_ary, vfy->fs_alloc * sizeof(char *));
+ vfy->fs_ary = xreallocarray(vfy->fs_ary, vfy->fs_alloc, sizeof(char *));
}
vfy->fs_ary[vfy->fs_num] = xstrdup(name);
static char **append_tabfile(char **files, int *nfiles, char *filename)
{
- files = xrealloc(files, sizeof(char *) * (*nfiles + 1));
+ files = xreallocarray(files, *nfiles + 1, sizeof(char *));
files[(*nfiles)++] = filename;
return files;
}
if (ctl->long_options_nr == ctl->long_options_length) {
ctl->long_options_length += REALLOC_INCREMENT;
- ctl->long_options = xrealloc(ctl->long_options,
- sizeof(struct option) *
- ctl->long_options_length);
+ ctl->long_options = xreallocarray(ctl->long_options,
+ ctl->long_options_length,
+ sizeof(struct option));
}
if (name) {
/* Not for init! */
vectors *= 2;
if (IOV_MAX < vectors)
errx(EXIT_FAILURE, _("maximum input lines (%d) exceeded"), IOV_MAX);
- iovec = xrealloc(iovec, vectors * sizeof(struct iovec));
+ iovec = xreallocarray(iovec, vectors, sizeof(struct iovec));
}
iovec[lines].iov_base = buf;
iovec[lines].iov_len = sz;
assert(dev);
assert(fs);
- dev->fss = xrealloc(dev->fss, (dev->nfss + 1)
- * sizeof(struct libmnt_fs *));
+ dev->fss = xreallocarray(dev->fss, dev->nfss + 1, sizeof(struct libmnt_fs *));
dev->fss[dev->nfss] = fs;
dev->nfss++;
dev->is_mounted = 1;
nmax = (nspaces + 16) / 16 * 16;
if (nmax <= nspaces + 1) {
nmax += 16;
- mnt_namespaces = xrealloc(mnt_namespaces,
- sizeof(ino_t) * nmax);
+ mnt_namespaces = xreallocarray(mnt_namespaces,
+ nmax, sizeof(ino_t));
}
mnt_namespaces[nspaces++] = id;
}
errx(EXIT_FAILURE, _("out of range value for pid specification: %ld"), v);
(*count)++;
- *pids = xrealloc(*pids, (*count) * sizeof(**pids));
+ *pids = xreallocarray(*pids, *count, sizeof(**pids));
(*pids)[*count - 1] = (pid_t)v;
while (next && *next != '\0'
if (stat->nr_irq == stat->nr_irq_info) {
stat->nr_irq_info *= 2;
- stat->irq_info = xrealloc(stat->irq_info,
- sizeof(*stat->irq_info) * stat->nr_irq_info);
+ stat->irq_info = xreallocarray(stat->irq_info, stat->nr_irq_info,
+ sizeof(*stat->irq_info));
}
}
fclose(irqfile);
struct lscpu_cputype *lscpu_add_cputype(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
{
DBG(TYPE, ul_debugobj(ct, "add new"));
- cxt->cputypes = xrealloc(cxt->cputypes, (cxt->ncputypes + 1)
- * sizeof(struct lscpu_cputype *));
+ cxt->cputypes = xreallocarray(cxt->cputypes, cxt->ncputypes + 1,
+ sizeof(struct lscpu_cputype *));
cxt->cputypes[cxt->ncputypes] = ct;
cxt->ncputypes++;
lscpu_ref_cputype(ct);
return 0;
cxt->necaches++;
- cxt->ecaches = xrealloc(cxt->ecaches,
- cxt->necaches * sizeof(struct lscpu_cache));
+ cxt->ecaches = xreallocarray(cxt->ecaches,
+ cxt->necaches, sizeof(struct lscpu_cache));
cache = &cxt->ecaches[cxt->necaches - 1];
memset(cache, 0 , sizeof(*cache));
struct lscpu_cache *ca;
cxt->ncaches++;
- cxt->caches = xrealloc(cxt->caches,
- cxt->ncaches * sizeof(*cxt->caches));
+ cxt->caches = xreallocarray(cxt->caches,
+ cxt->ncaches, sizeof(*cxt->caches));
ca = &cxt->caches[cxt->ncaches - 1];
memset(ca, 0 , sizeof(*ca));
continue;
}
lsmem->nblocks++;
- lsmem->blocks = xrealloc(lsmem->blocks, lsmem->nblocks * sizeof(blk));
+ lsmem->blocks = xreallocarray(lsmem->blocks, lsmem->nblocks, sizeof(blk));
*&lsmem->blocks[lsmem->nblocks - 1] = blk;
}
}
void add_label(const char *label)
{
- llist = xrealloc(llist, (++llct) * sizeof(char *));
+ llist = xreallocarray(llist, ++llct, sizeof(char *));
llist[llct - 1] = label;
}
void add_uuid(const char *uuid)
{
- ulist = xrealloc(ulist, (++ulct) * sizeof(char *));
+ ulist = xreallocarray(ulist, ++ulct, sizeof(char *));
ulist[ulct - 1] = uuid;
}
assert(streams);
assert(filename);
- stp->logs = xrealloc(stp->logs, (stp->nlogs + 1) * sizeof(*log));
+ stp->logs = xreallocarray(stp->logs, stp->nlogs + 1, sizeof(*log));
log = &stp->logs[stp->nlogs];
stp->nlogs++;
}
/* add log to the stream */
- stream->logs = xrealloc(stream->logs,
- (stream->nlogs + 1) * sizeof(log));
+ stream->logs = xreallocarray(stream->logs,
+ stream->nlogs + 1, sizeof(log));
stream->logs[stream->nlogs] = log;
stream->nlogs++;
*/
if (sorted_size < l->l_lsize) {
sorted_size = l->l_lsize;
- sorted = xrealloc(sorted, sizeof(struct col_char) * sorted_size);
+ sorted = xreallocarray(sorted, sorted_size, sizeof(struct col_char));
}
if (count_size <= l->l_max_col) {
count_size = l->l_max_col + 1;
- count = xrealloc(count, sizeof(size_t) * count_size);
+ count = xreallocarray(count, count_size, sizeof(size_t));
}
memset(count, 0, sizeof(size_t) * l->l_max_col + 1);
for (i = nchars, c = l->l_line; c && 0 < i; i--, c++)
{
if (ctl->nents <= *maxents) {
*maxents += 1000;
- ctl->ents = xrealloc(ctl->ents, *maxents * sizeof(wchar_t *));
+ ctl->ents = xreallocarray(ctl->ents, *maxents, sizeof(wchar_t *));
}
ctl->ents[ctl->nents] = wcs;
ctl->nents++;
env_argv[env_argc++] = tok;
if (size < env_argc) {
size *= 2;
- env_argv = xrealloc(env_argv, sizeof(char *) * size);
+ env_argv = xreallocarray(env_argv, size, sizeof(char *));
}
}
/* So now we double the buffer size */
bufsiz *= 2;
- buf = xrealloc(buf, bufsiz * sizeof(wchar_t));
+ buf = xreallocarray(buf, bufsiz, sizeof(wchar_t));
/* And fill the rest of the buffer */
len += read_line(sep, &buf[len], bufsiz/2, fp);
while (new_max >= ctl->buflen) {
ctl->buflen *= 2;
- ctl->buf = xrealloc(ctl->buf, sizeof(struct ul_char) * ctl->buflen);
+ ctl->buf = xreallocarray(ctl->buf, ctl->buflen, sizeof(struct ul_char));
}
}