diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | ChangeLog.ja | 9 | ||||
-rw-r--r-- | src/imap.c | 32 | ||||
-rw-r--r-- | src/socket.c | 53 | ||||
-rw-r--r-- | src/socket.h | 6 | ||||
-rw-r--r-- | src/utils.c | 11 | ||||
-rw-r--r-- | src/utils.h | 3 |
7 files changed, 86 insertions, 38 deletions
@@ -1,5 +1,15 @@ 2005-06-20 + * src/imap.c: replace embedded null characters with ' ' when parsing + block data (fix parse errors when embedded null characters appeared + in headers). + * src/socket.[ch]: modified *_getline() so that it returns the length + of string including embedded null characters. + * src/utils.[ch]: subst_null(): replaces null characters with + specified one. + +2005-06-20 + * src/textview.c: added "Add to address book" to the context menu (thanks to Tomohiro Masubuchi), and changed "Copy this link" to "Copy this address" when address is clicked. diff --git a/ChangeLog.ja b/ChangeLog.ja index e1f4bbb1..9904765f 100644 --- a/ChangeLog.ja +++ b/ChangeLog.ja @@ -1,5 +1,14 @@ 2005-06-20 + * src/imap.c: ブロックデータをパースするときに埋め込まれた null 文字 + を ' ' で置換するようにした(ヘッダに埋め込まれた null 文字が出現 + した場合にパースエラーが起こるのを修正)。 + * src/socket.[ch]: *_getline() を、埋め込まれた null 文字を含んだ + 文字列長を返すように修正。 + * src/utils.[ch]: subst_null(): null 文字を指定した文字で置換。 + +2005-06-20 + * src/textview.c: コンテキストメニューに「アドレス帳に追加」を追加し (増渕さん thanks)、アドレスをクリックした場合は「リンクをコピー」を 「アドレスをコピー」に変更。 @@ -2200,7 +2200,7 @@ static GSList *imap_get_uncached_messages(IMAPSession *session, str = g_string_new(NULL); for (;;) { - if ((tmp = sock_getline(SESSION(session)->sock)) == NULL) { + if (sock_getline(SESSION(session)->sock, &tmp) < 0) { log_warning(_("error occurred while getting envelope.\n")); g_string_free(str, TRUE); return newlist; @@ -2548,7 +2548,7 @@ static gchar *imap_parse_atom(IMAPSession *session, gchar *src, /* read the next line if the current response buffer is empty */ while (isspace(*(guchar *)cur_pos)) cur_pos++; while (*cur_pos == '\0') { - if ((nextline = sock_getline(SESSION(session)->sock)) == NULL) + if (sock_getline(SESSION(session)->sock, &nextline) < 0) return cur_pos; g_string_assign(str, nextline); cur_pos = str->str; @@ -2571,7 +2571,7 @@ static gchar *imap_parse_atom(IMAPSession *session, gchar *src, } else if (*cur_pos == '{') { gchar buf[32]; gint len; - gint line_len = 0; + gint block_len = 0; cur_pos = strchr_cpy(cur_pos + 1, '}', buf, sizeof(buf)); len = atoi(buf); @@ -2581,17 +2581,21 @@ static gchar *imap_parse_atom(IMAPSession *session, gchar *src, cur_pos = str->str; do { - if ((nextline = sock_getline(SESSION(session)->sock)) - == NULL) + gint cur_len; + + cur_len = sock_getline(SESSION(session)->sock, + &nextline); + if (cur_len < 0) return cur_pos; - line_len += strlen(nextline); + block_len += cur_len; + subst_null(nextline, cur_len, ' '); g_string_append(str, nextline); cur_pos = str->str; strretchomp(nextline); /* log_print("IMAP4< %s\n", nextline); */ debug_print("IMAP4< %s\n", nextline); g_free(nextline); - } while (line_len < len); + } while (block_len < len); memcpy(dest, cur_pos, MIN(len, dest_len - 1)); dest[MIN(len, dest_len - 1)] = '\0'; @@ -2625,12 +2629,16 @@ static gchar *imap_get_header(IMAPSession *session, gchar *cur_pos, cur_pos = str->str; do { - if ((nextline = sock_getline(SESSION(session)->sock)) == NULL) + gint cur_len; + + cur_len = sock_getline(SESSION(session)->sock, &nextline); + if (cur_len < 0) return cur_pos; - block_len += strlen(nextline); + block_len += cur_len; + subst_null(nextline, cur_len, ' '); g_string_append(str, nextline); cur_pos = str->str; - strretchomp(nextline); + /* strretchomp(nextline); */ /* debug_print("IMAP4< %s\n", nextline); */ g_free(nextline); } while (block_len < len); @@ -2642,7 +2650,7 @@ static gchar *imap_get_header(IMAPSession *session, gchar *cur_pos, while (isspace(*(guchar *)cur_pos)) cur_pos++; while (*cur_pos == '\0') { - if ((nextline = sock_getline(SESSION(session)->sock)) == NULL) + if (sock_getline(SESSION(session)->sock, &nextline) < 0) return cur_pos; g_string_assign(str, nextline); cur_pos = str->str; @@ -3648,7 +3656,7 @@ static void imap_cmd_gen_send(IMAPSession *session, const gchar *format, ...) static gint imap_cmd_gen_recv(IMAPSession *session, gchar **ret) { - if ((*ret = sock_getline(SESSION(session)->sock)) == NULL) + if (sock_getline(SESSION(session)->sock, ret) < 0) return IMAP_SOCKET; strretchomp(*ret); diff --git a/src/socket.c b/src/socket.c index 8d2023fc..c9ff5605 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2004 Hiroyuki Yamamoto + * Copyright (C) 1999-2005 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1168,61 +1168,68 @@ gint sock_gets(SockInfo *sock, gchar *buf, gint len) return fd_gets(sock->sock, buf, len); } -gchar *fd_getline(gint fd) +gint fd_getline(gint fd, gchar **line) { gchar buf[BUFFSIZE]; gchar *str = NULL; gint len; - gulong size = 1; + gulong size = 0; + gulong cur_offset = 0; while ((len = fd_gets(fd, buf, sizeof(buf))) > 0) { size += len; - if (!str) - str = g_strdup(buf); - else { - str = g_realloc(str, size); - strcat(str, buf); - } + str = g_realloc(str, size + 1); + memcpy(str + cur_offset, buf, len + 1); + cur_offset += len; if (buf[len - 1] == '\n') break; } - return str; + *line = str; + + if (!str) + return -1; + else + return (gint)size; } #if USE_SSL -gchar *ssl_getline(SSL *ssl) +gint ssl_getline(SSL *ssl, gchar **line) { gchar buf[BUFFSIZE]; gchar *str = NULL; gint len; - gulong size = 1; + gulong size = 0; + gulong cur_offset = 0; while ((len = ssl_gets(ssl, buf, sizeof(buf))) > 0) { size += len; - if (!str) - str = g_strdup(buf); - else { - str = g_realloc(str, size); - strcat(str, buf); - } + str = g_realloc(str, size + 1); + memcpy(str + cur_offset, buf, len + 1); + cur_offset += len; if (buf[len - 1] == '\n') break; } - return str; + *line = str; + + if (!str) + return -1; + else + return (gint)size; } #endif -gchar *sock_getline(SockInfo *sock) +gint sock_getline(SockInfo *sock, gchar **line) { - g_return_val_if_fail(sock != NULL, NULL); + g_return_val_if_fail(sock != NULL, -1); + g_return_val_if_fail(line != NULL, -1); #if USE_SSL if (sock->ssl) - return ssl_getline(sock->ssl); + return ssl_getline(sock->ssl, line); #endif - return fd_getline(sock->sock); + return fd_getline(sock->sock, line); } gint sock_puts(SockInfo *sock, const gchar *buf) diff --git a/src/socket.h b/src/socket.h index 05c43b89..35447cbe 100644 --- a/src/socket.h +++ b/src/socket.h @@ -87,7 +87,7 @@ gint sock_read (SockInfo *sock, gchar *buf, gint len); gint sock_write (SockInfo *sock, const gchar *buf, gint len); gint sock_write_all (SockInfo *sock, const gchar *buf, gint len); gint sock_gets (SockInfo *sock, gchar *buf, gint len); -gchar *sock_getline (SockInfo *sock); +gint sock_getline (SockInfo *sock, gchar **line); gint sock_puts (SockInfo *sock, const gchar *buf); gint sock_peek (SockInfo *sock, gchar *buf, gint len); gint sock_close (SockInfo *sock); @@ -101,7 +101,7 @@ gint fd_read (gint sock, gchar *buf, gint len); gint fd_write (gint sock, const gchar *buf, gint len); gint fd_write_all (gint sock, const gchar *buf, gint len); gint fd_gets (gint sock, gchar *buf, gint len); -gchar *fd_getline (gint sock); +gint fd_getline (gint sock, gchar **line); gint fd_close (gint sock); /* Functions for SSL */ @@ -110,7 +110,7 @@ gint ssl_read (SSL *ssl, gchar *buf, gint len); gint ssl_write (SSL *ssl, const gchar *buf, gint len); gint ssl_write_all (SSL *ssl, const gchar *buf, gint len); gint ssl_gets (SSL *ssl, gchar *buf, gint len); -gchar *ssl_getline (SSL *ssl); +gint ssl_getline (SSL *ssl, gchar **line); gint ssl_peek (SSL *ssl, gchar *buf, gint len); #endif diff --git a/src/utils.c b/src/utils.c index 901ec67c..1638bba9 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1048,6 +1048,17 @@ void subst_chars(gchar *str, gchar *orig, gchar subst) } } +void subst_null(gchar *str, gint len, gchar subst) +{ + register gchar *p = str; + + while (len--) { + if (*p == '\0') + *p = subst; + p++; + } +} + void subst_for_filename(gchar *str) { subst_chars(str, " \t\r\n\"'/\\", '_'); diff --git a/src/utils.h b/src/utils.h index 79273d90..1b7c4391 100644 --- a/src/utils.h +++ b/src/utils.h @@ -292,6 +292,9 @@ void subst_char (gchar *str, void subst_chars (gchar *str, gchar *orig, gchar subst); +void subst_null (gchar *str, + gint len, + gchar subst); void subst_for_filename (gchar *str); gboolean is_header_line (const gchar *str); gboolean is_ascii_str (const guchar *str); |