diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-03-04 11:41:49 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-03-04 11:41:49 +0000 |
commit | 00147be89513db41cdefb984b9d8e5e02e3f8ce6 (patch) | |
tree | 1066745852a3bc4db092442c5892994d798cb715 | |
parent | c713812fef1340829e2142e177f0a60f2e9471b8 (diff) |
improved header MIME decoding.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@147 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | ChangeLog.ja | 7 | ||||
-rw-r--r-- | src/codeconv.c | 29 | ||||
-rw-r--r-- | src/unmime.c | 63 | ||||
-rw-r--r-- | src/unmime.h | 3 |
5 files changed, 57 insertions, 52 deletions
@@ -1,5 +1,12 @@ 2005-03-04 + * src/unmime.[ch]: use GString for a buffer for header MIME decoding + to improve the efficiency. + * src/codeconv.c: conv_unmime_header(): directly return the return + value of unmime_header(). Restrict the buffer size on the stack. + +2005-03-04 + * src/codeconv.[ch]: removed conv_unmime_header_overwrite() because it had introduced heap buffer overflow. conv_unmime_header(): modified so that it returns newly-allocated diff --git a/ChangeLog.ja b/ChangeLog.ja index 5eb1ac9d..99253fd7 100644 --- a/ChangeLog.ja +++ b/ChangeLog.ja @@ -1,5 +1,12 @@ 2005-03-04 + * src/unmime.[ch]: 効率を上げるために、ヘッダの MIME デコードの + バッファとして GString を使用するようにした。 + * src/codeconv.c: conv_unmime_header(): unmime_header() の戻り値を + 直接返すようにした。スタックに置くバッファサイズを制限。 + +2005-03-04 + * src/codeconv.[ch]: ヒープのバッファオーバーフローを起こしていた conv_unmime_header_overwrite() を削除。 conv_unmime_header(): 新たに確保された文字列を返すように修正。 diff --git a/src/codeconv.c b/src/codeconv.c index 0d494919..8371486d 100644 --- a/src/codeconv.c +++ b/src/codeconv.c @@ -1543,31 +1543,25 @@ const gchar *conv_get_current_locale(void) gchar *conv_unmime_header(const gchar *str, const gchar *default_encoding) { - gchar *buf; - gint buflen; gchar *utf8_buf; + gint buflen; - if (is_ascii_str(str)) { - buflen = strlen(str) * 6 + 1; - Xalloca(buf, buflen, return NULL); - unmime_header(buf, str); - return g_strdup(buf); - } + if (is_ascii_str(str)) + return unmime_header(str); if (default_encoding) { utf8_buf = conv_codeset_strdup (str, default_encoding, CS_INTERNAL); if (utf8_buf) { - buflen = strlen(utf8_buf) * 6 + 1; - Xalloca(buf, buflen, - { g_free(utf8_buf); return NULL; }); - unmime_header(buf, utf8_buf); + gchar *decoded_str; + + decoded_str = unmime_header(utf8_buf); g_free(utf8_buf); - return g_strdup(buf); + return decoded_str; } } - buflen = strlen(str) * 6 + 1; + buflen = MIN(strlen(str) * 6 + 1, BUFFSIZE); Xalloca(utf8_buf, buflen, return NULL); if (conv_get_locale_charset() == C_EUC_JP) @@ -1575,12 +1569,7 @@ gchar *conv_unmime_header(const gchar *str, const gchar *default_encoding) else conv_localetodisp(utf8_buf, buflen, str); - buflen = strlen(utf8_buf) * 6 + 1; - Xalloca(buf, buflen, return NULL); - - unmime_header(buf, utf8_buf); - - return g_strdup(buf); + return unmime_header(utf8_buf); } #define MAX_LINELEN 76 diff --git a/src/unmime.c b/src/unmime.c index e4742afd..1365c3ce 100644 --- a/src/unmime.c +++ b/src/unmime.c @@ -34,53 +34,56 @@ /* Decodes headers based on RFC2045 and RFC2047. */ -void unmime_header(gchar *out, const gchar *str) +gchar *unmime_header(const gchar *encoded_str) { - const gchar *p = str; - gchar *outp = out; + const gchar *p = encoded_str; const gchar *eword_begin_p, *encoding_begin_p, *text_begin_p, *eword_end_p; gchar charset[32]; gchar encoding; gchar *conv_str; - gint len; + GString *outbuf; + gchar *out_str; + gsize out_len; + + outbuf = g_string_sized_new(strlen(encoded_str) * 2); while (*p != '\0') { gchar *decoded_text = NULL; + gint len; eword_begin_p = strstr(p, ENCODED_WORD_BEGIN); if (!eword_begin_p) { - strcpy(outp, p); - return; + g_string_append(outbuf, p); + break; } encoding_begin_p = strchr(eword_begin_p + 2, '?'); if (!encoding_begin_p) { - strcpy(outp, p); - return; + g_string_append(outbuf, p); + break; } text_begin_p = strchr(encoding_begin_p + 1, '?'); if (!text_begin_p) { - strcpy(outp, p); - return; + g_string_append(outbuf, p); + break; } eword_end_p = strstr(text_begin_p + 1, ENCODED_WORD_END); if (!eword_end_p) { - strcpy(outp, p); - return; + g_string_append(outbuf, p); + break; } - if (p == str) { - memcpy(outp, p, eword_begin_p - p); - outp += eword_begin_p - p; + if (p == encoded_str) { + g_string_append_len(outbuf, p, eword_begin_p - p); p = eword_begin_p; } else { /* ignore spaces between encoded words */ const gchar *sp; for (sp = p; sp < eword_begin_p; sp++) { - if (!isspace(*(const guchar *)sp)) { - memcpy(outp, p, eword_begin_p - p); - outp += eword_begin_p - p; + if (!g_ascii_isspace(*sp)) { + g_string_append_len + (outbuf, p, eword_begin_p - p); p = eword_begin_p; break; } @@ -91,7 +94,7 @@ void unmime_header(gchar *out, const gchar *str) encoding_begin_p - (eword_begin_p + 2)); memcpy(charset, eword_begin_p + 2, len); charset[len] = '\0'; - encoding = toupper(*(encoding_begin_p + 1)); + encoding = g_ascii_toupper(*(encoding_begin_p + 1)); if (encoding == 'B') { decoded_text = g_malloc @@ -106,28 +109,28 @@ void unmime_header(gchar *out, const gchar *str) (decoded_text, text_begin_p + 1, eword_end_p - (text_begin_p + 1)); } else { - memcpy(outp, p, eword_end_p + 2 - p); - outp += eword_end_p + 2 - p; + g_string_append_len(outbuf, p, eword_end_p + 2 - p); p = eword_end_p + 2; continue; } /* convert to UTF-8 */ conv_str = conv_codeset_strdup(decoded_text, charset, NULL); - if (conv_str) { - len = strlen(conv_str); - memcpy(outp, conv_str, len); - g_free(conv_str); - } else { - len = strlen(decoded_text); - conv_utf8todisp(outp, len + 1, decoded_text); + if (!conv_str) { + conv_str = g_malloc(len + 1); + conv_utf8todisp(conv_str, len + 1, decoded_text); } - outp += len; + g_string_append(outbuf, conv_str); + g_free(conv_str); g_free(decoded_text); p = eword_end_p + 2; } - *outp = '\0'; + out_str = outbuf->str; + out_len = outbuf->len; + g_string_free(outbuf, FALSE); + + return g_realloc(out_str, out_len + 1); } diff --git a/src/unmime.h b/src/unmime.h index 363dd219..be9f390e 100644 --- a/src/unmime.h +++ b/src/unmime.h @@ -22,7 +22,6 @@ #include <glib.h> -void unmime_header (gchar *out, - const gchar *str); +gchar *unmime_header (const gchar *encoded_str); #endif /* __UNMIME_H__ */ |