static void test_load_v2_key(void) { const char *keys[] = { "-----BEGIN PRIVATE KEY-----\n" \ "MGcCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcETTBLAgEBBCC25AkD65uhlZXCAdwN\n" \ "yLJV2ui8A/CUyqyEMrezvwgMO6EkAyIAAybRUR3MsH0+0PQcDwkrXOJ9aePwzTQV\n" \ "DN51+n1JCxbI\n" \ "-----END PRIVATE KEY-----\n", "2\t1.2.840.10045.3.1.7\t0\t0000002100b6e40903eb9ba19595c201dc0dc8b255dae8bc03f094caac8432b7b3bf080c3b\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd", "2\t1.2.840.10045.3.1.7\t2\taes-256-ctr\t2b19763d4bbf7754\tsha256\t2048\tc36fa194669a1aec400eae32fbadaa7c58b14f53c464cfbb0a4b61fbe24ab7750637c4025d\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd", "2\t1.2.840.10045.3.1.7\t1\taes-256-ctr\t7c7f1d12a7c011de\tsha256\t2048\tf5d1de11d58a81b141cf038012a618623e9d7b18062deeb3a4e35872c62ca0837db8688370\t021abfbc5bc4f6cf49c40b9fc388c4616ea079941675f477ee4557df1919626d35\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd" }; test_begin("test_load_v2_key"); const char *error = NULL; buffer_t *tmp = buffer_create_dynamic(default_pool, 256); struct dcrypt_private_key *priv,*priv2; test_assert_idx(dcrypt_key_load_private(&priv2, DCRYPT_FORMAT_PEM, keys[0], NULL, NULL, &error), 0); test_assert_idx(dcrypt_key_store_private(priv2, DCRYPT_FORMAT_PEM, NULL, tmp, NULL, NULL, &error), 0); test_assert_idx(strcmp(str_c(tmp), keys[0])==0, 0); buffer_set_used_size(tmp, 0); test_assert_idx(dcrypt_key_load_private(&priv, DCRYPT_FORMAT_DOVECOT, keys[1], NULL, NULL, &error), 1); test_assert_idx(dcrypt_key_store_private(priv, DCRYPT_FORMAT_DOVECOT, NULL, tmp, NULL, NULL, &error), 1); test_assert_idx(strcmp(str_c(tmp), keys[1])==0, 1); buffer_set_used_size(tmp, 0); dcrypt_key_free_private(&priv); test_assert_idx(dcrypt_key_load_private(&priv, DCRYPT_FORMAT_DOVECOT, keys[2], "This Is Sparta", NULL, &error), 2); test_assert_idx(dcrypt_key_store_private(priv, DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", tmp, "This Is Sparta", NULL, &error), 2); buffer_set_used_size(tmp, 0); dcrypt_key_free_private(&priv); struct dcrypt_public_key *pub = NULL; dcrypt_key_convert_private_to_public(priv2, &pub); test_assert_idx(dcrypt_key_load_private(&priv, DCRYPT_FORMAT_DOVECOT, keys[3], NULL, priv2, &error), 3); test_assert_idx(dcrypt_key_store_private(priv, DCRYPT_FORMAT_DOVECOT, "ecdh-aes-256-ctr", tmp, NULL, pub, &error), 3); buffer_set_used_size(tmp, 0); dcrypt_key_free_private(&priv2); dcrypt_key_free_private(&priv); dcrypt_key_free_public(&pub); buffer_free(&tmp); if (error != NULL) error = NULL; test_end(); }
static void test_quoted_printable_decode(void) { static struct test_quoted_printable_decode_data data[] = { { "foo \r\nbar=", "foo\r\nbar", 1, 0 }, { "foo\t=\nbar", "foo\tbar", 0, 0 }, { "foo = \n=01", "foo \001", 0, 0 }, { "foo =\t\r\nbar", "foo bar", 0, 0 }, { "foo =\r\n=01", "foo \001", 0, 0 }, { "foo \nbar=", "foo\nbar", 1, 0 }, { "=0A=0D ", "\n\r", 2, 0 }, { "foo_bar", "foo_bar", 0, 0 }, { "foo=", "foo", 1, 0 }, { "foo= ", "foo", 3, 0 }, { "foo=A", "foo", 2, 0 }, { "foo=Ax", "foo=Ax", 0, -1 }, { "foo=Ax=xy", "foo=Ax=xy", 0, -1 } }; buffer_t *buf; unsigned int i, start, end, len; size_t src_pos; int ret; test_begin("quoted printable decode"); buf = buffer_create_dynamic(pool_datastack_create(), 128); for (i = 0; i < N_ELEMENTS(data); i++) { len = strlen(data[i].input); ret = quoted_printable_decode((const void *)data[i].input, len, &src_pos, buf); test_assert(ret == data[i].ret); test_assert(src_pos + data[i].end_skip == len); test_assert(strcmp(data[i].output, str_c(buf)) == 0); buffer_set_used_size(buf, 0); for (start = 0, end = 1; end <= len; ) { quoted_printable_decode(CONST_PTR_OFFSET(data[i].input, start), end - start, &src_pos, buf); src_pos += start; start = src_pos; if (src_pos <= end) end++; else end = src_pos + 1; } test_assert(src_pos + data[i].end_skip == len); test_assert(strcmp(data[i].output, str_c(buf)) == 0); buffer_set_used_size(buf, 0); } test_end(); }
static void remove_subj_trailers(buffer_t *buf, size_t start_pos, bool *is_reply_or_forward_r) { const char *data; size_t orig_size, size; /* subj-trailer = "(fwd)" / WSP */ data = buffer_get_data(buf, &orig_size); if (orig_size < 1) /* size includes trailing \0 */ return; for (size = orig_size-1; size > start_pos; ) { if (data[size-1] == ' ') size--; else if (size >= 5 && memcmp(data + size - 5, "(FWD)", 5) == 0) { *is_reply_or_forward_r = TRUE; size -= 5; } else { break; } } if (size != orig_size-1) { buffer_set_used_size(buf, size); buffer_append_c(buf, '\0'); } }
void fts_icu_lcase(string_t *dest_utf8, const char *src_utf8) { struct UCaseMap *csm = fts_icu_csm(); size_t avail_bytes, dest_pos = dest_utf8->used; char *dest_data; int dest_full_len; UErrorCode err = U_ZERO_ERROR; avail_bytes = buffer_get_writable_size(dest_utf8) - dest_pos; dest_data = buffer_get_space_unsafe(dest_utf8, dest_pos, avail_bytes); dest_full_len = ucasemap_utf8ToLower(csm, dest_data, avail_bytes, src_utf8, -1, &err); if (err == U_BUFFER_OVERFLOW_ERROR) { err = U_ZERO_ERROR; dest_data = buffer_get_space_unsafe(dest_utf8, dest_pos, dest_full_len); dest_full_len = ucasemap_utf8ToLower(csm, dest_data, dest_full_len, src_utf8, -1, &err); i_assert(err != U_BUFFER_OVERFLOW_ERROR); } if (U_FAILURE(err)) { i_fatal("LibICU ucasemap_utf8ToLower() failed: %s", u_errorName(err)); } buffer_set_used_size(dest_utf8, dest_full_len); }
void message_decoder_decode_reset(struct message_decoder_context *ctx) { i_free_and_null(ctx->content_charset); ctx->message_cte = MESSAGE_CTE_78BIT; ctx->charset_utf8 = TRUE; buffer_set_used_size(ctx->encoding_buf, 0); }
static bool fts_tokenizer_generic_simple_current_token(struct generic_fts_tokenizer *tok, const char **token_r) { const unsigned char *data = tok->token->data; size_t len = tok->token->used; if (tok->untruncated_length <= tok->max_length) { /* Remove the trailing apostrophe - it was made into U+0027 earlier. There can be only a single such apostrophe, because otherwise the token would have already been split. We also want to remove the trailing apostrophe only if it's the the last character in the nontruncated token - a truncated token may end with apostrophe. */ if (len > 0 && data[len-1] == '\'') { len--; i_assert(len > 0 && data[len-1] != '\''); } } else { fts_tokenizer_delete_trailing_partial_char(data, &len); } i_assert(len <= tok->max_length); *token_r = len == 0 ? "" : t_strndup(tok->token->data, len); buffer_set_used_size(tok->token, 0); tok->untruncated_length = 0; tok->prev_letter = LETTER_TYPE_NONE; return len > 0; }
static void test_quoted_printable_decode_final(void) { static struct test_quoted_printable_decode_data data[] = { { "=0A=0D ", "\n\r", 2, 0 }, { "foo=", "foo", 1, 0 }, { "foo ", "foo", 2, 0 }, { "foo= ", "foo", 3, 0 }, { "foo=A", "foo", 2, -1 } }; buffer_t *buf; unsigned int i, len; size_t src_pos; int ret; test_begin("quoted printable decode final"); buf = buffer_create_dynamic(pool_datastack_create(), 128); for (i = 0; i < N_ELEMENTS(data); i++) { len = strlen(data[i].input); ret = quoted_printable_decode_final((const void *)data[i].input, len, &src_pos, buf); test_assert(ret == data[i].ret); test_assert(src_pos + data[i].end_skip == len); test_assert(strcmp(data[i].output, str_c(buf)) == 0); buffer_set_used_size(buf, 0); } test_end(); }
static void test_buffer_set_used_size(void) { buffer_t *buf; test_begin("buffer_set_used_size"); buf = t_buffer_create(8); memset(buffer_append_space_unsafe(buf, 7), 'a', 7); buffer_set_used_size(buf, 4); test_assert(memcmp(buffer_get_space_unsafe(buf, 0, 7), "aaaa\0\0\0", 7) == 0); memset(buffer_get_space_unsafe(buf, 4, 7), 'b', 7); buffer_set_used_size(buf, 10); test_assert(memcmp(buffer_append_space_unsafe(buf, 1), "\0", 1) == 0); buffer_set_used_size(buf, 11); test_assert(memcmp(buffer_get_space_unsafe(buf, 0, 11), "aaaabbbbbb\0", 11) == 0); test_end(); }
void fts_icu_utf16_to_utf8(string_t *dest_utf8, const UChar *src_utf16, unsigned int src_len) { int32_t dest_len = 0; int32_t sub_num = 0; char *dest_data, *retp = NULL; UErrorCode err = U_ZERO_ERROR; /* try to encode with the current buffer size */ dest_data = buffer_get_space_unsafe(dest_utf8, 0, buffer_get_writable_size(dest_utf8)); retp = u_strToUTF8WithSub(dest_data, buffer_get_writable_size(dest_utf8), &dest_len, src_utf16, src_len, UNICODE_REPLACEMENT_CHAR, &sub_num, &err); if (err == U_BUFFER_OVERFLOW_ERROR) { /* try again with a larger buffer */ dest_data = buffer_get_space_unsafe(dest_utf8, 0, dest_len); err = U_ZERO_ERROR; retp = u_strToUTF8WithSub(dest_data, buffer_get_writable_size(dest_utf8), &dest_len, src_utf16, src_len, UNICODE_REPLACEMENT_CHAR, &sub_num, &err); } if (U_FAILURE(err)) { i_panic("LibICU u_strToUTF8WithSub() failed: %s", u_errorName(err)); } buffer_set_used_size(dest_utf8, dest_len); i_assert(retp == dest_data); }
static void test_fts_icu_translate_resize(void) { const char *translit_id = "Any-Hex"; const char *src_utf8 = "FOO"; buffer_t *dest, *src_utf16; UTransliterator *translit; const char *error; unsigned int i; test_begin("fts_icu_translate_resize resize"); src_utf16 = buffer_create_dynamic(pool_datastack_create(), 16); translit = get_translit(translit_id); for (i = 2; i <= 20; i++) { buffer_set_used_size(src_utf16, 0); fts_icu_utf8_to_utf16(src_utf16, src_utf8); dest = buffer_create_dynamic(pool_datastack_create(), i); test_assert(buffer_get_size(dest) == i); test_assert(fts_icu_translate(dest, src_utf16->data, src_utf16->used/sizeof(UChar), translit, &error) == 0); } utrans_close(translit); test_end(); }
static void mail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file) { struct mail_transaction_log_file **p; file->sync_offset = file->hdr.hdr_size; file->sync_highest_modseq = file->hdr.initial_modseq; mail_transaction_log_file_skip_to_head(file); /* insert it to correct position */ for (p = &file->log->files; *p != NULL; p = &(*p)->next) { if ((*p)->hdr.file_seq > file->hdr.file_seq) break; i_assert((*p)->hdr.file_seq < file->hdr.file_seq); } file->next = *p; *p = file; if (file->buffer != NULL) { /* if we read any unfinished data, make sure the buffer gets truncated. */ (void)mail_transaction_log_file_sync(file); buffer_set_used_size(file->buffer, file->sync_offset - file->buffer_offset); } }
static bool remove_subj_fwd_hdr(buffer_t *buf, size_t *start_pos, bool *is_reply_or_forward_r) { const char *data; size_t size; /* subj-fwd = subj-fwd-hdr subject subj-fwd-trl subj-fwd-hdr = "[fwd:" subj-fwd-trl = "]" */ data = buffer_get_data(buf, &size); if (strncmp(data + *start_pos, "[FWD:", 5) != 0) return FALSE; if (data[size-2] != ']') return FALSE; *is_reply_or_forward_r = TRUE; buffer_set_used_size(buf, size-2); buffer_append_c(buf, '\0'); *start_pos += 5; return TRUE; }
static int mail_transaction_log_file_read_more(struct mail_transaction_log_file *file) { void *data; size_t size; uint32_t read_offset; ssize_t ret; read_offset = file->buffer_offset + file->buffer->used; do { data = buffer_append_space_unsafe(file->buffer, LOG_PREFETCH); ret = pread(file->fd, data, LOG_PREFETCH, read_offset); if (ret > 0) read_offset += ret; size = read_offset - file->buffer_offset; buffer_set_used_size(file->buffer, size); } while (ret > 0 || (ret < 0 && errno == EINTR)); file->last_size = read_offset; if (ret < 0) { if (errno == ESTALE) { /* log file was deleted in NFS server, fail silently */ return 0; } log_file_set_syscall_error(file, "pread()"); return -1; } return 1; }
static int mail_transaction_log_file_insert_read(struct mail_transaction_log_file *file, uoff_t offset) { void *data; size_t size; ssize_t ret; size = file->buffer_offset - offset; buffer_copy(file->buffer, size, file->buffer, 0, (size_t)-1); data = buffer_get_space_unsafe(file->buffer, 0, size); ret = pread_full(file->fd, data, size, offset); if (ret > 0) { /* success */ file->buffer_offset -= size; return 1; } /* failure. don't leave ourself to inconsistent state */ buffer_copy(file->buffer, 0, file->buffer, size, (size_t)-1); buffer_set_used_size(file->buffer, file->buffer->used - size); if (ret == 0) { mail_transaction_log_file_set_corrupted(file, "file shrank"); return 0; } else if (errno == ESTALE) { /* log file was deleted in NFS server, fail silently */ return 0; } else { log_file_set_syscall_error(file, "pread()"); return -1; } }
void fts_icu_utf8_to_utf16(buffer_t *dest_utf16, const char *src_utf8) { UErrorCode err = U_ZERO_ERROR; unsigned int src_bytes = strlen(src_utf8); int32_t utf16_len; UChar *dest_data, *retp = NULL; int32_t avail_uchars = 0; /* try to encode with the current buffer size */ avail_uchars = buffer_get_writable_size(dest_utf16) / sizeof(UChar); dest_data = buffer_get_space_unsafe(dest_utf16, 0, buffer_get_writable_size(dest_utf16)); retp = u_strFromUTF8Lenient(dest_data, avail_uchars, &utf16_len, src_utf8, src_bytes, &err); if (err == U_BUFFER_OVERFLOW_ERROR) { /* try again with a larger buffer */ dest_data = buffer_get_space_unsafe(dest_utf16, 0, utf16_len * sizeof(UChar)); err = U_ZERO_ERROR; retp = u_strFromUTF8Lenient(dest_data, utf16_len, &utf16_len, src_utf8, src_bytes, &err); } if (U_FAILURE(err)) { i_panic("LibICU u_strFromUTF8Lenient() failed: %s", u_errorName(err)); } buffer_set_used_size(dest_utf16, utf16_len * sizeof(UChar)); i_assert(retp == dest_data); }
static bool verify_b(const char *str, unsigned int i, bool starts_with_a) { unsigned int line_start = i, start, j, char_count = 0; char bufdata[1000]; buffer_t buf; buffer_create_from_data(&buf, bufdata, sizeof(bufdata)); if (strncmp(str+i, "\n\t", 2) == 0) { i += 2; line_start = i - 1; } for (;;) { if (strncmp(str+i, "=?utf-8?b?", 10) != 0) return FALSE; i += 10; start = i; for (; str[i] != '?'; i++) { if (str[i] == '\0') return FALSE; } buffer_set_used_size(&buf, 0); if (base64_decode(str+start, i-start, NULL, &buf) < 0) return FALSE; i++; if (!starts_with_a) j = 0; else { if (bufdata[0] != 'a') return FALSE; starts_with_a = FALSE; j = 1; } for (; j < buf.used; j += 2) { if (bufdata[j] != '\xc3' || bufdata[j+1] != '\xa4') return FALSE; char_count++; } if (j != buf.used) return FALSE; if (str[i++] != '=') return FALSE; if (i - line_start > 76) return FALSE; if (str[i] == '\0') break; if (strncmp(str+i, "\n\t", 2) != 0) return FALSE; i += 2; line_start = i - 1; } return char_count == 40; }
static void test_load_v1_key(void) { test_begin("test_load_v1_key"); buffer_t *key_1 = buffer_create_dynamic(pool_datastack_create(), 128); struct dcrypt_private_key *pkey = NULL, *pkey2 = NULL; const char *error = NULL; test_assert(dcrypt_key_load_private(&pkey, DCRYPT_FORMAT_DOVECOT, "1\t716\t0\t048FD04FD3612B22D32790C592CF21CEF417EFD2EA34AE5F688FA5B51BED29E05A308B68DA78E16E90B47A11E133BD9A208A2894FD01B0BEE865CE339EA3FB17AC\td0cfaca5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615e77a0", NULL, NULL, &error)); if (pkey != NULL) { buffer_set_used_size(key_1, 0); /* check that key_id matches */ struct dcrypt_public_key *pubkey = NULL; dcrypt_key_convert_private_to_public(pkey, &pubkey); test_assert(dcrypt_key_store_public(pubkey, DCRYPT_FORMAT_DOVECOT, key_1, NULL)); buffer_set_used_size(key_1, 0); dcrypt_key_id_public(pubkey, "sha256", key_1, &error); test_assert(strcmp("792caad4d38c9eb2134a0cbc844eae386116de096a0ccafc98479825fc99b6a1", binary_to_hex(key_1->data, key_1->used)) == 0); dcrypt_key_free_public(&pubkey); pkey2 = NULL; test_assert(dcrypt_key_load_private(&pkey2, DCRYPT_FORMAT_DOVECOT, "1\t716\t1\t0567e6bf9579813ae967314423b0fceb14bda24749303923de9a9bb9370e0026f995901a57e63113eeb2baf0c940e978d00686cbb52bd5014bc318563375876255\t0300E46DA2125427BE968EB3B649910CDC4C405E5FFDE18D433A97CABFEE28CEEFAE9EE356C792004FFB80981D67E741B8CC036A34235A8D2E1F98D1658CFC963D07EB\td0cfaca5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615e77a0\t7c9a1039ea2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea858b00fa4f", NULL, pkey, &error)); if (pkey2 != NULL) { buffer_set_used_size(key_1, 0); /* check that key_id matches */ struct dcrypt_public_key *pubkey = NULL; dcrypt_key_convert_private_to_public(pkey2, &pubkey); test_assert(dcrypt_key_store_public(pubkey, DCRYPT_FORMAT_DOVECOT, key_1, NULL)); buffer_set_used_size(key_1, 0); test_assert(dcrypt_key_id_public_old(pubkey, key_1, &error)); test_assert(strcmp("7c9a1039ea2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea858b00fa4f", binary_to_hex(key_1->data, key_1->used)) == 0); dcrypt_key_free_public(&pubkey); dcrypt_key_free_private(&pkey2); } dcrypt_key_free_private(&pkey); } test_end(); }
static void fts_tokenizer_generic_reset(struct fts_tokenizer *_tok) { struct generic_fts_tokenizer *tok = (struct generic_fts_tokenizer *)_tok; tok->prev_letter = LETTER_TYPE_NONE; tok->prev_prev_letter = LETTER_TYPE_NONE; tok->untruncated_length = 0; buffer_set_used_size(tok->token, 0); }
static int dump_record(int fd, buffer_t *buf) { struct fts_expunge_log_record rec; off_t offset; void *data; const uint32_t *expunges, *uids; ssize_t ret; size_t data_size; unsigned int i, uids_count; offset = lseek(fd, 0, SEEK_CUR); ret = read(fd, &rec, sizeof(rec)); if (ret == 0) return 0; if (ret != sizeof(rec)) i_fatal("rec read() %d != %d", (int)ret, (int)sizeof(rec)); if (rec.record_size < sizeof(rec) + sizeof(uint32_t) || rec.record_size > INT_MAX) { i_fatal("Invalid record_size=%u at offset %"PRIuUOFF_T, rec.record_size, offset); } data_size = rec.record_size - sizeof(rec); buffer_set_used_size(buf, 0); data = buffer_append_space_unsafe(buf, data_size); ret = read(fd, data, data_size); if (ret != (ssize_t)data_size) i_fatal("rec read() %d != %d", (int)ret, (int)data_size); printf("#%"PRIuUOFF_T":\n", offset); printf(" checksum = %8x\n", rec.checksum); printf(" size .... = %u\n", rec.record_size); printf(" mailbox . = %s\n", guid_128_to_string(rec.guid)); expunges = CONST_PTR_OFFSET(data, data_size - sizeof(uint32_t)); printf(" expunges = %u\n", *expunges); printf(" uids .... = "); uids = data; uids_count = (rec.record_size - sizeof(rec) - sizeof(uint32_t)) / sizeof(uint32_t); for (i = 0; i < uids_count; i += 2) { if (i != 0) printf(","); if (uids[i] == uids[i+1]) printf("%u", uids[i]); else printf("%u-%u", uids[i], uids[i+1]); } printf("\n"); return 1; }
void message_decoder_decode_reset(struct message_decoder_context *ctx) { const char *error; if (ctx->qp != NULL) (void)qp_decoder_finish(ctx->qp, &error); i_free_and_null(ctx->content_type); i_free_and_null(ctx->content_charset); ctx->message_cte = MESSAGE_CTE_78BIT; buffer_set_used_size(ctx->encoding_buf, 0); }
int fts_icu_translate(buffer_t *dest_utf16, const UChar *src_utf16, unsigned int src_len, UTransliterator *transliterator, const char **error_r) { UErrorCode err = U_ZERO_ERROR; int32_t utf16_len = src_len; UChar *dest_data; int32_t avail_uchars, limit = src_len; size_t dest_pos = dest_utf16->used; /* translation is done in-place in the buffer. try first with the current buffer size. */ buffer_append(dest_utf16, src_utf16, src_len*sizeof(UChar)); avail_uchars = (buffer_get_writable_size(dest_utf16)-dest_pos) / sizeof(UChar); dest_data = buffer_get_space_unsafe(dest_utf16, dest_pos, buffer_get_writable_size(dest_utf16)-dest_pos); utrans_transUChars(transliterator, dest_data, &utf16_len, avail_uchars, 0, &limit, &err); if (err == U_BUFFER_OVERFLOW_ERROR) { /* try again with a larger buffer */ err = U_ZERO_ERROR; avail_uchars = utf16_len; limit = utf16_len = src_len; buffer_write(dest_utf16, dest_pos, src_utf16, src_len*sizeof(UChar)); dest_data = buffer_get_space_unsafe(dest_utf16, dest_pos, avail_uchars * sizeof(UChar)); utrans_transUChars(transliterator, dest_data, &utf16_len, avail_uchars, 0, &limit, &err); i_assert(err != U_BUFFER_OVERFLOW_ERROR); } if (U_FAILURE(err)) { *error_r = t_strdup_printf("LibICU utrans_transUChars() failed: %s", u_errorName(err)); buffer_set_used_size(dest_utf16, dest_pos); return -1; } buffer_set_used_size(dest_utf16, utf16_len * sizeof(UChar)); return 0; }
static void str_add_nul(string_t *str) { const unsigned char *data = str_data(str); size_t len = str_len(str); size_t alloc = buffer_get_size(str); if (len == alloc || data[len] != '\0') { buffer_write(str, len, "", 1); /* remove the \0 - we don't want to keep it */ buffer_set_used_size(str, len); } }
static void astream_add_body(struct attachment_istream *astream, const struct message_block *block) { struct attachment_istream_part *part = &astream->part; buffer_t *part_buf; size_t new_size; switch (part->state) { case MAIL_ATTACHMENT_STATE_NO: stream_add_data(astream, block->data, block->size); break; case MAIL_ATTACHMENT_STATE_MAYBE: /* we'll write data to in-memory buffer until we reach attachment min_size */ if (part->part_buf == NULL) { part->part_buf = buffer_create_dynamic(default_pool, astream->set.min_size); } part_buf = part->part_buf; new_size = part_buf->used + block->size; if (new_size < astream->set.min_size) { buffer_append(part_buf, block->data, block->size); break; } /* attachment is large enough. we'll first copy the buffered data from memory to temp file */ if (astream_open_output(astream) < 0) { /* failed, fallback to just saving it inline */ part->state = MAIL_ATTACHMENT_STATE_NO; stream_add_data(astream, part_buf->data, part_buf->used); stream_add_data(astream, block->data, block->size); break; } part->state = MAIL_ATTACHMENT_STATE_YES; astream_try_base64_decode(part, part_buf->data, part_buf->used); hash_format_loop(astream->set.hash_format, part_buf->data, part_buf->used); o_stream_nsend(part->temp_output, part_buf->data, part_buf->used); buffer_set_used_size(part_buf, 0); /* fall through to write the new data to temp file */ case MAIL_ATTACHMENT_STATE_YES: astream_try_base64_decode(part, block->data, block->size); hash_format_loop(astream->set.hash_format, block->data, block->size); o_stream_nsend(part->temp_output, block->data, block->size); break; } }
static void test_foo(void) { buffer_t *buf = buffer_create_dynamic(default_pool, 100); for (int i = 1; i <= 24; i++) { buffer_set_used_size(buf, 0); buffer_append_c(buf, 0xff); buffer_append_c(buf, 0xff); buffer_append_c(buf, 0xff); buffer_truncate_rshift_bits(buf, i); printf("%2d bits: %24s %s\n", i, binary_to_hex(buf->data, buf->used), binary_to_10(buf->data, buf->used)); } }
static int mail_transaction_log_file_read(struct mail_transaction_log_file *file, uoff_t start_offset, bool nfs_flush) { int ret; i_assert(file->mmap_base == NULL); /* NFS: if file isn't locked, we're optimistic that we can read enough data without flushing attribute cache. if after reading we notice that we really should have read more, flush the cache and try again. if file is locked, the attribute cache was already flushed when refreshing the log. */ if (file->log->nfs_flush && nfs_flush) { if (!file->locked) nfs_flush_attr_cache_unlocked(file->filepath); else nfs_flush_attr_cache_fd_locked(file->filepath, file->fd); } if (file->buffer != NULL && file->buffer_offset > start_offset) { /* we have to insert missing data to beginning of buffer */ ret = mail_transaction_log_file_insert_read(file, start_offset); if (ret <= 0) return ret; } if (file->buffer == NULL) { file->buffer = buffer_create_dynamic(default_pool, LOG_PREFETCH); file->buffer_offset = start_offset; } if ((ret = mail_transaction_log_file_read_more(file)) <= 0) ; else if (file->log->nfs_flush && !nfs_flush && mail_transaction_log_file_need_nfs_flush(file)) { /* we didn't read enough data. flush and try again. */ return mail_transaction_log_file_read(file, start_offset, TRUE); } else if ((ret = mail_transaction_log_file_sync(file)) <= 0) { i_assert(ret != 0); /* ret=0 happens only with mmap */ } else { i_assert(file->sync_offset >= file->buffer_offset); } buffer_set_used_size(file->buffer, file->sync_offset - file->buffer_offset); return ret; }
static bool message_decode_header(struct message_decoder_context *ctx, struct message_header_line *hdr, struct message_block *output) { size_t value_len; if (hdr->continues) { hdr->use_full_value = TRUE; return FALSE; } T_BEGIN { if (hdr->name_len == 12 && strcasecmp(hdr->name, "Content-Type") == 0) parse_content_type(ctx, hdr); if (hdr->name_len == 25 && strcasecmp(hdr->name, "Content-Transfer-Encoding") == 0) ctx->message_cte = message_decoder_parse_cte(hdr); } T_END; buffer_set_used_size(ctx->buf, 0); message_header_decode_utf8(hdr->full_value, hdr->full_value_len, ctx->buf, ctx->normalizer); value_len = ctx->buf->used; if (ctx->normalizer != NULL) { (void)ctx->normalizer(hdr->name, hdr->name_len, ctx->buf); buffer_append_c(ctx->buf, '\0'); } else { if (!uni_utf8_get_valid_data((const unsigned char *)hdr->name, hdr->name_len, ctx->buf)) buffer_append_c(ctx->buf, '\0'); } ctx->hdr = *hdr; ctx->hdr.full_value = ctx->buf->data; ctx->hdr.full_value_len = value_len; ctx->hdr.value_len = 0; if (ctx->buf->used != value_len) { ctx->hdr.name = CONST_PTR_OFFSET(ctx->buf->data, ctx->hdr.full_value_len); ctx->hdr.name_len = ctx->buf->used - 1 - value_len; } output->hdr = &ctx->hdr; return TRUE; }
void mail_generate_guid_128_hash(const char *guid, guid_128_t guid_128_r) { unsigned char sha1_sum[SHA1_RESULTLEN]; buffer_t buf; if (guid_128_from_string(guid, guid_128_r) < 0) { /* not 128bit hex. use a hash of it instead. */ buffer_create_from_data(&buf, guid_128_r, GUID_128_SIZE); buffer_set_used_size(&buf, 0); sha1_get_digest(guid, strlen(guid), sha1_sum); #if SHA1_RESULTLEN < GUID_128_SIZE # error not possible #endif buffer_append(&buf, sha1_sum + SHA1_RESULTLEN - GUID_128_SIZE, GUID_128_SIZE); } }
static int ssl_refresh_parameters(struct master_service *service) { #define BUF_APPEND_SIZE 1024 const char *path; buffer_t *buf; void *data; ssize_t ret; int fd; if (ioloop_time == 0 || service->ssl_params_last_refresh > ioloop_time - SSL_PARAMS_CHECK_INTERVAL) return 0; service->ssl_params_last_refresh = ioloop_time; path = t_strdup_printf("%s/"SSL_PARAMETERS_PATH, service->set->base_dir); fd = net_connect_unix(path); if (fd == -1) { i_error("connect(%s) failed: %m", path); return -1; } net_set_nonblock(fd, FALSE); buf = buffer_create_dynamic(default_pool, BUF_APPEND_SIZE*2); for (;;) { data = buffer_append_space_unsafe(buf, BUF_APPEND_SIZE); ret = read(fd, data, BUF_APPEND_SIZE); buffer_set_used_size(buf, buf->used - BUF_APPEND_SIZE + (ret < 0 ? 0 : ret)); if (ret <= 0) break; } if (ret < 0) i_error("read(%s) failed: %m", path); else if (ssl_iostream_context_import_params(service->ssl_ctx, buf) < 0) { i_error("Corrupted SSL parameters file in state_dir: " "ssl-parameters.dat - disabling SSL %u", (int)buf->used); ret = -1; } i_close_fd(&fd); buffer_free(&buf); return ret < 0 ? -1 : 0; }
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; }
static void test_fts_icu_translate(void) { const char *translit_id = "Any-Lower"; UTransliterator *translit; buffer_t *dest = buffer_create_dynamic(pool_datastack_create(), 64); const UChar src[] = { 0xbd, 'B', 'C' }; const char *error; unsigned int i; test_begin("fts_icu_translate"); translit = get_translit(translit_id); for (i = N_ELEMENTS(src); i > 0; i--) { buffer_set_used_size(dest, 0); test_assert(fts_icu_translate(dest, src, i, translit, &error) == 0); test_assert(dest->used == i * sizeof(UChar)); } utrans_close(translit); test_end(); }