Commit dbbf8dae dbbf8dae0bdd56d108f8bfda7614b4a3b895eae2 by Sergey Poznyakoff

Fix memory leaks in filter and filter_iconv code.

* mailbox/filter.c (filter_destroy): Destroy the underlying
stream, unless flag is given.
(mu_filter_create): Treat last argument as stream flags.
* mailbox/filter_iconv.c (_icvt_destroy): Free the icvt_stream
structure.

* examples/mimetest.c (message_display_parts): Pass
MU_STREAM_NO_CLOSE to the invocation of mu_filter_create.
* mail/decode.c (display_submessage): Likewise.
* mailbox/attachment.c (mu_message_save_attachment): Likewise.
* mh/mh_list.c (eval_body): Likewise.
* mh/mhn.c (mhn_message_size, show_internal): Likewise.
(finish_text_msg): Likewise; call mu_stream_destroy

* imap4d/preauth.c (decode64_buf): remove unnecessary
call to mu_stream_destroy.
* libmu_auth/ldap.c (chk_md5, chk_smd5)
(chk_sha, chk_ssha): Likewise.

* mailbox/mutil.c: Fix indentation.
1 parent 77b116b1
...@@ -251,7 +251,10 @@ message_display_parts (mu_message_t msg, int indent) ...@@ -251,7 +251,10 @@ message_display_parts (mu_message_t msg, int indent)
251 printf ("%*.*sBegin\n", indent, indent, ""); 251 printf ("%*.*sBegin\n", indent, indent, "");
252 mu_message_get_body (part, &body); 252 mu_message_get_body (part, &body);
253 mu_body_get_stream (body, &str); 253 mu_body_get_stream (body, &str);
254 mu_filter_create (&str, str, encoding, 0, 0); 254 /* Make sure the original body stream is not closed when
255 str gets destroyed */
256 mu_filter_create (&str, str, encoding, MU_FILTER_DECODE,
257 MU_STREAM_READ | MU_STREAM_NO_CLOSE);
255 offset = 0; 258 offset = 0;
256 while (mu_stream_readline (str, buf, sizeof (buf), 259 while (mu_stream_readline (str, buf, sizeof (buf),
257 offset, &nbytes) == 0 && nbytes) 260 offset, &nbytes) == 0 && nbytes)
......
...@@ -217,7 +217,6 @@ decode64_buf (const char *name, unsigned char **pbuf, size_t *psize) ...@@ -217,7 +217,6 @@ decode64_buf (const char *name, unsigned char **pbuf, size_t *psize)
217 mu_stream_sequential_write (str, name, namelen); 217 mu_stream_sequential_write (str, name, namelen);
218 mu_stream_read (flt, (char*) buf, sizeof buf, 0, &size); 218 mu_stream_read (flt, (char*) buf, sizeof buf, 0, &size);
219 mu_stream_destroy (&flt, NULL); 219 mu_stream_destroy (&flt, NULL);
220 mu_stream_destroy (&str, NULL);
221 *pbuf = malloc (size); 220 *pbuf = malloc (size);
222 if (!*pbuf) 221 if (!*pbuf)
223 return 1; 222 return 1;
......
...@@ -602,7 +602,6 @@ chk_md5 (const char *db_pass, const char *pass) ...@@ -602,7 +602,6 @@ chk_md5 (const char *db_pass, const char *pass)
602 602
603 mu_stream_read (flt, (char*) d1, sizeof d1, 0, NULL); 603 mu_stream_read (flt, (char*) d1, sizeof d1, 0, NULL);
604 mu_stream_destroy (&flt, NULL); 604 mu_stream_destroy (&flt, NULL);
605 mu_stream_destroy (&str, NULL);
606 605
607 return memcmp (md5digest, d1, sizeof md5digest) == 0 ? 606 return memcmp (md5digest, d1, sizeof md5digest) == 0 ?
608 0 : MU_ERR_AUTH_FAILURE; 607 0 : MU_ERR_AUTH_FAILURE;
...@@ -629,13 +628,11 @@ chk_smd5 (const char *db_pass, const char *pass) ...@@ -629,13 +628,11 @@ chk_smd5 (const char *db_pass, const char *pass)
629 if (!d1) 628 if (!d1)
630 { 629 {
631 mu_stream_destroy (&flt, NULL); 630 mu_stream_destroy (&flt, NULL);
632 mu_stream_destroy (&str, NULL);
633 return ENOMEM; 631 return ENOMEM;
634 } 632 }
635 633
636 mu_stream_read (flt, (char*) d1, size, 0, &size); 634 mu_stream_read (flt, (char*) d1, size, 0, &size);
637 mu_stream_destroy (&flt, NULL); 635 mu_stream_destroy (&flt, NULL);
638 mu_stream_destroy (&str, NULL);
639 636
640 if (size <= 16) 637 if (size <= 16)
641 { 638 {
...@@ -674,7 +671,6 @@ chk_sha (const char *db_pass, const char *pass) ...@@ -674,7 +671,6 @@ chk_sha (const char *db_pass, const char *pass)
674 671
675 mu_stream_read (flt, (char*) d1, sizeof d1, 0, NULL); 672 mu_stream_read (flt, (char*) d1, sizeof d1, 0, NULL);
676 mu_stream_destroy (&flt, NULL); 673 mu_stream_destroy (&flt, NULL);
677 mu_stream_destroy (&str, NULL);
678 674
679 return memcmp (sha1digest, d1, sizeof sha1digest) == 0 ? 675 return memcmp (sha1digest, d1, sizeof sha1digest) == 0 ?
680 0 : MU_ERR_AUTH_FAILURE; 676 0 : MU_ERR_AUTH_FAILURE;
...@@ -701,7 +697,6 @@ chk_ssha (const char *db_pass, const char *pass) ...@@ -701,7 +697,6 @@ chk_ssha (const char *db_pass, const char *pass)
701 if (!d1) 697 if (!d1)
702 { 698 {
703 mu_stream_destroy (&flt, NULL); 699 mu_stream_destroy (&flt, NULL);
704 mu_stream_destroy (&str, NULL);
705 return ENOMEM; 700 return ENOMEM;
706 } 701 }
707 702
......
...@@ -258,7 +258,8 @@ display_submessage (struct mime_descend_closure *closure, void *data) ...@@ -258,7 +258,8 @@ display_submessage (struct mime_descend_closure *closure, void *data)
258 258
259 /* Can we decode. */ 259 /* Can we decode. */
260 if (mu_filter_create(&d_stream, b_stream, closure->encoding, 260 if (mu_filter_create(&d_stream, b_stream, closure->encoding,
261 MU_FILTER_DECODE, MU_STREAM_READ) == 0) 261 MU_FILTER_DECODE,
262 MU_STREAM_READ|MU_STREAM_NO_CLOSE) == 0)
262 stream = d_stream; 263 stream = d_stream;
263 else 264 else
264 stream = b_stream; 265 stream = b_stream;
......
...@@ -313,7 +313,8 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, ...@@ -313,7 +313,8 @@ mu_message_save_attachment (mu_message_t msg, const char *filename,
313 content_encoding = "7bit"; 313 content_encoding = "7bit";
314 ret = 314 ret =
315 mu_filter_create (&info->stream, istream, content_encoding, 315 mu_filter_create (&info->stream, istream, content_encoding,
316 MU_FILTER_DECODE, MU_STREAM_READ); 316 MU_FILTER_DECODE,
317 MU_STREAM_READ | MU_STREAM_NO_CLOSE);
317 free (content_encoding_mem); 318 free (content_encoding_mem);
318 } 319 }
319 } 320 }
......
...@@ -46,6 +46,8 @@ static void ...@@ -46,6 +46,8 @@ static void
46 filter_destroy (mu_stream_t stream) 46 filter_destroy (mu_stream_t stream)
47 { 47 {
48 mu_filter_t filter = mu_stream_get_owner (stream); 48 mu_filter_t filter = mu_stream_get_owner (stream);
49 if (!(stream->flags & MU_STREAM_NO_CLOSE))
50 mu_stream_destroy (&filter->stream, mu_stream_get_owner (filter->stream));
49 if (filter->_destroy) 51 if (filter->_destroy)
50 filter->_destroy (filter); 52 filter->_destroy (filter);
51 if (filter->property) 53 if (filter->property)
...@@ -165,7 +167,7 @@ mu_filter_get_list (mu_list_t *plist) ...@@ -165,7 +167,7 @@ mu_filter_get_list (mu_list_t *plist)
165 167
166 int 168 int
167 mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name, 169 mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name,
168 int type, int direction) 170 int type, int flags)
169 { 171 {
170 mu_iterator_t iterator = NULL; 172 mu_iterator_t iterator = NULL;
171 mu_filter_record_t filter_record = NULL; 173 mu_filter_record_t filter_record = NULL;
...@@ -204,14 +206,12 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name, ...@@ -204,14 +206,12 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name,
204 206
205 if (found) 207 if (found)
206 { 208 {
207 int flags = 0;
208 mu_filter_t filter; 209 mu_filter_t filter;
209 210
210 filter = calloc (1, sizeof (*filter)); 211 filter = calloc (1, sizeof (*filter));
211 if (filter == NULL) 212 if (filter == NULL)
212 return ENOMEM; 213 return ENOMEM;
213 214
214 mu_stream_get_flags (stream, &flags);
215 status = mu_stream_create (pstream, flags | MU_STREAM_NO_CHECK, filter); 215 status = mu_stream_create (pstream, flags | MU_STREAM_NO_CHECK, filter);
216 if (status != 0) 216 if (status != 0)
217 { 217 {
...@@ -221,7 +221,11 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name, ...@@ -221,7 +221,11 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name,
221 221
222 filter->stream = stream; 222 filter->stream = stream;
223 filter->filter_stream = *pstream; 223 filter->filter_stream = *pstream;
224 filter->direction = (direction == 0) ? MU_STREAM_READ : direction; 224 filter->direction = (flags == 0) ? MU_STREAM_READ
225 : (flags
226 & (MU_STREAM_READ |
227 MU_STREAM_WRITE |
228 MU_STREAM_RDWR));
225 filter->type = type; 229 filter->type = type;
226 230
227 status = mu_property_create (&(filter->property), filter); 231 status = mu_property_create (&(filter->property), filter);
...@@ -249,8 +253,8 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name, ...@@ -249,8 +253,8 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name,
249 } 253 }
250 } 254 }
251 255
252 mu_stream_set_open (*pstream, filter_open, filter ); 256 mu_stream_set_open (*pstream, filter_open, filter);
253 mu_stream_set_close (*pstream, filter_close, filter ); 257 mu_stream_set_close (*pstream, filter_close, filter);
254 mu_stream_set_read (*pstream, filter_read, filter); 258 mu_stream_set_read (*pstream, filter_read, filter);
255 mu_stream_set_readline (*pstream, filter_readline, filter); 259 mu_stream_set_readline (*pstream, filter_readline, filter);
256 mu_stream_set_write (*pstream, filter_write, filter); 260 mu_stream_set_write (*pstream, filter_write, filter);
......
...@@ -114,6 +114,7 @@ _icvt_destroy (mu_stream_t stream) ...@@ -114,6 +114,7 @@ _icvt_destroy (mu_stream_t stream)
114 s->buf = NULL; 114 s->buf = NULL;
115 if (s->cd != (iconv_t) -1) 115 if (s->cd != (iconv_t) -1)
116 iconv_close (s->cd); 116 iconv_close (s->cd);
117 free (s);
117 } 118 }
118 119
119 static int _icvt_read (mu_stream_t stream, char *optr, size_t osize, 120 static int _icvt_read (mu_stream_t stream, char *optr, size_t osize,
......
...@@ -1329,8 +1329,8 @@ mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input, ...@@ -1329,8 +1329,8 @@ mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input,
1329 { 1329 {
1330 mu_stream_t cvt; 1330 mu_stream_t cvt;
1331 status = mu_filter_iconv_create (&cvt, filter, fromcode, tocode, 1331 status = mu_filter_iconv_create (&cvt, filter, fromcode, tocode,
1332 MU_STREAM_NO_CLOSE, 1332 MU_STREAM_NO_CLOSE,
1333 mu_default_fallback_mode); 1333 mu_default_fallback_mode);
1334 if (status == 0) 1334 if (status == 0)
1335 { 1335 {
1336 if (mu_stream_open (cvt)) 1336 if (mu_stream_open (cvt))
......
...@@ -699,7 +699,8 @@ eval_body (struct eval_env *env) ...@@ -699,7 +699,8 @@ eval_body (struct eval_env *env)
699 if (encoding) 699 if (encoding)
700 { 700 {
701 int rc = mu_filter_create(&dstr, input, encoding, 701 int rc = mu_filter_create(&dstr, input, encoding,
702 MU_FILTER_DECODE, MU_STREAM_READ); 702 MU_FILTER_DECODE,
703 MU_STREAM_READ | MU_STREAM_NO_CLOSE);
703 if (rc == 0) 704 if (rc == 0)
704 input = dstr; 705 input = dstr;
705 free (encoding); 706 free (encoding);
......
...@@ -1122,8 +1122,9 @@ mhn_message_size (mu_message_t msg, size_t *psize) ...@@ -1122,8 +1122,9 @@ mhn_message_size (mu_message_t msg, size_t *psize)
1122 mu_message_get_header (msg, &hdr); 1122 mu_message_get_header (msg, &hdr);
1123 _get_content_encoding (hdr, &encoding); 1123 _get_content_encoding (hdr, &encoding);
1124 1124
1125 rc = mu_filter_create(&dstr, bstr, encoding, 1125 rc = mu_filter_create (&dstr, bstr, encoding,
1126 MU_FILTER_DECODE, MU_STREAM_READ); 1126 MU_FILTER_DECODE,
1127 MU_STREAM_READ | MU_STREAM_NO_CLOSE);
1127 free (encoding); 1128 free (encoding);
1128 if (rc == 0) 1129 if (rc == 0)
1129 { 1130 {
...@@ -1272,8 +1273,8 @@ show_internal (mu_message_t msg, msg_part_t part, char *encoding, mu_stream_t ou ...@@ -1272,8 +1273,8 @@ show_internal (mu_message_t msg, msg_part_t part, char *encoding, mu_stream_t ou
1272 return 0; 1273 return 0;
1273 } 1274 }
1274 mu_body_get_stream (body, &bstr); 1275 mu_body_get_stream (body, &bstr);
1275 rc = mu_filter_create(&dstr, bstr, encoding, 1276 rc = mu_filter_create (&dstr, bstr, encoding,
1276 MU_FILTER_DECODE, MU_STREAM_READ); 1277 MU_FILTER_DECODE, MU_STREAM_READ | MU_STREAM_NO_CLOSE);
1277 if (rc == 0) 1278 if (rc == 0)
1278 bstr = dstr; 1279 bstr = dstr;
1279 cat_message (out, bstr); 1280 cat_message (out, bstr);
...@@ -2052,10 +2053,12 @@ finish_text_msg (struct compose_env *env, mu_message_t *msg, int ascii) ...@@ -2052,10 +2053,12 @@ finish_text_msg (struct compose_env *env, mu_message_t *msg, int ascii)
2052 mu_message_get_body (*msg, &body); 2053 mu_message_get_body (*msg, &body);
2053 mu_body_get_stream (body, &input); 2054 mu_body_get_stream (body, &input);
2054 rc = mu_filter_create (&fstr, input, "quoted-printable", 2055 rc = mu_filter_create (&fstr, input, "quoted-printable",
2055 MU_FILTER_ENCODE, MU_STREAM_READ); 2056 MU_FILTER_ENCODE,
2057 MU_STREAM_READ | MU_STREAM_NO_CLOSE);
2056 if (rc == 0) 2058 if (rc == 0)
2057 { 2059 {
2058 cat_message (output, fstr); 2060 cat_message (output, fstr);
2061 mu_stream_destroy (&fstr, NULL);
2059 mu_message_unref (*msg); 2062 mu_message_unref (*msg);
2060 *msg = newmsg; 2063 *msg = newmsg;
2061 } 2064 }
......