2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "claws-features.h"
31 #include "quoted-printable.h"
33 #define ENCODED_WORD_BEGIN "=?"
34 #define ENCODED_WORD_END "?="
36 /* Decodes headers based on RFC2045 and RFC2047. */
38 gchar
*unmime_header(const gchar
*encoded_str
, gboolean addr_field
)
40 const gchar
*p
= encoded_str
;
41 const gchar
*eword_begin_p
, *encoding_begin_p
, *text_begin_p
,
51 cm_return_val_if_fail(encoded_str
!= NULL
, NULL
);
53 outbuf
= g_string_sized_new(strlen(encoded_str
) * 2);
56 gchar
*decoded_text
= NULL
;
60 eword_begin_p
= strstr(p
, ENCODED_WORD_BEGIN
);
62 g_string_append(outbuf
, p
);
67 while ((quote_p
= strchr(quote_p
, '"')) != NULL
) {
68 if (quote_p
&& quote_p
< eword_begin_p
) {
69 /* Found a quote before the encoded word. */
73 if (quote_p
>= eword_begin_p
)
77 encoding_begin_p
= strchr(eword_begin_p
+ 2, '?');
78 if (!encoding_begin_p
) {
79 g_string_append(outbuf
, p
);
82 text_begin_p
= strchr(encoding_begin_p
+ 1, '?');
84 g_string_append(outbuf
, p
);
87 eword_end_p
= strstr(text_begin_p
+ 1, ENCODED_WORD_END
);
89 g_string_append(outbuf
, p
);
93 if (p
== encoded_str
) {
94 g_string_append_len(outbuf
, p
, eword_begin_p
- p
);
97 /* ignore spaces between encoded words */
100 for (sp
= p
; sp
< eword_begin_p
; sp
++) {
101 if (!g_ascii_isspace(*sp
)) {
103 (outbuf
, p
, eword_begin_p
- p
);
110 len
= MIN(sizeof(charset
) - 1,
111 encoding_begin_p
- (eword_begin_p
+ 2));
112 memcpy(charset
, eword_begin_p
+ 2, len
);
114 encoding
= g_ascii_toupper(*(encoding_begin_p
+ 1));
116 if (encoding
== 'B') {
118 tmp
= g_strndup(text_begin_p
+ 1, eword_end_p
- (text_begin_p
+ 1) + 1);
119 decoded_text
= g_base64_decode(tmp
, &out_len
);
121 } else if (encoding
== 'Q') {
122 decoded_text
= g_malloc
123 (eword_end_p
- (text_begin_p
+ 1) + 1);
124 len
= qp_decode_q_encoding
125 (decoded_text
, text_begin_p
+ 1,
126 eword_end_p
- (text_begin_p
+ 1));
128 g_string_append_len(outbuf
, p
, eword_end_p
+ 2 - p
);
133 /* An encoded word MUST not appear within a quoted string,
134 * so quoting that word after decoding should be safe.
135 * We check there are no quotes just to be sure. If there
136 * are, well, the comma won't pose a problem, probably.
138 if (addr_field
&& strchr(decoded_text
, ',') && !in_quote
&&
139 !strchr(decoded_text
, '"')) {
140 gchar
*tmp
= g_strdup_printf("\"%s\"", decoded_text
);
141 g_free(decoded_text
);
145 /* convert to UTF-8 */
146 conv_str
= conv_codeset_strdup(decoded_text
, charset
, NULL
);
147 if (!conv_str
|| !g_utf8_validate(conv_str
, -1, NULL
)) {
149 conv_str
= g_malloc(len
+ 1);
150 conv_utf8todisp(conv_str
, len
+ 1, decoded_text
);
152 g_string_append(outbuf
, conv_str
);
155 g_free(decoded_text
);
160 out_str
= outbuf
->str
;
161 out_len
= outbuf
->len
;
162 g_string_free(outbuf
, FALSE
);
164 return g_realloc(out_str
, out_len
+ 1);