Commit 72a5595a 72a5595aa569f4036a15a0e0c8e9366e8b7c8e9d by Sergey Poznyakoff

Bugfix.

* pop3d/retr.c (pop3d_retr): Use constant-size buffer.  This
avoids running out of memory on messages that do not contain
trailing newline.
* pop3d/top.c (pop3d_top): Likewise.
1 parent 2fa93e70
1 2008-08-04 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * pop3d/retr.c (pop3d_retr): Use constant-size buffer. This
4 avoids running out of memory on messages that do not contain
5 trailing newline.
6 * pop3d/top.c (pop3d_top): Likewise.
7
1 2008-07-31 Sergey Poznyakoff <gray@gnu.org.ua> 8 2008-07-31 Sergey Poznyakoff <gray@gnu.org.ua>
2 9
3 * libproto/include/amd.h: Fix indentation. 10 * libproto/include/amd.h: Fix indentation.
......
...@@ -24,13 +24,13 @@ int ...@@ -24,13 +24,13 @@ int
24 pop3d_retr (const char *arg) 24 pop3d_retr (const char *arg)
25 { 25 {
26 size_t mesgno, n; 26 size_t mesgno, n;
27 char *buf; 27 char buf[BUFFERSIZE];
28 size_t buflen = BUFFERSIZE;
29 mu_message_t msg = NULL; 28 mu_message_t msg = NULL;
30 mu_attribute_t attr = NULL; 29 mu_attribute_t attr = NULL;
31 mu_stream_t stream = NULL; 30 mu_stream_t stream = NULL;
32 off_t off; 31 mu_off_t off;
33 32 int prev_nl;
33
34 if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL)) 34 if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL))
35 return ERR_BAD_ARGS; 35 return ERR_BAD_ARGS;
36 36
...@@ -50,37 +50,36 @@ pop3d_retr (const char *arg) ...@@ -50,37 +50,36 @@ pop3d_retr (const char *arg)
50 pop3d_outf ("+OK\r\n"); 50 pop3d_outf ("+OK\r\n");
51 51
52 off = n = 0; 52 off = n = 0;
53 buf = malloc (buflen * sizeof (*buf));
54 if (buf == NULL)
55 pop3d_abquit (ERR_NO_MEM);
56 53
57 while (mu_stream_readline (stream, buf, buflen, off, &n) == 0 54 prev_nl = 1;
55 while (mu_stream_readline (stream, buf, sizeof(buf), off, &n) == 0
58 && n > 0) 56 && n > 0)
59 { 57 {
60 /* Nuke the trailing newline. */ 58 if (prev_nl && buf[0] == '.')
59 pop3d_outf (".");
60
61 if (buf[n - 1] == '\n') 61 if (buf[n - 1] == '\n')
62 buf[n - 1] = '\0';
63 else /* Make room for the line. */
64 { 62 {
65 buflen *= 2; 63 buf[n - 1] = '\0';
66 buf = realloc (buf, buflen * sizeof (*buf)); 64 pop3d_outf ("%s\r\n", buf);
67 if (buf == NULL) 65 prev_nl = 1;
68 pop3d_abquit (ERR_NO_MEM);
69 continue;
70 } 66 }
71 if (buf[0] == '.')
72 pop3d_outf (".%s\r\n", buf);
73 else 67 else
74 pop3d_outf ("%s\r\n", buf); 68 {
69 pop3d_outf ("%s", buf);
70 prev_nl = 0;
71 }
75 off += n; 72 off += n;
76 } 73 }
77 74
75 if (!prev_nl)
76 pop3d_outf ("\r\n");
77
78 if (!mu_attribute_is_read (attr)) 78 if (!mu_attribute_is_read (attr))
79 mu_attribute_set_read (attr); 79 mu_attribute_set_read (attr);
80 80
81 pop3d_mark_retr (attr); 81 pop3d_mark_retr (attr);
82 82
83 free (buf);
84 pop3d_outf (".\r\n"); 83 pop3d_outf (".\r\n");
85 84
86 return OK; 85 return OK;
......
...@@ -31,8 +31,7 @@ pop3d_top (const char *arg) ...@@ -31,8 +31,7 @@ pop3d_top (const char *arg)
31 mu_body_t body; 31 mu_body_t body;
32 mu_stream_t stream; 32 mu_stream_t stream;
33 char *mesgc, *linesc; 33 char *mesgc, *linesc;
34 char *buf; 34 char buf[BUFFERSIZE];
35 size_t buflen = BUFFERSIZE;
36 size_t n; 35 size_t n;
37 off_t off; 36 off_t off;
38 37
...@@ -65,11 +64,8 @@ pop3d_top (const char *arg) ...@@ -65,11 +64,8 @@ pop3d_top (const char *arg)
65 /* Header. */ 64 /* Header. */
66 mu_message_get_header (msg, &hdr); 65 mu_message_get_header (msg, &hdr);
67 mu_header_get_stream (hdr, &stream); 66 mu_header_get_stream (hdr, &stream);
68 buf = malloc (buflen * sizeof (*buf));
69 if (buf == NULL)
70 pop3d_abquit (ERR_NO_MEM);
71 off = n = 0; 67 off = n = 0;
72 while (mu_stream_readline (stream, buf, buflen, off, &n) == 0 68 while (mu_stream_readline (stream, buf, sizeof(buf), off, &n) == 0
73 && n > 0) 69 && n > 0)
74 { 70 {
75 /* Nuke the trainline newline. */ 71 /* Nuke the trainline newline. */
...@@ -86,33 +82,35 @@ pop3d_top (const char *arg) ...@@ -86,33 +82,35 @@ pop3d_top (const char *arg)
86 /* Lines of body. */ 82 /* Lines of body. */
87 if (lines) 83 if (lines)
88 { 84 {
85 int prev_nl = 1;
86
89 mu_message_get_body (msg, &body); 87 mu_message_get_body (msg, &body);
90 mu_body_get_stream (body, &stream); 88 mu_body_get_stream (body, &stream);
91 n = off = 0; 89 n = off = 0;
92 while (mu_stream_readline (stream, buf, buflen, off, &n) == 0 90 while (mu_stream_readline (stream, buf, sizeof(buf), off, &n) == 0
93 && n > 0 && lines > 0) 91 && n > 0 && lines > 0)
94 { 92 {
95 /* Nuke the trailing newline. */ 93 if (prev_nl && buf[0] == '.')
94 pop3d_outf (".");
95
96 if (buf[n - 1] == '\n') 96 if (buf[n - 1] == '\n')
97 buf[n - 1] = '\0';
98 else /* make room for the line. */
99 { 97 {
100 buflen *= 2; 98 buf[n - 1] = '\0';
101 buf = realloc (buf, buflen * sizeof (*buf)); 99 pop3d_outf ("%s\r\n", buf);
102 if (buf == NULL) 100 prev_nl = 1;
103 pop3d_abquit (ERR_NO_MEM); 101 lines--;
104 continue;
105 } 102 }
106 if (buf[0] == '.')
107 pop3d_outf (".%s\r\n", buf);
108 else 103 else
109 pop3d_outf ("%s\r\n", buf); 104 {
110 lines--; 105 pop3d_outf ("%s", buf);
106 prev_nl = 0;
107 }
111 off += n; 108 off += n;
112 } 109 }
110 if (!prev_nl)
111 pop3d_outf ("\r\n");
113 } 112 }
114 113
115 free (buf);
116 pop3d_outf (".\r\n"); 114 pop3d_outf (".\r\n");
117 115
118 return OK; 116 return OK;
......