static inline void buffer_check_limits(struct real_buffer *buf, size_t pos, size_t data_size) { unsigned int extra; size_t new_size; if (unlikely((size_t)-1 - pos < data_size)) { i_panic("Buffer write out of range (%"PRIuSIZE_T " + %"PRIuSIZE_T")", pos, data_size); } new_size = pos + data_size; if (new_size > buf->used && buf->used < buf->dirty) { /* clear used..dirty area */ size_t max = I_MIN(I_MIN(buf->alloc, buf->dirty), new_size); memset(buf->w_buffer + buf->used, 0, max - buf->used); } /* always keep +1 byte allocated available in case str_c() is called for this buffer. this is mainly for cases where the buffer is allocated from data stack, and str_c() is called in a separate stack frame. */ extra = buf->dynamic ? 1 : 0; if (new_size + extra > buf->alloc) { if (unlikely(!buf->dynamic)) { i_panic("Buffer full (%"PRIuSIZE_T" > %"PRIuSIZE_T", " "pool %s)", pos + data_size, buf->alloc, buf->pool == NULL ? "<none>" : pool_get_name(buf->pool)); } buffer_alloc(buf, pool_get_exp_grown_size(buf->pool, buf->alloc, new_size + extra)); } #if 0 else if (new_size > buf->used && buf->alloced && !buf->pool->alloconly_pool && !buf->pool->datastack_pool) { void *new_buf; /* buffer's size increased: move the buffer's memory elsewhere. this should help catch bugs where old pointers are tried to be used to access the buffer's memory */ new_buf = p_malloc(buf->pool, buf->alloc); memcpy(new_buf, buf->w_buffer, buf->alloc); p_free(buf->pool, buf->w_buffer); buf->w_buffer = new_buf; buf->r_buffer = new_buf; } #endif if (new_size > buf->used) buf->used = new_size; i_assert(buf->used <= buf->alloc); }
static size_t o_stream_ssl_buffer(struct ssl_ostream *sstream, const struct const_iovec *iov, unsigned int iov_count, size_t bytes_sent) { size_t avail, skip_left, size; unsigned int i; if (sstream->buffer == NULL) sstream->buffer = buffer_create_dynamic(default_pool, 4096); skip_left = bytes_sent; for (i = 0; i < iov_count; i++) { if (skip_left < iov[i].iov_len) break; skip_left -= iov[i].iov_len; } if (sstream->ostream.max_buffer_size == 0) { /* we're requeted to use whatever space is available in the buffer */ avail = buffer_get_size(sstream->buffer) - sstream->buffer->used; } else { avail = sstream->ostream.max_buffer_size > sstream->buffer->used ? sstream->ostream.max_buffer_size - sstream->buffer->used : 0; } if (i < iov_count && skip_left > 0) { size = I_MIN(iov[i].iov_len - skip_left, avail); buffer_append(sstream->buffer, CONST_PTR_OFFSET(iov[i].iov_base, skip_left), size); bytes_sent += size; avail -= size; if (size != iov[i].iov_len) i = iov_count; } if (avail > 0) o_stream_set_flush_pending(sstream->ssl_io->plain_output, TRUE); for (; i < iov_count; i++) { size = I_MIN(iov[i].iov_len, avail); buffer_append(sstream->buffer, iov[i].iov_base, size); bytes_sent += size; avail -= size; if (size != iov[i].iov_len) break; } sstream->ostream.ostream.offset += bytes_sent; return bytes_sent; }
static ssize_t o_stream_escaped_send_chunk(struct escaped_ostream *estream, const unsigned char *data, size_t len) { size_t i, max_buffer_size; ssize_t ret; max_buffer_size = I_MIN(o_stream_get_max_buffer_size(estream->ostream.parent), estream->ostream.max_buffer_size); if (max_buffer_size > IO_BLOCK_SIZE) { /* avoid using up too much memory in case of large buffers */ max_buffer_size = IO_BLOCK_SIZE; } for (i = 0; i < len; i++) { if (str_len(estream->buf) + 2 > max_buffer_size) { /* escaping takes at least two bytes */ ret = o_stream_escaped_send_outbuf(estream); if (ret < 0) { estream->ostream.ostream.offset += i; return ret; } if (ret == 0) break; } estream->format(estream->buf, data[i]); estream->flushed = FALSE; } estream->ostream.ostream.offset += i; return i; }
static bool pop3_uidl_assign_by_size(struct mailbox *box) { struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(box); struct pop3_migration_mail_storage *mstorage = POP3_MIGRATION_CONTEXT(box->storage); struct pop3_uidl_map *pop3_map; struct imap_msg_map *imap_map; unsigned int i, pop3_count, imap_count, count; pop3_map = array_get_modifiable(&mstorage->pop3_uidl_map, &pop3_count); imap_map = array_get_modifiable(&mbox->imap_msg_map, &imap_count); count = I_MIN(pop3_count, imap_count); /* see if we can match the messages using sizes */ for (i = 0; i < count; i++) { if (pop3_map[i].size != imap_map[i].psize) break; if (i+1 < count && pop3_map[i].size == pop3_map[i+1].size) { /* two messages with same size, don't trust them */ break; } pop3_map[i].imap_uid = imap_map[i].uid; imap_map[i].pop3_uidl = pop3_map[i].pop3_uidl; imap_map[i].pop3_seq = pop3_map[i].pop3_seq; } mbox->first_unfound_idx = i; return i == count; }
void mailbox_name_get_sha128(const char *name, guid_128_t guid_128_r) { unsigned char sha[SHA1_RESULTLEN]; sha1_get_digest(name, strlen(name), sha); memcpy(guid_128_r, sha, I_MIN(GUID_128_SIZE, sizeof(sha))); }
static void tok_append_truncated(struct generic_fts_tokenizer *tok, const unsigned char *data, size_t size) { buffer_append(tok->token, data, I_MIN(size, tok->max_length - tok->token->used)); tok->untruncated_length += size; }
static void aqueue_grow(struct aqueue *aqueue) { unsigned int orig_area_size, count; i_assert(aqueue->full && aqueue->head == aqueue->tail); orig_area_size = aqueue->area_size; (void)array_append_space_i(aqueue->arr); aqueue->area_size = buffer_get_size(aqueue->arr->buffer) / aqueue->arr->element_size; i_assert(orig_area_size < aqueue->area_size); count = I_MIN(aqueue->area_size - orig_area_size, aqueue->head); array_copy(aqueue->arr, orig_area_size, aqueue->arr, 0, count); if (count < aqueue->area_size - orig_area_size) aqueue->head = orig_area_size + count; else { array_copy(aqueue->arr, 0, aqueue->arr, count, aqueue->head - count); aqueue->head -= count; } i_assert(aqueue->head != aqueue->tail); aqueue->full = FALSE; }
static void test_ostream_multiplex_simple(void) { test_begin("ostream multiplex (simple)"); const unsigned char expected[] = { '\x00','\x00','\x00','\x00','\x05','\x68','\x65', '\x6c','\x6c','\x6f','\x01','\x00','\x00','\x00', '\x05','\x77','\x6f','\x72','\x6c','\x64' }; buffer_t *result = t_str_new(64); struct ostream *os = test_ostream_create(result); struct ostream *os2 = o_stream_create_multiplex(os, (size_t)-1); struct ostream *os3 = o_stream_multiplex_add_channel(os2, 1); test_assert(o_stream_send_str(os2, "hello") == 5); test_assert(o_stream_send_str(os3, "world") == 5); o_stream_unref(&os3); o_stream_unref(&os2); o_stream_unref(&os); test_assert(sizeof(expected) == result->used); test_assert(memcmp(result->data, expected, I_MIN(sizeof(expected), result->used)) == 0); test_end(); }
struct mail_index *mail_index_alloc(const char *dir, const char *prefix) { struct mail_index *index; index = i_new(struct mail_index, 1); index->dir = i_strdup(dir); index->prefix = i_strdup(prefix); index->fd = -1; index->extension_pool = pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024); p_array_init(&index->extensions, index->extension_pool, 5); i_array_init(&index->sync_lost_handlers, 4); i_array_init(&index->module_contexts, I_MIN(5, mail_index_module_register.id)); index->mode = 0600; index->gid = (gid_t)-1; index->lock_method = FILE_LOCK_METHOD_FCNTL; index->max_lock_timeout_secs = UINT_MAX; index->keywords_ext_id = mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS, 128, 2, 1); index->keywords_pool = pool_alloconly_create("keywords", 512); i_array_init(&index->keywords, 16); hash_table_create(&index->keywords_hash, index->keywords_pool, 0, strcase_hash, strcasecmp); index->log = mail_transaction_log_alloc(index); mail_index_modseq_init(index); return index; }
void mail_index_view_clone(struct mail_index_view *dest, const struct mail_index_view *src) { memset(dest, 0, sizeof(*dest)); dest->refcount = 1; dest->v = src->v; dest->index = src->index; if (src->log_view != NULL) { dest->log_view = mail_transaction_log_view_open(src->index->log); } dest->indexid = src->indexid; dest->inconsistency_id = src->inconsistency_id; dest->map = src->map; if (dest->map != NULL) dest->map->refcount++; dest->log_file_expunge_seq = src->log_file_expunge_seq; dest->log_file_expunge_offset = src->log_file_expunge_offset; dest->log_file_head_seq = src->log_file_head_seq; dest->log_file_head_offset = src->log_file_head_offset; i_array_init(&dest->module_contexts, I_MIN(5, mail_index_module_register.id)); DLLIST_PREPEND(&dest->index->views, dest); }
static int mail_index_recreate(struct mail_index *index) { struct mail_index_map *map = index->map; struct ostream *output; unsigned int base_size; const char *path; int ret = 0, fd; i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); i_assert(map->hdr.indexid == index->indexid); i_assert((map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) == 0); i_assert(index->indexid != 0); fd = mail_index_create_tmp_file(index, index->filepath, &path); if (fd == -1) return -1; output = o_stream_create_fd_file(fd, 0, FALSE); o_stream_cork(output); base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr)); o_stream_nsend(output, &map->hdr, base_size); o_stream_nsend(output, CONST_PTR_OFFSET(map->hdr_base, base_size), map->hdr.header_size - base_size); o_stream_nsend(output, map->rec_map->records, map->rec_map->records_count * map->hdr.record_size); o_stream_nflush(output); if (o_stream_nfinish(output) < 0) { mail_index_file_set_syscall_error(index, path, "write()"); ret = -1; } o_stream_destroy(&output); if (ret == 0 && index->fsync_mode != FSYNC_MODE_NEVER) { if (fdatasync(fd) < 0) { mail_index_file_set_syscall_error(index, path, "fdatasync()"); ret = -1; } } if (close(fd) < 0) { mail_index_file_set_syscall_error(index, path, "close()"); ret = -1; } if ((index->flags & MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS) != 0) (void)mail_index_create_backup(index); if (ret == 0 && rename(path, index->filepath) < 0) { mail_index_set_error(index, "rename(%s, %s) failed: %m", path, index->filepath); ret = -1; } if (ret < 0) i_unlink(path); return ret; }
static void dcrypt_gnutls_ctx_sym_set_iv(struct dcrypt_context_symmetric *ctx, const unsigned char *iv, size_t iv_len) { if(ctx->iv.data != NULL) p_free(ctx->pool, ctx->iv.data); ctx->iv.size = I_MIN(iv_len,(size_t)gnutls_cipher_get_iv_size(ctx->cipher)); ctx->iv.data = p_malloc(ctx->pool, ctx->iv.size); memcpy(ctx->iv.data, iv, ctx->iv.size); }
static void dcrypt_gnutls_ctx_hmac_set_key(struct dcrypt_context_hmac *ctx, const unsigned char *key, size_t key_len) { if(ctx->key.data != NULL) p_free(ctx->pool, ctx->key.data); ctx->key.size = I_MIN(key_len,(size_t)gnutls_hmac_get_len(ctx->md)); ctx->key.data = p_malloc(ctx->pool, ctx->key.size); memcpy(ctx->key.data, key, ctx->key.size); }
static void dcrypt_gnutls_ctx_sym_set_key(struct dcrypt_context_symmetric *ctx, const unsigned char *key, size_t key_len) { if(ctx->key.data != NULL) p_free(ctx->pool, ctx->key.data); ctx->key.size = I_MIN(key_len,(size_t)gnutls_cipher_get_key_size(ctx->cipher)); ctx->key.data = p_malloc(ctx->pool, ctx->key.size); memcpy(ctx->key.data, key, ctx->key.size); }
static void iostream_pump_copy(struct iostream_pump *pump) { enum ostream_send_istream_result res; size_t old_size; o_stream_cork(pump->output); old_size = o_stream_get_max_buffer_size(pump->output); o_stream_set_max_buffer_size(pump->output, I_MIN(IO_BLOCK_SIZE, o_stream_get_max_buffer_size(pump->output))); res = o_stream_send_istream(pump->output, pump->input); o_stream_set_max_buffer_size(pump->output, old_size); o_stream_uncork(pump->output); switch(res) { case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: io_remove(&pump->io); pump->callback(IOSTREAM_PUMP_STATUS_INPUT_ERROR, pump->context); return; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: io_remove(&pump->io); pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR, pump->context); return; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: i_assert(!pump->output->blocking); pump->waiting_output = TRUE; io_remove(&pump->io); return; case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: pump->waiting_output = FALSE; io_remove(&pump->io); /* flush it */ switch (o_stream_flush(pump->output)) { case -1: pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR, pump->context); break; case 0: pump->waiting_output = TRUE; pump->completed = TRUE; break; default: pump->callback(IOSTREAM_PUMP_STATUS_INPUT_EOF, pump->context); break; } return; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: i_assert(!pump->input->blocking); pump->waiting_output = FALSE; return; } i_unreached(); }
static void mdbox_map_get_ext_hdr(struct mdbox_map *map, struct mail_index_view *view, struct mdbox_map_mail_index_header *hdr_r) { const void *data; size_t data_size; mail_index_get_header_ext(view, map->map_ext_id, &data, &data_size); memset(hdr_r, 0, sizeof(*hdr_r)); memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); }
static int squat_uidlist_map_blocks(struct squat_uidlist *uidlist) { const struct squat_uidlist_file_header *hdr = &uidlist->hdr; const void *base; uint32_t block_count, blocks_offset, blocks_size, i, verify_count; if (hdr->block_list_offset == 0) { /* empty file */ uidlist->cur_block_count = 0; return 1; } /* get number of blocks */ if (uidlist_file_cache_read(uidlist, hdr->block_list_offset, sizeof(block_count)) < 0) return -1; blocks_offset = hdr->block_list_offset + sizeof(block_count); if (blocks_offset > uidlist->data_size) { squat_uidlist_set_corrupted(uidlist, "block list outside file"); return 0; } i_assert(uidlist->data != NULL); base = CONST_PTR_OFFSET(uidlist->data, hdr->block_list_offset); memcpy(&block_count, base, sizeof(block_count)); /* map the blocks */ blocks_size = block_count * sizeof(uint32_t)*2; if (uidlist_file_cache_read(uidlist, blocks_offset, blocks_size) < 0) return -1; if (blocks_offset + blocks_size > uidlist->data_size) { squat_uidlist_set_corrupted(uidlist, "block list outside file"); return 0; } uidlist->cur_block_count = block_count; squat_uidlist_map_blocks_set_pointers(uidlist); i_assert(uidlist->cur_block_end_indexes != NULL); /* verify just a couple of the end indexes to make sure they look correct */ verify_count = I_MIN(block_count, 8); for (i = 1; i < verify_count; i++) { if (unlikely(uidlist->cur_block_end_indexes[i-1] >= uidlist->cur_block_end_indexes[i])) { squat_uidlist_set_corrupted(uidlist, "block list corrupted"); return 0; } } return 1; }
void mail_transaction_log_get_dotlock_set(struct mail_transaction_log *log, struct dotlock_settings *set_r) { struct mail_index *index = log->index; memset(set_r, 0, sizeof(*set_r)); set_r->timeout = I_MIN(MAIL_TRANSACTION_LOG_LOCK_TIMEOUT, index->max_lock_timeout_secs); set_r->stale_timeout = MAIL_TRANSACTION_LOG_LOCK_CHANGE_TIMEOUT; set_r->nfs_flush = (index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0; set_r->use_excl_lock = (index->flags & MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL) != 0; }
static void test_penalty_checksum(void) { struct penalty *penalty; struct ioloop *ioloop; time_t t; unsigned int i, j; test_begin("penalty"); ioloop = io_loop_create(); penalty = penalty_init(); test_assert(penalty_get(penalty, "foo", &t) == 0); for (i = 1; i <= 10; i++) { ioloop_time = 12345678 + i; penalty_inc(penalty, "foo", i, 5+i); for (j = I_MIN(1, i-1); j <= i; j++) { test_assert(penalty_get(penalty, "foo", &t) == 5+i); test_assert(t == (time_t)(12345678 + i)); test_assert(penalty_has_checksum(penalty, "foo", i)); } test_assert(penalty_get(penalty, "foo", &t) == 5+i); test_assert(t == (time_t)(12345678 + i)); test_assert(!penalty_has_checksum(penalty, "foo", j)); } test_assert(penalty_get(penalty, "foo2", &t) == 0); /* overflows checksum array */ ioloop_time = 12345678 + i; penalty_inc(penalty, "foo", i, 5 + i); penalty_inc(penalty, "foo", i, 5 + i); penalty_inc(penalty, "foo", 0, 5 + i); test_assert(penalty_get(penalty, "foo", &t) == 5+i); test_assert(t == (time_t)(12345678 + i)); test_assert(!penalty_has_checksum(penalty, "foo", 1)); for (j = 2; j <= i; j++) { test_assert(penalty_get(penalty, "foo", &t) == 5+i); test_assert(t == (time_t)(12345678 + i)); test_assert(penalty_has_checksum(penalty, "foo", i)); } penalty_deinit(&penalty); io_loop_destroy(&ioloop); test_end(); }
const char *str_sanitize(const char *src, size_t max_bytes) { string_t *str; size_t i; if (src == NULL) return NULL; i = str_sanitize_skip_start(src, max_bytes); if (src[i] == '\0') return src; str = t_str_new(I_MIN(max_bytes, 256)); str_sanitize_append(str, src, max_bytes); return str_c(str); }
int mail_transaction_log_file_lock(struct mail_transaction_log_file *file) { unsigned int lock_timeout_secs; int ret; if (file->locked) return 0; if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { file->locked = TRUE; return 0; } if (file->log->index->lock_method == FILE_LOCK_METHOD_DOTLOCK) return mail_transaction_log_file_dotlock(file); if (file->log->index->readonly) { mail_index_set_error(file->log->index, "Index is read-only, can't write-lock %s", file->filepath); return -1; } i_assert(file->file_lock == NULL); lock_timeout_secs = I_MIN(MAIL_TRANSACTION_LOG_LOCK_TIMEOUT, file->log->index->max_lock_timeout_secs); ret = mail_index_lock_fd(file->log->index, file->filepath, file->fd, F_WRLCK, lock_timeout_secs, &file->file_lock); if (ret > 0) { file->locked = TRUE; file->lock_created = time(NULL); return 0; } if (ret < 0) { log_file_set_syscall_error(file, "mail_index_wait_lock_fd()"); return -1; } mail_index_set_error(file->log->index, "Timeout (%us) while waiting for lock for " "transaction log file %s%s", lock_timeout_secs, file->filepath, file_lock_find(file->fd, file->log->index->lock_method, F_WRLCK)); file->log->index->index_lock_timeout = TRUE; return -1; }
bool stream_cmp_block(struct istream *input, const unsigned char *data, size_t size) { const unsigned char *indata; size_t insize, max; while (size > 0) { (void)i_stream_read_data(input, &indata, &insize, size-1); max = I_MIN(insize, size); if (insize == 0 || memcmp(data, indata, max) != 0) return FALSE; data += max; size -= max; i_stream_skip(input, max); } return TRUE; }
static bool proxy_try_reconnect(struct login_proxy *proxy) { int since_started_msecs, left_msecs; since_started_msecs = timeval_diff_msecs(&ioloop_timeval, &proxy->created); if (since_started_msecs < 0) return FALSE; /* time moved backwards */ left_msecs = proxy->connect_timeout_msecs - since_started_msecs; if (left_msecs <= 0) return FALSE; login_proxy_disconnect(proxy); proxy->to = timeout_add(I_MIN(PROXY_CONNECT_RETRY_MSECS, left_msecs), proxy_reconnect_timeout, proxy); proxy->reconnect_count++; return TRUE; }
static ssize_t mail_transaction_log_file_read_header(struct mail_transaction_log_file *file) { void *dest; size_t pos, dest_size; ssize_t ret; i_assert(file->buffer == NULL && file->mmap_base == NULL); memset(&file->hdr, 0, sizeof(file->hdr)); if (file->last_size < mmap_get_page_size() && file->last_size > 0) { /* just read the entire transaction log to memory. note that if some of the data hasn't been fully committed yet (hdr.size=0), the buffer must be truncated later */ file->buffer = buffer_create_dynamic(default_pool, 4096); file->buffer_offset = 0; dest_size = file->last_size; dest = buffer_append_space_unsafe(file->buffer, dest_size); } else { /* read only the header */ dest = &file->hdr; dest_size = sizeof(file->hdr); } /* it's not necessarily an error to read less than wanted header size, since older versions of the log format used smaller headers. */ pos = 0; do { ret = pread(file->fd, PTR_OFFSET(dest, pos), dest_size - pos, pos); if (ret > 0) pos += ret; } while (ret > 0 && pos < dest_size); if (file->buffer != NULL) { buffer_set_used_size(file->buffer, pos); memcpy(&file->hdr, file->buffer->data, I_MIN(pos, sizeof(file->hdr))); } return ret < 0 ? -1 : (ssize_t)pos; }
int sdbox_read_header(struct sdbox_mailbox *mbox, struct sdbox_index_header *hdr, bool log_error, bool *need_resize_r) { struct mail_index_view *view; const void *data; size_t data_size; int ret = 0; i_assert(mbox->box.opened); view = mail_index_view_open(mbox->box.index); mail_index_get_header_ext(view, mbox->hdr_ext_id, &data, &data_size); if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE && (!mbox->box.creating || data_size != 0)) { if (log_error) { mail_storage_set_critical( &mbox->storage->storage.storage, "sdbox %s: Invalid dbox header size", mailbox_get_path(&mbox->box)); } ret = -1; } else { memset(hdr, 0, sizeof(*hdr)); memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr))); if (guid_128_is_empty(hdr->mailbox_guid)) ret = -1; else { /* data is valid. remember it in case mailbox is being reset */ mail_index_set_ext_init_data(mbox->box.index, mbox->hdr_ext_id, hdr, sizeof(*hdr)); } } mail_index_view_close(&view); *need_resize_r = data_size < sizeof(*hdr); return ret; }
static ssize_t o_stream_buffer_sendv(struct ostream_private *stream, const struct const_iovec *iov, unsigned int iov_count) { struct buffer_ostream *bstream = (struct buffer_ostream *)stream; size_t left, n; ssize_t ret = 0; unsigned int i; for (i = 0; i < iov_count; i++) { left = bstream->ostream.max_buffer_size - stream->ostream.offset; n = I_MIN(left, iov[i].iov_len); buffer_write(bstream->buf, stream->ostream.offset, iov[i].iov_base, n); ret += n; if (n != iov[i].iov_len) break; } stream->ostream.offset += ret; return ret; }
int mdbox_read_header(struct mdbox_mailbox *mbox, struct mdbox_index_header *hdr, bool *need_resize_r) { const void *data; size_t data_size; i_assert(mbox->box.opened); mail_index_get_header_ext(mbox->box.view, mbox->hdr_ext_id, &data, &data_size); if (data_size < MDBOX_INDEX_HEADER_MIN_SIZE && (!mbox->creating || data_size != 0)) { mail_storage_set_critical(&mbox->storage->storage.storage, "mdbox %s: Invalid dbox header size: %"PRIuSIZE_T, mailbox_get_path(&mbox->box), data_size); mdbox_storage_set_corrupted(mbox->storage); return -1; } memset(hdr, 0, sizeof(*hdr)); memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr))); *need_resize_r = data_size < sizeof(*hdr); return 0; }
static int i_stream_base64_try_decode_block(struct base64_decoder_istream *bstream) { struct istream_private *stream = &bstream->istream; const unsigned char *data; size_t size, avail, buffer_avail, pos; buffer_t buf; data = i_stream_get_data(stream->parent, &size); if (size == 0) return 0; i_stream_try_alloc(stream, (size+3)/4*3, &avail); buffer_avail = stream->buffer_size - stream->pos; if ((size + 3) / 4 * 3 > buffer_avail) { /* can't fit everything to destination buffer. write as much as we can. */ size = (buffer_avail / 3) * 4; if (size == 0) return -2; } buffer_create_from_data(&buf, stream->w_buffer + stream->pos, buffer_avail); if (base64_decode(data, size, &pos, &buf) < 0) { io_stream_set_error(&stream->iostream, "Invalid base64 data: 0x%s", binary_to_hex(data+pos, I_MIN(size-pos, 8))); stream->istream.stream_errno = EINVAL; return -1; } stream->pos += buf.used; i_stream_skip(stream->parent, pos); return pos > 0 ? 1 : 0; }
static int solr_xml_parse(struct solr_connection *conn, const void *data, size_t size, bool done) { enum XML_Error err; int line, col; if (conn->xml_failed) return -1; if (XML_Parse(conn->xml_parser, data, size, done)) return 0; err = XML_GetErrorCode(conn->xml_parser); if (err != XML_ERROR_FINISHED) { line = XML_GetCurrentLineNumber(conn->xml_parser); col = XML_GetCurrentColumnNumber(conn->xml_parser); i_error("fts_solr: Invalid XML input at %d:%d: %s " "(near: %.*s)", line, col, XML_ErrorString(err), (int)I_MIN(size, 128), (const char *)data); conn->xml_failed = TRUE; return -1; } return 0; }
static ssize_t i_stream_mmap_read(struct istream_private *stream) { struct mmap_istream *mstream = (struct mmap_istream *) stream; size_t aligned_skip; uoff_t top; if (stream->pos < stream->buffer_size) { /* more bytes available without needing to mmap() */ stream->pos = stream->buffer_size; return stream->pos - stream->skip; } if (stream->istream.v_offset >= mstream->v_size) { stream->istream.eof = TRUE; return -1; } aligned_skip = stream->skip & ~mmap_pagemask; if (aligned_skip == 0 && mstream->mmap_base != NULL) { /* didn't skip enough bytes */ return -2; } stream->skip -= aligned_skip; mstream->mmap_offset += aligned_skip; if (mstream->mmap_base != NULL) { if (munmap(mstream->mmap_base, stream->buffer_size) < 0) { i_error("mmap_istream.munmap(%s) failed: %m", i_stream_get_name(&stream->istream)); } } top = mstream->v_size - mstream->mmap_offset; stream->buffer_size = I_MIN(top, mstream_get_mmap_block_size(stream)); i_assert((uoff_t)mstream->mmap_offset + stream->buffer_size <= mstream->v_size); if (stream->buffer_size == 0) { /* don't bother even trying mmap */ mstream->mmap_base = NULL; stream->buffer = NULL; } else { mstream->mmap_base = mmap(NULL, stream->buffer_size, PROT_READ, MAP_PRIVATE, stream->fd, mstream->mmap_offset); if (mstream->mmap_base == MAP_FAILED) { i_assert(errno != 0); stream->istream.stream_errno = errno; mstream->mmap_base = NULL; stream->buffer = NULL; stream->buffer_size = 0; stream->skip = stream->pos = 0; i_error("mmap_istream.mmap(%s) failed: %m", i_stream_get_name(&stream->istream)); return -1; } stream->buffer = mstream->mmap_base; } if (stream->buffer_size > mmap_get_page_size()) { if (madvise(mstream->mmap_base, stream->buffer_size, MADV_SEQUENTIAL) < 0) { i_error("mmap_istream.madvise(%s): %m", i_stream_get_name(&stream->istream)); } } stream->pos = stream->buffer_size; i_assert(stream->pos - stream->skip > 0); return stream->pos - stream->skip; }