message-header-decode.c revision 345253fb28498b2e0a60f4a2a8644c65feee7e75
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen/* Copyright (C) 2002-2007 Timo Sirainen */
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainenmessage_header_decode_encoded(const unsigned char *data, size_t size,
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen buffer_t *decodebuf, unsigned int *charsetlen_r)
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen unsigned int num = 0;
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* data should contain "charset?encoding?text?=" */
797de45dcf6e24642ab347d5033beb92034b779dTimo Sirainen for (i = 0; i < size; i++) {
dac0b2e5e0f38c6d95ef1a842d891480db580236Timo Sirainen /* invalid block */
717a444a466280a84a468220f647fdcb9f3b546fTimo Sirainen quoted_printable_decode(data + start_pos[1] + 1,
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* contains invalid data. show what we got so far. */
720692523ece4a549f7c589508d5693ee310f6b3Timo Sirainen /* unknown encoding */
08f24237ccc177f5b3a09b24d8a725fa47e1ee32Timo Sirainenvoid message_header_decode(const unsigned char *data, size_t size,
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen unsigned int charsetlen = 0;
8d59f06c9422fa49b538e23ffb06eddb23c6add2Timo Sirainen /* =?charset?Q|B?text?= */
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* encoded string beginning */
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* send the unencoded data so far */
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen if (!callback(data + start_pos, pos - start_pos,
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen buffer_create_dynamic(pool_datastack_create(),
08f24237ccc177f5b3a09b24d8a725fa47e1ee32Timo Sirainen pos += message_header_decode_encoded(data + pos, size - pos,
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* decodebuf contains <charset> NUL <text> */
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen if (!callback(CONST_PTR_OFFSET(decodebuf->data,
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen (void)callback(data + start_pos, size - start_pos,
193f5296d2a6b847970c222d8a261b89aae46331Timo Sirainendecode_utf8_callback(const unsigned char *data, size_t size,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen /* one call with charset=NULL means nothing changed */
745f2c7424d88e368eff0a3a7650b352a9d1f0ddTimo Sirainen if (charset == NULL || charset_is_utf8(charset)) {
745f2c7424d88e368eff0a3a7650b352a9d1f0ddTimo Sirainen /* ASCII / UTF-8 */
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen (void)uni_utf8_to_decomposed_titlecase(data, size,
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen if (charset_to_utf8_begin(charset, ctx->dtcase, &t) < 0) {
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen /* let's just ignore this part */
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen /* ignore any errors */
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen (void)charset_to_utf8(t, data, &size, ctx->dest);
797de45dcf6e24642ab347d5033beb92034b779dTimo Sirainenbool message_header_decode_utf8(const unsigned char *data, size_t size,
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen message_header_decode(data, size, decode_utf8_callback, &ctx);
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen return ctx.changed || (dest->used - used != size);