/* keep the extra fields at the beginning. the last static_tab field
contains the ending NULL-fields. */
- tab = ret_tab = t_new(struct var_expand_table, *count + auth_count);
+ tab = ret_tab = t_new(struct var_expand_table,
+ MALLOC_ADD(*count, auth_count));
tab += *count;
*count += auth_count;
/* add some padding, since we don't bother to handle undersized
headers correctly */
- buf = t_malloc0(ext->hdr_size + 128);
+ buf = t_malloc0(MALLOC_ADD(ext->hdr_size, 128));
data = CONST_PTR_OFFSET(index->map->hdr_base, ext->hdr_offset);
memcpy(buf, data, ext->hdr_size);
data = buf;
/* at least one encoded character */
str_append_n(dest, src, p-src);
- utf16 = t_malloc0(strlen(p)*2);
+ utf16 = t_malloc0(MALLOC_MULTIPLY(strlen(p), 2));
while (*p != '\0') {
if (*p == '&') {
str_append(dest, "&-");
tview->recs_count = t->first_new_seq;
tview->record_size = I_MAX(map->hdr.record_size,
tview->view.map->hdr.record_size);
- tview->recs = i_malloc(tview->record_size *
- tview->recs_count);
+ tview->recs = i_malloc(MALLOC_MULTIPLY(tview->record_size,
+ tview->recs_count));
array_append(&tview->all_recs, &tview->recs, 1);
}
i_assert(tview->recs_count == t->first_new_seq);
}
/* @UNSAFE */
- k = i_malloc(sizeof(struct mail_keywords) +
- (sizeof(k->idx) * (count-1)));
+ k = i_malloc(MALLOC_ADD(sizeof(struct mail_keywords),
+ MALLOC_MULTIPLY(sizeof(k->idx), (count-1))));
k->index = index;
k->refcount = 1;
}
/* @UNSAFE */
- k = i_malloc(sizeof(struct mail_keywords) +
- (sizeof(k->idx) * (count-1)));
+ k = i_malloc(MALLOC_ADD(sizeof(struct mail_keywords),
+ MALLOC_MULTIPLY(sizeof(k->idx), (count-1))));
k->index = index;
k->refcount = 1;
/* @UNSAFE: we have a request. do userdb lookup for it. */
req.data_size -= i;
- client = i_malloc(sizeof(struct master_login_client) + req.data_size);
+ client = i_malloc(MALLOC_ADD(sizeof(struct master_login_client), req.data_size));
client->conn = conn;
client->fd = client_fd;
client->auth_req = req;
efds = array_get_modifiable(&pclient->extra_fds, &xfd_count);
if (xfd_count > 0) {
- parent_extra_fds = t_malloc0(sizeof(int) * xfd_count);
- child_extra_fds =
- t_malloc0(sizeof(int) * xfd_count * 2 + 1);
+ i_assert(xfd_count < INT_MAX);
+ parent_extra_fds = t_new(int, xfd_count);
+ child_extra_fds = t_new(int, xfd_count * 2 + 1);
for(i = 0; i < xfd_count; i++) {
if (pipe(extra_fd) < 0) {
i_error("pipe(extra=%d) failed: %m",
into new/ or cur/. */
/* @UNSAFE */
keyword_count = mdata->keywords == NULL ? 0 : mdata->keywords->count;
- mf = p_malloc(ctx->pool, sizeof(*mf) +
- sizeof(unsigned int) * keyword_count);
+ mf = p_malloc(ctx->pool, MALLOC_ADD(sizeof(*mf),
+ MALLOC_MULTIPLY(sizeof(unsigned int), keyword_count)));
mf->tmp_name = mf->dest_basename = p_strdup(ctx->pool, tmp_fname);
mf->flags = mdata->flags;
mf->size = (uoff_t)-1;
array_sort(&remote_msgs, pop3c_sync_msg_uidl_cmp);
/* skip over existing messages with matching UIDLs and expunge the ones
- that no longer exist in remote. (+1 to avoid malloc(0) assert) */
- mbox->msg_uids = i_new(uint32_t, mbox->msg_count + 1);
+ that no longer exist in remote. */
+ mbox->msg_uids = mbox->msg_count == 0 ?
+ i_new(uint32_t, 1) : /* avoid malloc(0) assert */
+ i_new(uint32_t, mbox->msg_count);
cache_trans = mail_cache_get_transaction(cache_view, sync_trans);
lmsg = array_get(&local_msgs, &lcount);
if (list_sep != ns_sep || prefix_len > 0) {
/* @UNSAFE */
name_len = strlen(vname);
- ret = t_malloc_no0(prefix_len + name_len + 1);
+ ret = t_malloc_no0(MALLOC_ADD(prefix_len, name_len) + 1);
memcpy(ret, list->ns->prefix, prefix_len);
for (i = 0; i < name_len; i++) {
ret[i + prefix_len] =
size_t prev_size, alloc_size;
prev_size = current_block == NULL ? 0 : current_block->size;
- alloc_size = nearest_power(prev_size + min_size);
+ alloc_size = nearest_power(MALLOC_ADD(prev_size, min_size));
+ /* nearest_power() returns 2^n values, so alloc_size can't be
+ anywhere close to SIZE_MAX */
#ifndef USE_GC
block = malloc(SIZEOF_MEMBLOCK + alloc_size);
#else
const char *binary_to_hex(const unsigned char *data, size_t size)
{
- unsigned char *dest = t_malloc_no0(size * 2 + 1);
+ unsigned char *dest = t_malloc_no0(MALLOC_MULTIPLY(size, 2) + 1);
binary_to_hex_case(dest, data, size, FALSE);
dest[size*2] = '\0';
const char *binary_to_hex_ucase(const unsigned char *data, size_t size)
{
- unsigned char *dest = t_malloc_no0(size * 2 + 1);
+ unsigned char *dest = t_malloc_no0(MALLOC_MULTIPLY(size, 2) + 1);
binary_to_hex_case(dest, data, size, TRUE);
dest[size*2] = '\0';
i_assert(key_len > 0);
i_assert(key_len < INT_MAX);
- ctx = p_malloc(pool, sizeof(struct str_find_context) +
- sizeof(ctx->goodtab[0]) * key_len);
+ ctx = p_malloc(pool, MALLOC_ADD(sizeof(struct str_find_context),
+ MALLOC_MULTIPLY(sizeof(ctx->goodtab[0]), key_len)));
ctx->pool = pool;
ctx->matches = p_new(pool, unsigned int, key_len);
ctx->key_len = key_len;
char *p;
size_t len, size = sizeof(const char *);
+ /* @UNSAFE: integer overflow checks are missing */
for (i = 0; arr[i] != NULL; i++)
size += sizeof(const char *) + strlen(arr[i]) + 1;
log_error_buffer_delete_head(buf);
/* @UNSAFE */
- data = i_malloc(sizeof(*data) + prefix_size + text_size);
+ data = i_malloc(MALLOC_ADD(sizeof(*data),
+ MALLOC_ADD(prefix_size, text_size)));
data->type = error->type;
data->timestamp = error->timestamp;
memcpy(data->prefix_text, error->prefix, prefix_size);
obj_cache = hash_table_lookup(cache->objects, objname);
if (obj_cache == NULL) {
- obj_cache = i_malloc(sizeof(struct acl_object_cache) +
- cache->validity_rec_size);
+ obj_cache = i_malloc(MALLOC_ADD(sizeof(struct acl_object_cache),
+ cache->validity_rec_size));
obj_cache->name = i_strdup(objname);
hash_table_insert(cache->objects, obj_cache->name, obj_cache);
*created_r = TRUE;
unsigned char mask[1];
};
#define SIZEOF_ACL_MASK(bitmask_size) \
- (sizeof(pool_t) + sizeof(unsigned int) + (bitmask_size))
+ (MALLOC_ADD(sizeof(pool_t) + sizeof(unsigned int), (bitmask_size)))
struct acl_cache *acl_cache_init(struct acl_backend *backend,
size_t validity_rec_size);
typedef void command_func_t(struct client *client);
#define MSGS_BITMASK_SIZE(client) \
- (((client)->messages_count + (CHAR_BIT-1)) / CHAR_BIT)
+ (MALLOC_ADD((client)->messages_count, (CHAR_BIT-1)) / CHAR_BIT)
/* Stop reading input when output buffer has this many bytes. Once the buffer
size has dropped to half of it, start reading input again. */
}
/* map UIDLs to msgnums (in case POP3 sort ordering is different) */
client->message_uidls = p_new(client->uidl_pool, const char *,
- client->messages_count+1);
+ MALLOC_ADD(client->messages_count, 1));
for (msgnum = 0; msgnum < client->messages_count; msgnum++) {
client->message_uidls[msgnum] =
seq_uidls[msgnum_to_seq(client, msgnum) - 1];
{
struct mail_command *cmd;
- cmd = i_malloc(sizeof(struct mail_command) + stats_alloc_size());
+ cmd = i_malloc(MALLOC_ADD(sizeof(struct mail_command), stats_alloc_size()));
cmd->stats = (void *)(cmd + 1);
cmd->refcount = 1; /* unrefed at "done" */
cmd->session = session;
return domain;
}
- domain = i_malloc(sizeof(struct mail_domain) + stats_alloc_size());
+ domain = i_malloc(MALLOC_ADD(sizeof(struct mail_domain), stats_alloc_size()));
domain->stats = (void *)(domain + 1);
domain->name = i_strdup(name);
domain->reset_timestamp = ioloop_time;
return ip;
}
- ip = i_malloc(sizeof(struct mail_ip) + stats_alloc_size());
+ ip = i_malloc(MALLOC_ADD(sizeof(struct mail_ip), stats_alloc_size()));
ip->stats = (void *)(ip + 1);
ip->ip = *ip_addr;
ip->reset_timestamp = ioloop_time;
session_id, args[1], args[2], (long)session->pid, (long)pid);
return -1;
}
- session = i_malloc(sizeof(struct mail_session) + stats_alloc_size());
+ session = i_malloc(MALLOC_ADD(sizeof(struct mail_session), stats_alloc_size()));
session->stats = (void *)(session + 1);
session->refcount = 1; /* unrefed at disconnect */
session->id = i_strdup(session_id);
if (domain == NULL)
domain = "";
- user = i_malloc(sizeof(struct mail_user) + stats_alloc_size());
+ user = i_malloc(MALLOC_ADD(sizeof(struct mail_user), stats_alloc_size()));
user->stats = (void *)(user + 1);
user->name = i_strdup(username);
user->reset_timestamp = ioloop_time;