aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--ChangeLog.ja9
-rw-r--r--src/imap.c32
-rw-r--r--src/socket.c53
-rw-r--r--src/socket.h6
-rw-r--r--src/utils.c11
-rw-r--r--src/utils.h3
7 files changed, 86 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index 61e5c75a..e2fa82f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)、アドレスをクリックした場合は「リンクをコピー」を
「アドレスをコピー」に変更。
diff --git a/src/imap.c b/src/imap.c
index 15ecc75c..423c40b0 100644
--- a/src/imap.c
+++ b/src/imap.c
@@ -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);