2 * Sylpheed -- 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 outbuf
= g_string_sized_new(strlen(encoded_str
) * 2);
54 gchar
*decoded_text
= NULL
;
58 eword_begin_p
= strstr(p
, ENCODED_WORD_BEGIN
);
60 g_string_append(outbuf
, p
);
65 while ((quote_p
= strchr(quote_p
, '"')) != NULL
) {
66 if (quote_p
&& quote_p
< eword_begin_p
) {
67 /* Found a quote before the encoded word. */
71 if (quote_p
>= eword_begin_p
)
75 encoding_begin_p
= strchr(eword_begin_p
+ 2, '?');
76 if (!encoding_begin_p
) {
77 g_string_append(outbuf
, p
);
80 text_begin_p
= strchr(encoding_begin_p
+ 1, '?');
82 g_string_append(outbuf
, p
);
85 eword_end_p
= strstr(text_begin_p
+ 1, ENCODED_WORD_END
);
87 g_string_append(outbuf
, p
);
91 if (p
== encoded_str
) {
92 g_string_append_len(outbuf
, p
, eword_begin_p
- p
);
95 /* ignore spaces between encoded words */
98 for (sp
= p
; sp
< eword_begin_p
; sp
++) {
99 if (!g_ascii_isspace(*sp
)) {
101 (outbuf
, p
, eword_begin_p
- p
);
108 len
= MIN(sizeof(charset
) - 1,
109 encoding_begin_p
- (eword_begin_p
+ 2));
110 memcpy(charset
, eword_begin_p
+ 2, len
);
112 encoding
= g_ascii_toupper(*(encoding_begin_p
+ 1));
114 if (encoding
== 'B') {
116 tmp
= g_strndup(text_begin_p
+ 1, eword_end_p
- (text_begin_p
+ 1) + 1);
117 decoded_text
= g_base64_decode(tmp
, &out_len
);
119 } else if (encoding
== 'Q') {
120 decoded_text
= g_malloc
121 (eword_end_p
- (text_begin_p
+ 1) + 1);
122 len
= qp_decode_q_encoding
123 (decoded_text
, text_begin_p
+ 1,
124 eword_end_p
- (text_begin_p
+ 1));
126 g_string_append_len(outbuf
, p
, eword_end_p
+ 2 - p
);
131 /* An encoded word MUST not appear within a quoted string,
132 * so quoting that word after decoding should be safe.
133 * We check there are no quotes just to be sure. If there
134 * are, well, the comma won't pose a problem, probably.
136 if (addr_field
&& strchr(decoded_text
, ',') && !in_quote
&&
137 !strchr(decoded_text
, '"')) {
138 gchar
*tmp
= g_strdup_printf("\"%s\"", decoded_text
);
139 g_free(decoded_text
);
143 /* convert to UTF-8 */
144 conv_str
= conv_codeset_strdup(decoded_text
, charset
, NULL
);
145 if (!conv_str
|| !g_utf8_validate(conv_str
, -1, NULL
)) {
147 conv_str
= g_malloc(len
+ 1);
148 conv_utf8todisp(conv_str
, len
+ 1, decoded_text
);
150 g_string_append(outbuf
, conv_str
);
153 g_free(decoded_text
);
158 out_str
= outbuf
->str
;
159 out_len
= outbuf
->len
;
160 g_string_free(outbuf
, FALSE
);
162 return g_realloc(out_str
, out_len
+ 1);