aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2008-12-26 06:15:53 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2008-12-26 06:15:53 +0000
commit47aac1577bc348326417141ffbcbfd5851757353 (patch)
tree31794bb16d9b28045b30b1100da1c5d069ea283a
parent75ae67fc4779ab0bb1e9d20a0666ad1d44da96bf (diff)
properly process lines longer than 8192 bytes.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2106 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r--ChangeLog5
-rw-r--r--ChangeLog.ja5
-rw-r--r--libsylph/procmime.c119
3 files changed, 102 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 7ee3110e..d2c4dc62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-26
+
+ * libsylph/procmime.c: procmime_decode_content(): properly process
+ lines longer than 8192 bytes.
+
2008-12-19
* version 2.6.0
diff --git a/ChangeLog.ja b/ChangeLog.ja
index cf65496c..3c7897f7 100644
--- a/ChangeLog.ja
+++ b/ChangeLog.ja
@@ -1,3 +1,8 @@
+2008-12-26
+
+ * libsylph/procmime.c: procmime_decode_content(): 8192 バイトを
+ 超える行を正しく処理するようにした。
+
2008-12-19
* version 2.6.0
diff --git a/libsylph/procmime.c b/libsylph/procmime.c
index fbd4e382..c920203c 100644
--- a/libsylph/procmime.c
+++ b/libsylph/procmime.c
@@ -814,6 +814,37 @@ MimeInfo *procmime_scan_mime_header(FILE *fp)
return mimeinfo;
}
+static gint procmime_normalize_lbreak(FILE *infp, FILE *outfp)
+{
+ gchar buf[BUFFSIZE];
+ gint len;
+
+ g_return_val_if_fail(infp != NULL, -1);
+ g_return_val_if_fail(outfp != NULL, -1);
+
+ while (fgets(buf, sizeof(buf), infp) != NULL) {
+ len = strlen(buf);
+ if (len == sizeof(buf) - 1 && buf[len - 1] != '\n') {
+ if (buf[len - 1] == '\r') {
+ ungetc('\r', infp);
+ buf[len - 1] = '\0';
+ }
+ fputs(buf, outfp);
+ continue;
+ }
+#ifdef G_OS_WIN32
+ strretchomp(buf);
+ fputs(buf, outfp);
+ fputs("\r\n", outfp);
+#else
+ strcrchomp(buf);
+ fputs(buf, outfp);
+#endif
+ }
+
+ return 0;
+}
+
FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
{
gchar buf[BUFFSIZE];
@@ -848,6 +879,7 @@ FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
if (mimeinfo->encoding_type == ENC_QUOTED_PRINTABLE) {
FILE *tmpfp = outfp;
+ gchar prev_empty_line[3] = "";
if (normalize_lbreak) {
tmpfp = my_tmpfile();
@@ -862,9 +894,22 @@ FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
(!boundary ||
!IS_BOUNDARY(buf, boundary, boundary_len))) {
gint len;
- len = qp_decode_line(buf);
- fwrite(buf, len, 1, tmpfp);
+
+ if (prev_empty_line[0]) {
+ fputs(prev_empty_line, tmpfp);
+ prev_empty_line[0] = '\0';
+ }
+
+ if (buf[0] == '\n' ||
+ (buf[0] == '\r' && buf[1] == '\n'))
+ strcpy(prev_empty_line, buf);
+ else {
+ len = qp_decode_line(buf);
+ fwrite(buf, len, 1, tmpfp);
+ }
}
+ if (!boundary && prev_empty_line[0])
+ fputs(prev_empty_line, tmpfp);
if (normalize_lbreak) {
if (fflush(tmpfp) == EOF) {
@@ -874,16 +919,7 @@ FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
return NULL;
}
rewind(tmpfp);
- while (fgets(buf, sizeof(buf), tmpfp) != NULL) {
-#ifdef G_OS_WIN32
- strretchomp(buf);
- fputs(buf, outfp);
- fputs("\r\n", outfp);
-#else
- strcrchomp(buf);
- fputs(buf, outfp);
-#endif
- }
+ procmime_normalize_lbreak(tmpfp, outfp);
fclose(tmpfp);
}
} else if (mimeinfo->encoding_type == ENC_BASE64) {
@@ -923,16 +959,7 @@ FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
return NULL;
}
rewind(tmpfp);
- while (fgets(buf, sizeof(buf), tmpfp) != NULL) {
-#ifdef G_OS_WIN32
- strretchomp(buf);
- fputs(buf, outfp);
- fputs("\r\n", outfp);
-#else
- strcrchomp(buf);
- fputs(buf, outfp);
-#endif
- }
+ procmime_normalize_lbreak(tmpfp, outfp);
fclose(tmpfp);
}
} else if (mimeinfo->encoding_type == ENC_X_UUENCODE) {
@@ -957,21 +984,59 @@ FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
flag = TRUE;
}
} else {
+ gchar prev_empty_line[3] = "";
+ gint len;
+ gboolean cont_line = FALSE;
+
while (fgets(buf, sizeof(buf), infp) != NULL &&
(!boundary ||
!IS_BOUNDARY(buf, boundary, boundary_len))) {
+ if (prev_empty_line[0]) {
+ fputs(prev_empty_line, outfp);
+ prev_empty_line[0] = '\0';
+ }
+
+ len = strlen(buf);
+ if (len == sizeof(buf) - 1 &&
+ buf[len - 1] != '\n') {
+ if (buf[len - 1] == '\r') {
+ ungetc('\r', infp);
+ buf[len - 1] = '\0';
+ }
+ fputs(buf, outfp);
+ cont_line = TRUE;
+ continue;
+ }
+
if (normalize_lbreak) {
#ifdef G_OS_WIN32
strretchomp(buf);
- fputs(buf, outfp);
- fputs("\r\n", outfp);
+ if (!cont_line && buf[0] == '\0')
+ strcpy(prev_empty_line, "\r\n");
+ else {
+ fputs(buf, outfp);
+ fputs("\r\n", outfp);
+ }
#else
strcrchomp(buf);
- fputs(buf, outfp);
+ if (!cont_line && buf[0] == '\n')
+ strcpy(prev_empty_line, "\n");
+ else
+ fputs(buf, outfp);
#endif
- } else
- fputs(buf, outfp);
+ } else {
+ if (!cont_line &&
+ (buf[0] == '\n' ||
+ (buf[0] == '\r' && buf[1] == '\n')))
+ strcpy(prev_empty_line, buf);
+ else
+ fputs(buf, outfp);
+ }
+
+ cont_line = FALSE;
}
+ if (!boundary && prev_empty_line[0])
+ fputs(prev_empty_line, outfp);
}
if (fflush(outfp) == EOF)