message-header-decode.c revision af6c7862e6160ffaecec458f4cec43b94272ad57
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmessage_header_decode_encoded(const unsigned char *data, size_t size,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen buffer_t *decodebuf, unsigned int *charsetlen_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int num = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* data should contain "charset?encoding?text?=" */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (i = 0; i < size; i++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* invalid block */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen quoted_printable_decode(data + start_pos[1] + 1,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* contains invalid data. show what we got so far. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* unknown encoding */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid message_header_decode(const unsigned char *data, size_t size,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int charsetlen = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* =?charset?Q|B?text?= */
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen /* encoded string beginning */
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen /* send the unencoded data so far */
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen if (!callback(data + start_pos, pos - start_pos,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen decodebuf = buffer_create_dynamic(default_pool,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = message_header_decode_encoded(data + pos, size - pos,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* decodebuf contains <charset> NUL <text> */
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen if (!callback(CONST_PTR_OFFSET(decodebuf->data,
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen (void)callback(data + start_pos, size - start_pos,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainendecode_utf8_callback(const unsigned char *data, size_t size,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* one call with charset=NULL means nothing changed */
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen if (charset == NULL || charset_is_utf8(charset)) {
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen /* ASCII / UTF-8 */
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen (void)uni_utf8_to_decomposed_titlecase(data, size,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen flags = ctx->dtcase ? CHARSET_FLAG_DECOMP_TITLECASE : 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (charset_to_utf8_begin(charset, flags, &t) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* data probably still contains some valid ASCII characters.
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen append them. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (uni_utf8_get_valid_data(data, size, ctx->dest))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* ignore any errors */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (void)charset_to_utf8(t, data, &size, ctx->dest);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenbool message_header_decode_utf8(const unsigned char *data, size_t size,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen message_header_decode(data, size, decode_utf8_callback, &ctx);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return ctx.changed || (dest->used - used != size);