static void test_imap_bodystructure_parse(void) { struct message_part *parts; const char *error; string_t *str = t_str_new(128); pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024); test_begin("imap bodystructure parser"); parts = msg_parse(pool, FALSE); test_assert(imap_body_parse_from_bodystructure(testmsg_bodystructure, str, &error) == 0); test_assert(strcmp(str_c(str), testmsg_body) == 0); test_assert(imap_bodystructure_parse(testmsg_bodystructure, pool, parts, &error) == 0); str_truncate(str, 0); imap_bodystructure_write(parts, str, TRUE); test_assert(strcmp(str_c(str), testmsg_bodystructure) == 0); pool_unref(&pool); test_end(); }
int index_mail_get_special(struct mail *_mail, enum mail_fetch_field field, const char **value_r) { struct index_mail *mail = (struct index_mail *)_mail; struct index_mail_data *data = &mail->data; struct mail_cache_field *cache_fields = mail->ibox->cache_fields; string_t *str; switch (field) { case MAIL_FETCH_IMAP_BODY: { unsigned int body_cache_field = cache_fields[MAIL_CACHE_IMAP_BODY].idx; unsigned int bodystructure_cache_field = cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx; if (data->body != NULL) { *value_r = data->body; return 0; } /* 1) use plain-7bit-ascii flag if it exists 2) get BODY if it exists 3) get it using BODYSTRUCTURE if it exists 4) parse body structure, and save BODY/BODYSTRUCTURE depending on what we want cached */ str = str_new(mail->data_pool, 128); if ((mail->data.cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 && get_cached_parts(mail)) { index_mail_get_plain_bodystructure(mail, str, FALSE); data->body = str_c(str); } else if (index_mail_cache_lookup_field(mail, str, body_cache_field) > 0) data->body = str_c(str); else if (index_mail_cache_lookup_field(mail, str, bodystructure_cache_field) > 0) { data->bodystructure = p_strdup(mail->data_pool, str_c(str)); str_truncate(str, 0); if (imap_body_parse_from_bodystructure( data->bodystructure, str)) data->body = str_c(str); else { /* broken, continue.. */ mail_set_cache_corrupted(_mail, MAIL_FETCH_IMAP_BODYSTRUCTURE); } } if (data->body == NULL) { str_free(&str); if (index_mail_parse_bodystructure(mail, MAIL_CACHE_IMAP_BODY) < 0) return -1; } i_assert(data->body != NULL); *value_r = data->body; return 0; } case MAIL_FETCH_IMAP_BODYSTRUCTURE: { unsigned int bodystructure_cache_field = cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx; if (data->bodystructure != NULL) { *value_r = data->bodystructure; return 0; } str = str_new(mail->data_pool, 128); if ((mail->data.cache_flags & MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII) != 0 && get_cached_parts(mail)) { index_mail_get_plain_bodystructure(mail, str, TRUE); data->bodystructure = str_c(str); } else if (index_mail_cache_lookup_field(mail, str, bodystructure_cache_field) > 0) { data->bodystructure = str_c(str); } else { str_free(&str); if (index_mail_parse_bodystructure(mail, MAIL_CACHE_IMAP_BODYSTRUCTURE) < 0) return -1; } i_assert(data->bodystructure != NULL); *value_r = data->bodystructure; return 0; } case MAIL_FETCH_IMAP_ENVELOPE: if (data->envelope == NULL) { if (index_mail_headers_get_envelope(mail) < 0) return -1; } *value_r = data->envelope; return 0; case MAIL_FETCH_FROM_ENVELOPE: case MAIL_FETCH_UIDL_FILE_NAME: case MAIL_FETCH_UIDL_BACKEND: case MAIL_FETCH_SEARCH_SCORE: case MAIL_FETCH_GUID: case MAIL_FETCH_HEADER_MD5: *value_r = ""; return 0; case MAIL_FETCH_MAILBOX_NAME: *value_r = _mail->box->vname; return 0; default: i_unreached(); return -1; } }