Index: protos.h =================================================================== RCS file: /home/roessler/cvs/mutt/protos.h,v retrieving revision 3.44 diff -p -u -r3.44 protos.h --- protos.h 28 Apr 2006 19:52:45 -0000 3.44 +++ protos.h 11 Jun 2006 13:54:52 -0000 @@ -37,6 +37,8 @@ void _mutt_make_string (char *, size_t, int mutt_extract_token (BUFFER *, BUFFER *, int); BUFFER * mutt_buffer_init (BUFFER *); +BUFFER * mutt_buffer_size (BUFFER *, size_t); +BUFFER * mutt_buffer_resize (BUFFER *, size_t); BUFFER * mutt_buffer_from (BUFFER *, char *); void mutt_buffer_free(BUFFER **); int mutt_buffer_printf (BUFFER*, const char*, ...); @@ -369,7 +371,7 @@ pid_t mutt_create_filter_fd (const char ADDRESS *alias_reverse_lookup (ADDRESS *); /* base64.c */ -void mutt_to_base64 (unsigned char*, const unsigned char*, size_t, size_t); +void mutt_to_base64 (BUFFER*, const unsigned char*, size_t); int mutt_from_base64 (char*, const char*); /* utf8.c */ Index: rfc1524.h =================================================================== RCS file: /home/roessler/cvs/mutt/rfc1524.h,v retrieving revision 3.3 diff -p -u -r3.3 rfc1524.h --- rfc1524.h 17 Sep 2005 20:46:11 -0000 3.3 +++ rfc1524.h 11 Jun 2006 13:54:52 -0000 @@ -36,7 +36,7 @@ typedef struct rfc1524_mailcap_entry { rfc1524_entry *rfc1524_new_entry (void); void rfc1524_free_entry (rfc1524_entry **); -int rfc1524_expand_command (BODY *, char *, char *, char *, int); +int rfc1524_expand_command (BODY *, char *, char *, BUFFER *); int rfc1524_expand_filename (char *, char *, char *, size_t); int rfc1524_mailcap_lookup (BODY *, char *, rfc1524_entry *, int); int mutt_rename_file (char *, char *); Index: url.h =================================================================== RCS file: /home/roessler/cvs/mutt/url.h,v retrieving revision 3.0 diff -p -u -r3.0 url.h --- url.h 24 Jan 2002 12:10:52 -0000 3.0 +++ url.h 11 Jun 2006 13:54:53 -0000 @@ -29,7 +29,7 @@ ciss_url_t; url_scheme_t url_check_scheme (const char *s); int url_parse_file (char *d, const char *src, size_t dl); int url_parse_ciss (ciss_url_t *ciss, char *src); -int url_ciss_tostring (ciss_url_t* ciss, char* dest, size_t len, int flags); +int url_ciss_tostring (ciss_url_t* ciss, BUFFER* dest, int flags); int url_parse_mailto (ENVELOPE *e, char **body, const char *src); #endif Index: imap/imap.h =================================================================== RCS file: /home/roessler/cvs/mutt/imap/imap.h,v retrieving revision 3.11 diff -p -u -r3.11 imap.h --- imap/imap.h 15 Jan 2006 21:37:03 -0000 3.11 +++ imap/imap.h 11 Jun 2006 13:54:56 -0000 @@ -62,9 +62,9 @@ int imap_fetch_message (MESSAGE* msg, CO void imap_logout_all (void); /* util.c */ -int imap_expand_path (char* path, size_t len); +int imap_expand_path (BUFFER *path); int imap_parse_path (const char* path, IMAP_MBOX* mx); -void imap_pretty_mailbox (char* path); +void imap_pretty_mailbox (BUFFER* path); int imap_wait_keepalive (pid_t pid); void imap_keepalive (void); Index: imap/imap_private.h =================================================================== RCS file: /home/roessler/cvs/mutt/imap/imap_private.h,v retrieving revision 3.28 diff -p -u -r3.28 imap_private.h --- imap/imap_private.h 23 Dec 2005 18:20:02 -0000 3.28 +++ imap/imap_private.h 11 Jun 2006 13:54:56 -0000 @@ -260,7 +260,7 @@ int imap_code (const char* s); int imap_exec (IMAP_DATA* idata, const char* cmd, int flags); /* message.c */ -void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags, size_t slen); +void imap_add_keywords (BUFFER* s, HEADER* keywords, LIST* mailbox_flags); void imap_free_header_data (void** data); int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend); char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s); @@ -271,17 +271,16 @@ int imap_continue (const char* msg, cons void imap_error (const char* where, const char* msg); IMAP_DATA* imap_new_idata (void); void imap_free_idata (IMAP_DATA** idata); -char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path, - size_t plen); +BUFFER* imap_fix_path (IMAP_DATA* idata, char* mailbox, BUFFER* path); int imap_get_literal_count (const char* buf, long* bytes); char* imap_get_qualifier (char* buf); int imap_mxcmp (const char* mx1, const char* mx2); char* imap_next_word (char* s); time_t imap_parse_date (char* s); -void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path); -void imap_quote_string (char* dest, size_t slen, const char* src); +void imap_qualify_path (BUFFER *dest, IMAP_MBOX *mx, char* path); +void imap_quote_string (BUFFER* dest, const char* src); void imap_unquote_string (char* s); -void imap_munge_mbox_name (char *dest, size_t dlen, const char *src); +void imap_munge_mbox_name (BUFFER *dest, const char *src); void imap_unmunge_mbox_name (char *s); int imap_wordcasecmp(const char *a, const char *b); Index: muttlib.c =================================================================== RCS file: /home/roessler/cvs/mutt/muttlib.c,v retrieving revision 3.43 diff -p -u -r3.43 muttlib.c --- muttlib.c 18 May 2006 17:35:30 -0000 3.43 +++ muttlib.c 11 Jun 2006 13:54:51 -0000 @@ -495,7 +495,15 @@ char *_mutt_expand_path (char *s, size_t /* Rewrite IMAP path in canonical form - aids in string comparisons of * folders. May possibly fail, in which case s should be the same. */ if (mx_is_imap (s)) - imap_expand_path (s, slen); + { + BUFFER *tmpbuf = NULL; + tmpbuf = mutt_buffer_from (tmpbuf, s); + imap_expand_path (tmpbuf); + if ((tmpbuf->dptr - tmpbuf->data) > slen) + dprint (1, (debugfile, "expand_path: possibly truncated: [%s]\n", tmpbuf->data)); + strfcpy (s, tmpbuf->data, slen); + mutt_buffer_free (&tmpbuf); + } #endif return (s); @@ -763,7 +771,14 @@ void mutt_pretty_mailbox (char *s) #ifdef USE_IMAP if (scheme == U_IMAP || scheme == U_IMAPS) { - imap_pretty_mailbox (s); + BUFFER *ibuf = NULL; + ibuf = mutt_buffer_from (ibuf, s); + len = ibuf->dsize; + imap_pretty_mailbox (ibuf); + if (len < ibuf->dsize) + dprint (1, (debugfile, "pretty_mailbox: possibly truncated\n")); + strfcpy (s, ibuf->data, len); + mutt_buffer_free (&ibuf); return; } #endif @@ -1399,6 +1414,46 @@ BUFFER * mutt_buffer_init(BUFFER *b) return b; } +BUFFER * mutt_buffer_size(BUFFER *b, size_t size) +{ + b = mutt_buffer_init (b); + if (!b) + return NULL; + b->data = safe_malloc (size); + if (!b->data) + { + FREE (&b); + return NULL; + } + b->dptr = b->data; + *b->dptr = '\0'; + b->dsize = size; + return b; +} + +BUFFER * mutt_buffer_resize(BUFFER *b, size_t size) +{ + size_t offset; + + if (!b) + { + b = mutt_buffer_init (b); + if (!b) + return NULL; + } + offset = b->dptr - b->data; + safe_realloc (b->data, size); + if (!b->data) + { + FREE (&b); + return NULL; + } + b->data[size-1] = '\0'; + b->dsize = size; + b->dptr = b->data + offset; + return b; +} + /* * Creates and initializes a BUFFER*. If passed an existing BUFFER*, * just initializes. Frees anything already in the buffer. Copies in @@ -1414,8 +1469,8 @@ BUFFER * mutt_buffer_from(BUFFER *b, cha b = mutt_buffer_init(b); b->data = safe_strdup (seed); - b->dsize = mutt_strlen (seed); - b->dptr = (char *) b->data + b->dsize; + b->dsize = mutt_strlen (seed) + 1; + b->dptr = (char *) b->data + b->dsize - 1; return b; } @@ -1427,6 +1482,9 @@ int mutt_buffer_printf (BUFFER* buf, con va_start (ap, fmt); va_copy (ap_retry, ap); + if (!buf) + buf = mutt_buffer_size (buf, STRING); + doff = buf->dptr - buf->data; blen = buf->dsize - doff; /* solaris 9 vsnprintf barfs when blen is 0 */ @@ -1483,6 +1541,9 @@ void mutt_buffer_add (BUFFER* buf, const { size_t offset; + if (!buf) + buf = mutt_buffer_size (buf, len + 1); + if (buf->dptr + len + 1 > buf->data + buf->dsize) { offset = buf->dptr - buf->data; Index: account.c =================================================================== RCS file: /home/roessler/cvs/mutt/account.c,v retrieving revision 3.11 diff -p -u -r3.11 account.c --- account.c 17 Sep 2005 20:46:09 -0000 3.11 +++ account.c 11 Jun 2006 13:54:43 -0000 @@ -68,18 +68,22 @@ int mutt_account_match (const ACCOUNT* a int mutt_account_fromurl (ACCOUNT* account, ciss_url_t* url) { /* must be present */ - if (url->host) + if (url->host && strlen (url->host) < sizeof (account->host)) strfcpy (account->host, url->host, sizeof (account->host)); else return -1; if (url->user) { + if (strlen (url->user) >= sizeof (account->user)) + return -1; strfcpy (account->user, url->user, sizeof (account->user)); account->flags |= M_ACCT_USER; } if (url->pass) { + if (strlen (url->pass) >= sizeof (account->pass)) + return -1; strfcpy (account->pass, url->pass, sizeof (account->pass)); account->flags |= M_ACCT_PASS; } Index: attach.c =================================================================== RCS file: /home/roessler/cvs/mutt/attach.c,v retrieving revision 3.21 diff -p -u -r3.21 attach.c --- attach.c 21 Feb 2006 08:10:15 -0000 3.21 +++ attach.c 11 Jun 2006 13:54:43 -0000 @@ -87,7 +87,7 @@ int mutt_get_tmp_attachment (BODY *a) int mutt_compose_attachment (BODY *a) { char type[STRING]; - char command[STRING]; + BUFFER *command = NULL; char newfile[_POSIX_PATH_MAX] = ""; rfc1524_entry *entry = rfc1524_new_entry (); short unlink_newfile = 0; @@ -100,9 +100,9 @@ int mutt_compose_attachment (BODY *a) { if (entry->composetypecommand) - strfcpy (command, entry->composetypecommand, sizeof (command)); + command = mutt_buffer_from (command, entry->composetypecommand); else - strfcpy (command, entry->composecommand, sizeof (command)); + command = mutt_buffer_from (command, entry->composecommand); if (rfc1524_expand_filename (entry->nametemplate, a->filename, newfile, sizeof (newfile))) { @@ -119,8 +119,7 @@ int mutt_compose_attachment (BODY *a) else strfcpy(newfile, a->filename, sizeof(newfile)); - if (rfc1524_expand_command (a, newfile, type, - command, sizeof (command))) + if (rfc1524_expand_command (a, newfile, type, command)) { /* For now, editing requires a file, no piping */ mutt_error _("Mailcap compose entry requires %%s"); @@ -130,8 +129,8 @@ int mutt_compose_attachment (BODY *a) int r; mutt_endwin (NULL); - if ((r = mutt_system (command)) == -1) - mutt_error (_("Error running \"%s\"!"), command); + if ((r = mutt_system (command->data)) == -1) + mutt_error (_("Error running \"%s\"!"), command->data); if (r != -1 && entry->composetypecommand) { @@ -196,6 +195,7 @@ int mutt_compose_attachment (BODY *a) rfc1524_free_entry (&entry); mutt_message (_("No mailcap compose entry for %s, creating empty file."), type); + mutt_buffer_free (&command); return 1; } @@ -207,6 +207,7 @@ int mutt_compose_attachment (BODY *a) unlink(newfile); rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return rc; } @@ -222,7 +223,7 @@ int mutt_compose_attachment (BODY *a) int mutt_edit_attachment (BODY *a) { char type[STRING]; - char command[STRING]; + BUFFER *command = NULL; char newfile[_POSIX_PATH_MAX] = ""; rfc1524_entry *entry = rfc1524_new_entry (); short unlink_newfile = 0; @@ -233,8 +234,7 @@ int mutt_edit_attachment (BODY *a) { if (entry->editcommand) { - - strfcpy (command, entry->editcommand, sizeof (command)); + command = mutt_buffer_from (command, entry->editcommand); if (rfc1524_expand_filename (entry->nametemplate, a->filename, newfile, sizeof (newfile))) { @@ -251,8 +251,7 @@ int mutt_edit_attachment (BODY *a) else strfcpy(newfile, a->filename, sizeof(newfile)); - if (rfc1524_expand_command (a, newfile, type, - command, sizeof (command))) + if (rfc1524_expand_command (a, newfile, type, command)) { /* For now, editing requires a file, no piping */ mutt_error _("Mailcap Edit entry requires %%s"); @@ -261,9 +260,9 @@ int mutt_edit_attachment (BODY *a) else { mutt_endwin (NULL); - if (mutt_system (command) == -1) + if (mutt_system (command->data) == -1) { - mutt_error (_("Error running \"%s\"!"), command); + mutt_error (_("Error running \"%s\"!"), command->data); goto bailout; } } @@ -278,6 +277,7 @@ int mutt_edit_attachment (BODY *a) { rfc1524_free_entry (&entry); mutt_error (_("No mailcap edit entry for %s"),type); + mutt_buffer_free (&command); return 0; } @@ -289,6 +289,7 @@ int mutt_edit_attachment (BODY *a) unlink(newfile); rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return rc; } @@ -416,7 +417,7 @@ int mutt_view_attachment (FILE *fp, BODY int use_pipe = 0; int use_pager = 1; char type[STRING]; - char command[STRING]; + BUFFER *command = NULL; char descrip[STRING]; char *fname; rfc1524_entry *entry = NULL; @@ -456,7 +457,7 @@ int mutt_view_attachment (FILE *fp, BODY mutt_error _("MIME type not defined. Cannot view attachment."); goto return_error; } - strfcpy (command, entry->command, sizeof (command)); + command = mutt_buffer_from (command, entry->command); if (fp) { @@ -494,8 +495,7 @@ int mutt_view_attachment (FILE *fp, BODY goto return_error; } - use_pipe = rfc1524_expand_command (a, tempfile, type, - command, sizeof (command)); + use_pipe = rfc1524_expand_command (a, tempfile, type, command); use_pager = entry->copiousoutput; } @@ -534,7 +534,7 @@ int mutt_view_attachment (FILE *fp, BODY goto return_error; } - if ((thepid = mutt_create_filter_fd (command, NULL, NULL, NULL, + if ((thepid = mutt_create_filter_fd (command->data, NULL, NULL, NULL, use_pipe ? tempfd : -1, use_pager ? pagerfd : -1, -1)) == -1) { if(pagerfd != -1) @@ -552,10 +552,10 @@ int mutt_view_attachment (FILE *fp, BODY if (a->description) snprintf (descrip, sizeof (descrip), "---Command: %-20.20s Description: %s", - command, a->description); + command->data, a->description); else snprintf (descrip, sizeof (descrip), - "---Command: %-30.30s Attachment: %s", command, type); + "---Command: %-30.30s Attachment: %s", command->data, type); } if ((mutt_wait_filter (thepid) || (entry->needsterminal && @@ -569,7 +569,7 @@ int mutt_view_attachment (FILE *fp, BODY else { /* interactive command */ - if (mutt_system (command) || + if (mutt_system (command->data) || (entry->needsterminal && option (OPTWAITKEY))) mutt_any_key_to_continue (NULL); } @@ -639,6 +639,7 @@ int mutt_view_attachment (FILE *fp, BODY if (pagerfile[0]) mutt_unlink (pagerfile); + mutt_buffer_free (&command); return rc; } @@ -950,7 +951,7 @@ int mutt_print_attachment (FILE *fp, BOD if (rfc1524_mailcap_lookup (a, type, NULL, M_PRINT)) { - char command[_POSIX_PATH_MAX+STRING]; + BUFFER *command = NULL; rfc1524_entry *entry; int piped = FALSE; @@ -968,6 +969,7 @@ int mutt_print_attachment (FILE *fp, BOD if (mutt_yesorno (_("Can't match nametemplate, continue?"), M_YES) != M_YES) { rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return 0; } strfcpy (newfile, a->filename, sizeof (newfile)); @@ -981,8 +983,8 @@ int mutt_print_attachment (FILE *fp, BOD if (fp) mutt_save_attachment (fp, a, newfile, 0, NULL); - strfcpy (command, entry->printcommand, sizeof (command)); - piped = rfc1524_expand_command (a, newfile, type, command, sizeof (command)); + command = mutt_buffer_from (command, entry->printcommand); + piped = rfc1524_expand_command (a, newfile, type, command); mutt_endwin (NULL); @@ -993,14 +995,16 @@ int mutt_print_attachment (FILE *fp, BOD { mutt_perror ("fopen"); rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return (0); } - if ((thepid = mutt_create_filter (command, &fpout, NULL, NULL)) < 0) + if ((thepid = mutt_create_filter (command->data, &fpout, NULL, NULL)) < 0) { mutt_perror _("Can't create filter"); rfc1524_free_entry (&entry); safe_fclose (&ifp); + mutt_buffer_free (&command); return 0; } mutt_copy_stream (ifp, fpout); @@ -1011,7 +1015,7 @@ int mutt_print_attachment (FILE *fp, BOD } else { - if (mutt_system (command) || option (OPTWAITKEY)) + if (mutt_system (command->data) || option (OPTWAITKEY)) mutt_any_key_to_continue (NULL); } @@ -1021,6 +1025,7 @@ int mutt_print_attachment (FILE *fp, BOD unlink(newfile); rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return (1); } Index: base64.c =================================================================== RCS file: /home/roessler/cvs/mutt/base64.c,v retrieving revision 3.3 diff -p -u -r3.3 base64.c --- base64.c 17 Sep 2005 20:46:09 -0000 3.3 +++ base64.c 11 Jun 2006 13:54:43 -0000 @@ -49,34 +49,39 @@ #define BAD -1 /* raw bytes to null-terminated base 64 string */ -void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len, - size_t olen) +void mutt_to_base64 (BUFFER *out, const unsigned char *in, size_t len) { - while (len >= 3 && olen > 10) + if (!out) + out = mutt_buffer_size (out, SHORT_STRING); + + while (len >= 3) { - *out++ = B64Chars[in[0] >> 2]; - *out++ = B64Chars[((in[0] << 4) & 0x30) | (in[1] >> 4)]; - *out++ = B64Chars[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; - *out++ = B64Chars[in[2] & 0x3f]; - olen -= 4; + /* get rid of mutt_buffer_add for performance sake */ + if (out->data + out->dsize < out->dptr + 5) + out = mutt_buffer_resize (out, out->dsize + SHORT_STRING); + + *out->dptr++ = B64Chars[in[0] >> 2]; + *out->dptr++ = B64Chars[((in[0] << 4) & 0x30) | (in[1] >> 4)]; + *out->dptr++ = B64Chars[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; + *out->dptr++ = B64Chars[in[2] & 0x3f]; len -= 3; in += 3; } + *out->dptr = '\0'; /* clean up remainder */ - if (len > 0 && olen > 4) + if (len > 0) { unsigned char fragment; - *out++ = B64Chars[in[0] >> 2]; + mutt_buffer_addch (out, B64Chars[in[0] >> 2]); fragment = (in[0] << 4) & 0x30; if (len > 1) fragment |= in[1] >> 4; - *out++ = B64Chars[fragment]; - *out++ = (len < 2) ? '=' : B64Chars[(in[1] << 2) & 0x3c]; - *out++ = '='; + mutt_buffer_addch (out, B64Chars[fragment]); + mutt_buffer_addch (out, (len < 2) ? '=' : B64Chars[(in[1] << 2) & 0x3c]); + mutt_buffer_addch (out, '='); } - *out = '\0'; } /* Convert '\0'-terminated base 64 string to raw bytes. Index: buffy.c =================================================================== RCS file: /home/roessler/cvs/mutt/buffy.c,v retrieving revision 3.19 diff -p -u -r3.19 buffy.c --- buffy.c 18 May 2006 17:35:29 -0000 3.19 +++ buffy.c 11 Jun 2006 13:54:44 -0000 @@ -180,6 +180,8 @@ int mutt_parse_mailboxes (BUFFER *path, while (MoreArgs (s)) { mutt_extract_token (path, s, 0); + if (sizeof (buf) <= path->dptr - path->data) + return -1; /* too long */ strfcpy (buf, path->data, sizeof (buf)); if(data == M_UNMAILBOXES && mutt_strcmp(buf,"*") == 0) Index: commands.c =================================================================== RCS file: /home/roessler/cvs/mutt/commands.c,v retrieving revision 3.35 diff -p -u -r3.35 commands.c --- commands.c 17 Sep 2005 20:46:10 -0000 3.35 +++ commands.c 11 Jun 2006 13:54:44 -0000 @@ -60,7 +60,8 @@ static char LastSaveFolder[_POSIX_PATH_M int mutt_display_message (HEADER *cur) { - char tempfile[_POSIX_PATH_MAX], buf[LONG_STRING]; + char tempfile[_POSIX_PATH_MAX]; + BUFFER *buf = NULL; int rc = 0, builtin = 0; int cmflags = M_CM_DECODE | M_CM_DISPLAY | M_CM_CHARCONV; FILE *fpout = NULL; @@ -68,7 +69,8 @@ int mutt_display_message (HEADER *cur) pid_t filterpid = -1; int res; - snprintf (buf, sizeof (buf), "%s/%s", TYPE (cur->content), + buf = mutt_buffer_size (buf, LONG_STRING); + mutt_buffer_printf (buf, "%s/%s", TYPE (cur->content), cur->content->subtype); mutt_parse_mime_message (Context, cur); @@ -82,7 +84,10 @@ int mutt_display_message (HEADER *cur) if (cur->security & APPLICATION_SMIME) crypt_smime_getkeys (cur->env); if(!crypt_valid_passphrase(cur->security)) + { + mutt_buffer_free (&buf); return 0; + } cmflags |= M_CM_VERIFY; } @@ -115,6 +120,7 @@ int mutt_display_message (HEADER *cur) if ((fpout = safe_fopen (tempfile, "w")) == NULL) { mutt_error _("Could not create temporary file!"); + mutt_buffer_free (&buf); return (0); } @@ -130,6 +136,7 @@ int mutt_display_message (HEADER *cur) mutt_error (_("Cannot create display filter")); safe_fclose (&fpfilterout); unlink (tempfile); + mutt_buffer_free (&buf); return 0; } } @@ -138,8 +145,9 @@ int mutt_display_message (HEADER *cur) builtin = 1; else { - mutt_make_string (buf, sizeof (buf), NONULL(PagerFmt), Context, cur); - fputs (buf, fpout); + char sbuf[LONG_STRING]; + mutt_make_string (sbuf, sizeof (sbuf), NONULL(PagerFmt), Context, cur); + fputs (sbuf, fpout); fputs ("\n\n", fpout); } @@ -154,6 +162,7 @@ int mutt_display_message (HEADER *cur) safe_fclose (&fpfilterout); } mutt_unlink (tempfile); + mutt_buffer_free (&buf); return 0; } @@ -216,9 +225,10 @@ int mutt_display_message (HEADER *cur) int r; mutt_endwin (NULL); - snprintf (buf, sizeof (buf), "%s %s", NONULL(Pager), tempfile); - if ((r = mutt_system (buf)) == -1) - mutt_error (_("Error running \"%s\"!"), buf); + buf->dptr = buf->data; + mutt_buffer_printf (buf, "%s %s", NONULL(Pager), tempfile); + if ((r = mutt_system (buf->data)) == -1) + mutt_error (_("Error running \"%s\"!"), buf->data); unlink (tempfile); keypad (stdscr, TRUE); if (r != -1) @@ -232,6 +242,7 @@ int mutt_display_message (HEADER *cur) rc = 0; } + mutt_buffer_free (&buf); return rc; } Index: compose.c =================================================================== RCS file: /home/roessler/cvs/mutt/compose.c,v retrieving revision 3.27 diff -p -u -r3.27 compose.c --- compose.c 17 Sep 2005 20:46:10 -0000 3.27 +++ compose.c 11 Jun 2006 13:54:45 -0000 @@ -1177,16 +1177,22 @@ int mutt_compose_menu (HEADER *msg, /* break; case OP_COMPOSE_ISPELL: + { + BUFFER *ispell = NULL; endwin (); - snprintf (buf, sizeof (buf), "%s -x %s", NONULL(Ispell), msg->content->filename); - if (mutt_system (buf) == -1) - mutt_error (_("Error running \"%s\"!"), buf); + ispell = mutt_buffer_from (ispell, NONULL(Ispell)); + mutt_buffer_add (ispell, " -x ", 4); + mutt_buffer_addstr (ispell, msg->content->filename); + if (mutt_system (ispell->data) == -1) + mutt_error (_("Error running \"%s\"!"), ispell->data); else { mutt_update_encoding (msg->content); menu->redraw |= REDRAW_STATUS; } + mutt_buffer_free (&ispell); break; + } case OP_COMPOSE_WRITE_MESSAGE: Index: edit.c =================================================================== RCS file: /home/roessler/cvs/mutt/edit.c,v retrieving revision 3.9 diff -p -u -r3.9 edit.c --- edit.c 21 Oct 2005 04:35:37 -0000 3.9 +++ edit.c 11 Jun 2006 13:54:45 -0000 @@ -334,7 +334,7 @@ int mutt_builtin_editor (const char *pat tmp[0] = 0; while (!done) { - if (mutt_enter_string (tmp, sizeof (tmp), LINES-1, 0, 0) == -1) + if (mutt_enter_string (tmp, sizeof (tmp) - 1, LINES-1, 0, 0) == -1) { tmp[0] = 0; continue; Index: getdomain.c =================================================================== RCS file: /home/roessler/cvs/mutt/getdomain.c,v retrieving revision 3.1 diff -p -u -r3.1 getdomain.c --- getdomain.c 3 Feb 2005 17:01:43 -0000 3.1 +++ getdomain.c 11 Jun 2006 13:54:45 -0000 @@ -12,19 +12,22 @@ int fclose (); #endif -/* poor man's version of getdomainname() for systems where it does not return +/* poor man's version of getdomainname() for systems where it does not * return the DNS domain, but the NIS domain. */ -static void strip_trailing_dot (char *q) +static size_t strip_trailing_dot (char *q) { char *p = q; + size_t l = 0; for (; *q; q++) - p = q; + p = q, l++; if (*p == '.') - *p = '\0'; + *p = '\0', l--; + + return l; } int getdnsdomainname (char *s, size_t l) @@ -54,7 +57,8 @@ int getdnsdomainname (char *s, size_t l) if (q) { - strip_trailing_dot (q); + if (strip_trailing_dot (q) >= l) + continue; /* ignore too long one */ strfcpy (s, q, l); safe_fclose (&f); return 0; Index: handler.c =================================================================== RCS file: /home/roessler/cvs/mutt/handler.c,v retrieving revision 3.26 diff -p -u -r3.26 handler.c --- handler.c 16 Dec 2005 18:49:40 -0000 3.26 +++ handler.c 11 Jun 2006 13:54:47 -0000 @@ -1516,7 +1516,7 @@ int autoview_handler (BODY *a, STATE *s) rfc1524_entry *entry = rfc1524_new_entry (); char buffer[LONG_STRING]; char type[STRING]; - char command[LONG_STRING]; + BUFFER *command = NULL; char tempfile[_POSIX_PATH_MAX] = ""; char *fname; FILE *fpin = NULL; @@ -1536,22 +1536,23 @@ int autoview_handler (BODY *a, STATE *s) if (entry->command) { - strfcpy (command, entry->command, sizeof (command)); + command = mutt_buffer_from (command, entry->command); /* rfc1524_expand_command returns 0 if the file is required */ - piped = rfc1524_expand_command (a, tempfile, type, command, sizeof (command)); + piped = rfc1524_expand_command (a, tempfile, type, command); if (s->flags & M_DISPLAY) { state_mark_attach (s); - state_printf (s, _("[-- Autoview using %s --]\n"), command); - mutt_message(_("Invoking autoview command: %s"),command); + state_printf (s, _("[-- Autoview using %s --]\n"), command->data); + mutt_message(_("Invoking autoview command: %s"),command->data); } if ((fpin = safe_fopen (tempfile, "w+")) == NULL) { mutt_perror ("fopen"); rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return -1; } @@ -1560,14 +1561,14 @@ int autoview_handler (BODY *a, STATE *s) if(!piped) { safe_fclose (&fpin); - thepid = mutt_create_filter (command, NULL, &fpout, &fperr); + thepid = mutt_create_filter (command->data, NULL, &fpout, &fperr); } else { unlink (tempfile); fflush (fpin); rewind (fpin); - thepid = mutt_create_filter_fd (command, NULL, &fpout, &fperr, + thepid = mutt_create_filter_fd (command->data, NULL, &fpout, &fperr, fileno(fpin), -1, -1); } @@ -1577,7 +1578,7 @@ int autoview_handler (BODY *a, STATE *s) if (s->flags & M_DISPLAY) { state_mark_attach (s); - state_printf (s, _("[-- Can't run %s. --]\n"), command); + state_printf (s, _("[-- Can't run %s. --]\n"), command->data); } rc = -1; goto bail; @@ -1596,7 +1597,7 @@ int autoview_handler (BODY *a, STATE *s) if (s->flags & M_DISPLAY) { state_mark_attach (s); - state_printf (s, _("[-- Autoview stderr of %s --]\n"), command); + state_printf (s, _("[-- Autoview stderr of %s --]\n"), command->data); } state_puts (s->prefix, s); @@ -1618,7 +1619,7 @@ int autoview_handler (BODY *a, STATE *s) { state_mark_attach (s); state_printf (s, _("[-- Autoview stderr of %s --]\n"), - command); + command->data); } state_puts (buffer, s); @@ -1640,6 +1641,7 @@ int autoview_handler (BODY *a, STATE *s) mutt_clear_error (); } rfc1524_free_entry (&entry); + mutt_buffer_free (&command); return rc; } Index: init.c =================================================================== RCS file: /home/roessler/cvs/mutt/init.c,v retrieving revision 3.55 diff -p -u -r3.55 init.c --- init.c 6 Jun 2006 23:58:10 -0000 3.55 +++ init.c 11 Jun 2006 13:54:48 -0000 @@ -1821,6 +1821,11 @@ static int parse_set (BUFFER *tmp, BUFFE } else if (DTYPE (MuttVars[idx].type) == DT_PATH) { + if ((tmp->dptr - tmp->data) >= sizeof (scratch)) + { + strfcpy (err->data, _("Path too long."), err->dsize); + return -1; + } strfcpy (scratch, tmp->data, sizeof (scratch)); mutt_expand_path (scratch, sizeof (scratch)); *((char **) MuttVars[idx].data) = safe_strdup (scratch); @@ -2207,6 +2212,11 @@ static int parse_source (BUFFER *tmp, BU strfcpy (err->data, _("source: too many arguments"), err->dsize); return (-1); } + if ((tmp->dptr - tmp->data) >= sizeof (path)) + { + strfcpy (err->data, _("source: too long filename"), err->dsize); + return -1; + } strfcpy (path, tmp->data, sizeof (path)); mutt_expand_path (path, sizeof (path)); return (source_rc (path, err)); Index: keymap.c =================================================================== RCS file: /home/roessler/cvs/mutt/keymap.c,v retrieving revision 3.17 diff -p -u -r3.17 keymap.c --- keymap.c 17 Sep 2005 20:46:10 -0000 3.17 +++ keymap.c 11 Jun 2006 13:54:49 -0000 @@ -508,7 +508,7 @@ char *km_keyname (int c) snprintf (buf, sizeof (buf), "\\%d%d%d", c >> 6, (c >> 3) & 7, c & 7); } else if (c >= KEY_F0 && c < KEY_F(256)) /* this maximum is just a guess */ - sprintf (buf, "", c - KEY_F0); + snprintf (buf, sizeof (buf), "", c - KEY_F0); else if (IsPrint (c)) snprintf (buf, sizeof (buf), "%c", (unsigned char) c); else Index: main.c =================================================================== RCS file: /home/roessler/cvs/mutt/main.c,v retrieving revision 3.35 diff -p -u -r3.35 main.c --- main.c 28 Apr 2006 08:35:03 -0000 3.35 +++ main.c 11 Jun 2006 13:54:49 -0000 @@ -578,6 +578,11 @@ int main (int argc, char **argv) break; case 'f': + if (strlen (optarg) >= sizeof (folder)) + { + fprintf (stderr, _("-f: too long: %s\n"), optarg); + exit (1); + } strfcpy (folder, optarg, sizeof (folder)); explicit_folder = 1; break; @@ -825,6 +830,13 @@ int main (int argc, char **argv) { char path[_POSIX_PATH_MAX]; + if (strlen (infile) >= sizeof (path)) + { + if (!option (OPTNOCURSES)) + mutt_endwin (NULL); + fputs (_("Infile: too long filename.\n"), stderr); + exit (1); + } strfcpy (path, infile, sizeof (path)); mutt_expand_path (path, sizeof (path)); if ((fin = fopen (path, "r")) == NULL) Index: mutt_socket.c =================================================================== RCS file: /home/roessler/cvs/mutt/mutt_socket.c,v retrieving revision 3.17 diff -p -u -r3.17 mutt_socket.c --- mutt_socket.c 26 May 2006 16:38:17 -0000 3.17 +++ mutt_socket.c 11 Jun 2006 13:54:50 -0000 @@ -249,13 +249,15 @@ CONNECTION* mutt_conn_find (const CONNEC { CONNECTION* conn; ciss_url_t url; - char hook[LONG_STRING]; + BUFFER *hook = NULL; /* account isn't actually modified, since url isn't either */ mutt_account_tourl ((ACCOUNT*) account, &url); url.path = NULL; - url_ciss_tostring (&url, hook, sizeof (hook), 0); - mutt_account_hook (hook); + hook = mutt_buffer_size (hook, LONG_STRING); + url_ciss_tostring (&url, hook, 0); + mutt_account_hook (hook->data); + mutt_buffer_free (&hook); conn = start ? start->next : Connections; while (conn) Index: pop.c =================================================================== RCS file: /home/roessler/cvs/mutt/pop.c,v retrieving revision 3.9 diff -p -u -r3.9 pop.c --- pop.c 21 Oct 2005 04:35:37 -0000 3.9 +++ pop.c 11 Jun 2006 13:54:51 -0000 @@ -68,7 +68,12 @@ static int pop_read_header (POP_DATA *po ret = pop_query (pop_data, buf, sizeof (buf)); if (ret == 0) { - sscanf (buf, "+OK %d %ld", &index, &length); + if (sscanf (buf, "+OK %d %ld", &index, &length) != 2) + { + mutt_error (_("unknown error")); + ret = -2; + goto finish; + } snprintf (buf, sizeof (buf), "TOP %d 0\r\n", h->refno); ret = pop_fetch_data (pop_data, buf, NULL, fetch_message, f); @@ -120,6 +125,7 @@ static int pop_read_header (POP_DATA *po } } +finish: fclose (f); unlink (tempfile); return ret; @@ -132,7 +138,8 @@ static int fetch_uidl (char *line, void CONTEXT *ctx = (CONTEXT *)data; POP_DATA *pop_data = (POP_DATA *)ctx->data; - sscanf (line, "%d %s", &index, line); + if (sscanf (line, "%d %s", &index, line) != 2) + return -2; for (i = 0; i < ctx->msgcount; i++) if (!mutt_strcmp (line, ctx->hdrs[i]->data)) break; @@ -237,7 +244,7 @@ static int pop_fetch_headers (CONTEXT *c int pop_open_mailbox (CONTEXT *ctx) { int ret; - char buf[LONG_STRING]; + BUFFER *buf = NULL; CONNECTION *conn; ACCOUNT acct; POP_DATA *pop_data; @@ -252,13 +259,18 @@ int pop_open_mailbox (CONTEXT *ctx) mutt_account_tourl (&acct, &url); url.path = NULL; - url_ciss_tostring (&url, buf, sizeof (buf), 0); + buf = mutt_buffer_size (buf, LONG_STRING); + url_ciss_tostring (&url, buf, 0); conn = mutt_conn_find (NULL, &acct); if (!conn) + { + mutt_buffer_free (&buf); return -1; + } FREE (&ctx->path); - ctx->path = safe_strdup (buf); + ctx->path = buf->data; + FREE (&buf); pop_data = safe_calloc (1, sizeof (POP_DATA)); pop_data->conn = conn; @@ -595,7 +607,11 @@ void pop_fetch_mail (void) goto finish; } - sscanf (buffer, "+OK %d %d", &msgs, &bytes); + if (sscanf (buffer, "+OK %d %d", &msgs, &bytes) != 2) + { + mutt_error (_("unknown error")); + goto finish; + } /* only get unread messages */ if (msgs > 0 && option (OPTPOPLAST)) @@ -605,7 +621,11 @@ void pop_fetch_mail (void) if (ret == -1) goto fail; if (ret == 0) - sscanf (buffer, "+OK %d", &last); + if (sscanf (buffer, "+OK %d", &last) != 1) + { + mutt_error (_("unknown error")); + goto finish; + } } if (msgs <= last) Index: pop_auth.c =================================================================== RCS file: /home/roessler/cvs/mutt/pop_auth.c,v retrieving revision 3.7 diff -p -u -r3.7 pop_auth.c --- pop_auth.c 17 Sep 2005 20:46:11 -0000 3.7 +++ pop_auth.c 11 Jun 2006 13:54:51 -0000 @@ -78,7 +78,8 @@ static pop_auth_res_t pop_auth_sasl (POP mutt_message _("Authenticating (SASL)..."); - snprintf (buf, sizeof (buf), "AUTH %s", mech); + if (snprintf (buf, sizeof (buf), "AUTH %s", mech) >= sizeof (buf)) + dprint (1, (debugfile, "pop_auth_sasl: mech too long - truncated\n")); olen = strlen (buf); /* looping protocol */ @@ -174,9 +175,7 @@ static pop_auth_res_t pop_auth_apop (POP { MD5_CTX mdContext; unsigned char digest[16]; - char hash[33]; - char buf[LONG_STRING]; - int i; + char buf[10 + sizeof (pop_data->conn->account.user) + sizeof (digest)*2]; if (!pop_data->timestamp) return POP_A_UNAVAIL; @@ -191,11 +190,15 @@ static pop_auth_res_t pop_auth_apop (POP strlen (pop_data->conn->account.pass)); MD5Final (digest, &mdContext); - for (i = 0; i < sizeof (digest); i++) - sprintf (hash + 2 * i, "%02x", digest[i]); - /* Send APOP command to server */ - snprintf (buf, sizeof (buf), "APOP %s %s\r\n", pop_data->conn->account.user, hash); + if (snprintf (buf, sizeof (buf), + "APOP %s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\r\n", + pop_data->conn->account.user, digest[0], + digest[1], digest[2], digest[3], digest[4], digest[5], + digest[6], digest[7], digest[8], digest[9], digest[10], + digest[11], digest[12], digest[13], digest[14], digest[15]) + >= sizeof (buf)) + return POP_A_FAILURE; switch (pop_query (pop_data, buf, sizeof (buf))) { Index: pop_lib.c =================================================================== RCS file: /home/roessler/cvs/mutt/pop_lib.c,v retrieving revision 3.14 diff -p -u -r3.14 pop_lib.c --- pop_lib.c 26 May 2006 16:38:17 -0000 3.14 +++ pop_lib.c 11 Jun 2006 13:54:52 -0000 @@ -360,7 +360,12 @@ int pop_open_connection (POP_DATA *pop_d return ret; } - sscanf (buf, "+OK %u %u", &n, &size); + if (sscanf (buf, "+OK %u %u", &n, &size) != 2) + { + mutt_error (_("unknown error")); + mutt_sleep (1); + return -2; + } pop_data->size = size; return 0; @@ -461,6 +466,10 @@ int pop_fetch_data (POP_DATA *pop_data, long pos = 0; size_t lenbuf = 0; +#ifdef DEBUG + if (mutt_strlen (query) >= sizeof (buf)) + dprint (1, (debugfile, "pop_fetch_data: query truncated: [%s]\n", query)); +#endif strfcpy (buf, query, sizeof (buf)); ret = pop_query (pop_data, buf, sizeof (buf)); if (ret < 0) @@ -516,7 +525,8 @@ static int check_uidl (char *line, void unsigned int index; CONTEXT *ctx = (CONTEXT *)data; - sscanf (line, "%u %s", &index, line); + if (sscanf (line, "%u %s", &index, line) != 2) + return -2; for (i = 0; i < ctx->msgcount; i++) { if (!mutt_strcmp (ctx->hdrs[i]->data, line)) Index: rfc1524.c =================================================================== RCS file: /home/roessler/cvs/mutt/rfc1524.c,v retrieving revision 3.9 diff -p -u -r3.9 rfc1524.c --- rfc1524.c 18 May 2006 17:35:30 -0000 3.9 +++ rfc1524.c 11 Jun 2006 13:54:52 -0000 @@ -56,37 +56,41 @@ * and 1 if the command works on a pipe. */ int rfc1524_expand_command (BODY *a, char *filename, char *_type, - char *command, int clen) + BUFFER *command) { - int x=0,y=0; int needspipe = TRUE; - char buf[LONG_STRING]; + BUFFER *buf = NULL; char type[LONG_STRING]; + char tmp_fn[_POSIX_PATH_MAX]; + size_t fnlen; strfcpy (type, _type, sizeof (type)); if (option (OPTMAILCAPSANITIZE)) mutt_sanitize_filename (type, 0); - while (command[x] && xdsize); + + command->dptr = command->data; + while (*command->dptr) { - if (command[x] == '\\') { - x++; - buf[y++] = command[x++]; + if (*command->dptr == '\\') { + command->dptr++; + mutt_buffer_add (buf, command->dptr++, 1); } - else if (command[x] == '%') + else if (*command->dptr == '%') { - x++; - if (command[x] == '{') + command->dptr++; + if (*command->dptr == '{') { char param[STRING]; char pvalue[STRING]; char *_pvalue; int z = 0; - x++; - while (command[x] && command[x] != '}' && zdptr++; + while (*command->dptr && *command->dptr != '}' && zdptr++); param[z] = '\0'; _pvalue = mutt_get_parameter (param, a->parameter); @@ -94,24 +98,30 @@ int rfc1524_expand_command (BODY *a, cha if (option (OPTMAILCAPSANITIZE)) mutt_sanitize_filename (pvalue, 0); - y += mutt_quote_filename (buf + y, sizeof (buf) - y, pvalue); + fnlen = mutt_quote_filename (tmp_fn, sizeof (tmp_fn), pvalue); + mutt_buffer_add (buf, tmp_fn, fnlen); } - else if (command[x] == 's' && filename != NULL) + else if (*command->dptr == 's' && filename != NULL) { - y += mutt_quote_filename (buf + y, sizeof (buf) - y, filename); + fnlen = mutt_quote_filename (tmp_fn, sizeof (tmp_fn), filename); + mutt_buffer_add (buf, tmp_fn, fnlen); needspipe = FALSE; } - else if (command[x] == 't') + else if (*command->dptr == 't') { - y += mutt_quote_filename (buf + y, sizeof (buf) - y, type); + fnlen = mutt_quote_filename (tmp_fn, sizeof (tmp_fn), type); + mutt_buffer_add (buf, tmp_fn, fnlen); } - x++; + command->dptr++; } else - buf[y++] = command[x++]; + mutt_buffer_add (buf, command->dptr++, 1); } - buf[y] = '\0'; - strfcpy (command, buf, clen); + FREE (&command->data); + command->data = buf->data; + command->dsize = buf->dsize; + command->dptr = buf->dptr; + FREE (&buf); return needspipe; } @@ -290,20 +300,22 @@ static int rfc1524_mailcap_parse (BODY * * if this is the right entry. */ char *test_command = NULL; - size_t len; if (get_field_text (field + 4, &test_command, type, filename, line) && test_command) { - len = mutt_strlen (test_command) + STRING; - safe_realloc (&test_command, len); - rfc1524_expand_command (a, a->filename, type, test_command, len); - if (mutt_system (test_command)) + BUFFER *tcommand = NULL; + tcommand = mutt_buffer_init (tcommand); + tcommand->data = test_command; + tcommand->dsize = strlen (test_command); + tcommand->dptr = tcommand->data + (tcommand->dsize++); + rfc1524_expand_command (a, a->filename, type, tcommand); + if (mutt_system (tcommand->data)) { /* a non-zero exit code means test failed */ found = FALSE; } - FREE (&test_command); + mutt_buffer_free (&tcommand); } } } /* while (ch) */ Index: rfc2231.c =================================================================== RCS file: /home/roessler/cvs/mutt/rfc2231.c,v retrieving revision 3.8 diff -p -u -r3.8 rfc2231.c --- rfc2231.c 18 May 2006 17:35:30 -0000 3.8 +++ rfc2231.c 11 Jun 2006 13:54:53 -0000 @@ -355,7 +355,7 @@ int rfc2231_encode_string (char **pd) if (*s < 0x20 || *s >= 0x7f || strchr (MimeSpecials, *s) || strchr ("*'%", *s)) { - sprintf (t, "%%%02X", (unsigned char)*s); + sprintf (t, "%%%02X", (unsigned char)*s); /* __SPRINTF_CHECKED__ */ t += 3; } else Index: url.c =================================================================== RCS file: /home/roessler/cvs/mutt/url.c,v retrieving revision 3.9 diff -p -u -r3.9 url.c --- url.c 17 Sep 2005 20:46:11 -0000 3.9 +++ url.c 11 Jun 2006 13:54:53 -0000 @@ -171,37 +171,32 @@ int url_parse_ciss (ciss_url_t *ciss, ch /* url_ciss_tostring: output the URL string for a given CISS object. */ -int url_ciss_tostring (ciss_url_t* ciss, char* dest, size_t len, int flags) +int url_ciss_tostring (ciss_url_t* ciss, BUFFER* dest, int flags) { - long l; - if (ciss->scheme == U_UNKNOWN) return -1; - snprintf (dest, len, "%s:", mutt_getnamebyvalue (ciss->scheme, UrlMap)); + mutt_buffer_printf (dest, "%s:", mutt_getnamebyvalue (ciss->scheme, UrlMap)); if (ciss->host) { - safe_strcat (dest, len, "//"); - len -= (l = strlen (dest)); dest += l; + mutt_buffer_add (dest, "//", 2); if (ciss->user) { if (flags & U_DECODE_PASSWD && ciss->pass) - snprintf (dest, len, "%s:%s@", ciss->user, ciss->pass); + mutt_buffer_printf (dest, "%s:%s@", ciss->user, ciss->pass); else - snprintf (dest, len, "%s@", ciss->user); - - len -= (l = strlen (dest)); dest += l; + mutt_buffer_printf (dest, "%s@", ciss->user); } if (ciss->port) - snprintf (dest, len, "%s:%hu/", ciss->host, ciss->port); + mutt_buffer_printf (dest, "%s:%hu/", ciss->host, ciss->port); else - snprintf (dest, len, "%s/", ciss->host); + mutt_buffer_printf (dest, "%s/", ciss->host); } if (ciss->path) - safe_strcat (dest, len, ciss->path); + mutt_buffer_addstr (dest, ciss->path); return 0; } Index: imap/auth_cram.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/auth_cram.c,v retrieving revision 3.7 diff -p -u -r3.7 auth_cram.c --- imap/auth_cram.c 10 Dec 2005 07:01:36 -0000 3.7 +++ imap/auth_cram.c 11 Jun 2006 13:54:53 -0000 @@ -37,7 +37,9 @@ static void hmac_md5 (const char* passwo /* imap_auth_cram_md5: AUTH=CRAM-MD5 support. */ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata, const char* method) { - char ibuf[LONG_STRING*2], obuf[LONG_STRING]; + BUFFER *ibuf = NULL; + char *obuf; + size_t olen; unsigned char hmac_response[MD5_DIGEST_LEN]; int len; int rc; @@ -67,13 +69,18 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP if (rc != IMAP_CMD_RESPOND) { - dprint (1, (debugfile, "Invalid response from server: %s\n", ibuf)); + dprint (1, (debugfile, "Invalid response from server: %s\n", idata->buf)); goto bail; } + /* allocate enough to base64decode and to sprintf hmac_response */ + olen = (idata->blen > sizeof (idata->conn->account.user) + 2 * sizeof (hmac_response) + 2) ? + idata->blen : sizeof (idata->conn->account.user) + 2 * sizeof (hmac_response) + 2; + obuf = safe_malloc (olen); if ((len = mutt_from_base64 (obuf, idata->buf + 2)) == -1) { dprint (1, (debugfile, "Error decoding base64 response.\n")); + FREE (&obuf); goto bail; } @@ -93,7 +100,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP */ hmac_md5 (idata->conn->account.pass, obuf, hmac_response); /* dubious optimisation I saw elsewhere: make the whole string in one call */ - snprintf (obuf, sizeof (obuf), + snprintf (obuf, olen, "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", idata->conn->account.user, hmac_response[0], hmac_response[1], hmac_response[2], hmac_response[3], @@ -102,14 +109,14 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP hmac_response[12], hmac_response[13], hmac_response[14], hmac_response[15]); dprint(2, (debugfile, "CRAM response: %s\n", obuf)); - /* XXX - ibuf must be long enough to store the base64 encoding of obuf, - * plus the additional debris - */ - - mutt_to_base64 ((unsigned char*) ibuf, (unsigned char*) obuf, strlen (obuf), - sizeof (ibuf) - 2); - safe_strcat (ibuf, sizeof (ibuf), "\r\n"); - mutt_socket_write (idata->conn, ibuf); + /* Maximum length of base64 encoded data is (4/3)*strlen(obuf)+5 */ + olen = strlen (obuf); + ibuf = mutt_buffer_size (ibuf, olen + olen / 3 + 11); + mutt_to_base64 (ibuf, (unsigned char*) obuf, olen); + FREE (&obuf); + mutt_buffer_addstr (ibuf, "\r\n"); + mutt_socket_write (idata->conn, ibuf->data); + mutt_buffer_free (&ibuf); do rc = imap_cmd_step (idata); Index: imap/auth_gss.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/auth_gss.c,v retrieving revision 3.7 diff -p -u -r3.7 auth_gss.c --- imap/auth_gss.c 10 Dec 2005 07:01:36 -0000 3.7 +++ imap/auth_gss.c 11 Jun 2006 13:54:53 -0000 @@ -53,7 +53,8 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA gss_qop_t quality; int cflags; OM_uint32 maj_stat, min_stat; - char buf1[GSS_BUFSIZE], buf2[GSS_BUFSIZE], server_conf_flags; + BUFFER *buf1 = NULL; + char *buf2, *server_conf_flags; unsigned long buf_size; int rc; @@ -64,14 +65,16 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA return IMAP_AUTH_FAILURE; /* get an IMAP service ticket for the server */ - snprintf (buf1, sizeof (buf1), "imap@%s", idata->conn->account.host); - request_buf.value = buf1; - request_buf.length = strlen (buf1) + 1; + buf1 = mutt_buffer_size (buf1, GSS_BUFSIZE); + mutt_buffer_printf (buf1, "imap@%s", idata->conn->account.host); + request_buf.value = buf1->data; + request_buf.length = (buf1->dptr - buf1->data) + 1; maj_stat = gss_import_name (&min_stat, &request_buf, gss_nt_service_name, &target_name); if (maj_stat != GSS_S_COMPLETE) { - dprint (2, (debugfile, "Couldn't get service name for [%s]\n", buf1)); + dprint (2, (debugfile, "Couldn't get service name for [%s]\n", buf1->data)); + mutt_free_buffer (&buf1); return IMAP_AUTH_UNAVAIL; } #ifdef DEBUG @@ -97,6 +100,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA { dprint (1, (debugfile, "Error acquiring credentials - no TGT?\n")); gss_release_name (&min_stat, &target_name); + mutt_buffer_free (&buf1); return IMAP_AUTH_UNAVAIL; } @@ -113,18 +117,18 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA if (rc != IMAP_CMD_RESPOND) { - dprint (2, (debugfile, "Invalid response from server: %s\n", buf1)); + dprint (2, (debugfile, "Invalid response from server: %s\n", buf1->data)); gss_release_name (&min_stat, &target_name); goto bail; } /* now start the security context initialisation loop... */ dprint (2, (debugfile, "Sending credentials\n")); - mutt_to_base64 ((unsigned char*) buf1, send_token.value, send_token.length, - sizeof (buf1) - 2); + buf1->dptr = buf1->data; + mutt_to_base64 (buf1, send_token.value, send_token.length); gss_release_buffer (&min_stat, &send_token); - safe_strcat (buf1, sizeof (buf1), "\r\n"); - mutt_socket_write (idata->conn, buf1); + mutt_buffer_add (buf1, "\r\n", 2); + mutt_socket_write (idata->conn, buf1->data); while (maj_stat == GSS_S_CONTINUE_NEEDED) { @@ -156,11 +160,11 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA goto err_abort_cmd; } - mutt_to_base64 ((unsigned char*) buf1, send_token.value, - send_token.length, sizeof (buf1) - 2); + buf1->dptr = buf1->data; + mutt_to_base64 (buf1, send_token.value, send_token.length); gss_release_buffer (&min_stat, &send_token); - safe_strcat (buf1, sizeof (buf1), "\r\n"); - mutt_socket_write (idata->conn, buf1); + mutt_buffer_add (buf1, "\r\n", 2); + mutt_socket_write (idata->conn, buf1->data); } gss_release_name (&min_stat, &target_name); @@ -209,12 +213,13 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA /* agree to terms (hack!) */ buf_size = htonl (buf_size); /* not relevant without integrity/privacy */ - memcpy (buf1, &buf_size, 4); - buf1[0] = GSS_AUTH_P_NONE; + memcpy (buf1->data, &buf_size, 4); + buf1->data[0] = GSS_AUTH_P_NONE; /* server decides if principal can log in as user */ - strncpy (buf1 + 4, idata->conn->account.user, sizeof (buf1) - 4); - request_buf.value = buf1; + buf1->dptr = buf1->data + 4; request_buf.length = 4 + strlen (idata->conn->account.user) + 1; + mutt_buffer_add (buf1, idata->conn->account.user, request_buf.length - 5); + request_buf.value = buf1->data; maj_stat = gss_wrap (&min_stat, context, 0, GSS_C_QOP_DEFAULT, &request_buf, &cflags, &send_token); if (maj_stat != GSS_S_COMPLETE) @@ -223,12 +228,12 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA goto err_abort_cmd; } - mutt_to_base64 ((unsigned char*) buf1, send_token.value, send_token.length, - sizeof (buf1) - 2); + buf1->dptr = buf1->data; + mutt_to_base64 (buf1, send_token.value, send_token.length); dprint (2, (debugfile, "Requesting authorisation as %s\n", idata->conn->account.user)); - safe_strcat (buf1, sizeof (buf1), "\r\n"); - mutt_socket_write (idata->conn, buf1); + mutt_buffer_add (buf1, "\r\n", 2); + mutt_socket_write (idata->conn, buf1->data); /* Joy of victory or agony of defeat? */ do @@ -253,6 +258,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA * enough to flush its own credentials */ gss_release_buffer (&min_stat, &send_token); + mutt_buffer_free (&buf1); return IMAP_AUTH_SUCCESS; } else @@ -267,5 +273,6 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA bail: mutt_error _("GSSAPI authentication failed."); mutt_sleep (2); + mutt_buffer_free (&buf1); return IMAP_AUTH_FAILURE; } Index: imap/auth_login.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/auth_login.c,v retrieving revision 3.5 diff -p -u -r3.5 auth_login.c --- imap/auth_login.c 17 Sep 2005 20:46:11 -0000 3.5 +++ imap/auth_login.c 11 Jun 2006 13:54:53 -0000 @@ -29,8 +29,9 @@ /* imap_auth_login: Plain LOGIN support */ imap_auth_res_t imap_auth_login (IMAP_DATA* idata, const char* method) { - char q_user[SHORT_STRING], q_pass[SHORT_STRING]; - char buf[STRING]; + BUFFER *q_user = NULL; + BUFFER *q_pass = NULL; + BUFFER *buf = NULL; int rc; if (mutt_bit_isset (idata->capabilities, LOGINDISABLED)) @@ -46,8 +47,10 @@ imap_auth_res_t imap_auth_login (IMAP_DA mutt_message _("Logging in..."); - imap_quote_string (q_user, sizeof (q_user), idata->conn->account.user); - imap_quote_string (q_pass, sizeof (q_pass), idata->conn->account.pass); + q_user = mutt_buffer_size (q_user, SHORT_STRING); + imap_quote_string (q_user, idata->conn->account.user); + q_pass = mutt_buffer_size (q_pass, SHORT_STRING); + imap_quote_string (q_pass, idata->conn->account.pass); #ifdef DEBUG /* don't print the password unless we're at the ungodly debugging level @@ -58,8 +61,13 @@ imap_auth_res_t imap_auth_login (IMAP_DA idata->conn->account.user)); #endif - snprintf (buf, sizeof (buf), "LOGIN %s %s", q_user, q_pass); - rc = imap_exec (idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS); + buf = mutt_buffer_size (buf, STRING); + mutt_buffer_printf (buf, "LOGIN %s %s", q_user->data, q_pass->data); + rc = imap_exec (idata, buf->data, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS); + + mutt_buffer_free (&buf); + mutt_buffer_free (&q_user); + mutt_buffer_free (&q_pass); if (!rc) return IMAP_AUTH_SUCCESS; Index: imap/auth_sasl.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/auth_sasl.c,v retrieving revision 3.15 diff -p -u -r3.15 auth_sasl.c --- imap/auth_sasl.c 18 Apr 2006 23:22:30 -0000 3.15 +++ imap/auth_sasl.c 11 Jun 2006 13:54:54 -0000 @@ -96,7 +96,8 @@ imap_auth_res_t imap_auth_sasl (IMAP_DAT mutt_message (_("Authenticating (%s)..."), mech); - snprintf (buf, sizeof (buf), "AUTHENTICATE %s", mech); + if (snprintf (buf, sizeof (buf), "AUTHENTICATE %s", mech) >= sizeof (buf)) + dprint (1, (debugfile, "imap_auth_sasl: mech too long. [%s]\n", mech)); if (mutt_bit_isset (idata->capabilities, SASL_IR) && client_start) { len = mutt_strlen (buf); @@ -172,8 +173,8 @@ imap_auth_res_t imap_auth_sasl (IMAP_DAT if (irc == IMAP_CMD_RESPOND) { - strfcpy (buf + olen, "\r\n", sizeof (buf) - olen); mutt_socket_write (idata->conn, buf); + mutt_socket_write (idata->conn, "\r\n"); } /* If SASL has errored out, send an abort string to the server */ Index: imap/browse.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/browse.c,v retrieving revision 3.17 diff -p -u -r3.17 browse.c --- imap/browse.c 15 Jan 2006 21:37:03 -0000 3.17 +++ imap/browse.c 11 Jun 2006 13:54:54 -0000 @@ -35,7 +35,7 @@ static int browse_add_list_result (IMAP_ static void imap_add_folder (char delim, char *folder, int noselect, int noinferiors, struct browser_state *state, short isparent); static int compare_names(struct folder_file *a, struct folder_file *b); -static int browse_get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen, +static int browse_get_namespace (IMAP_DATA *idata, BUFFER *nsbuf, IMAP_NAMESPACE_INFO *nsi, int nsilen, int *nns); static int browse_verify_namespace (IMAP_DATA* idata, IMAP_NAMESPACE_INFO* nsi, int nns); @@ -46,14 +46,13 @@ int imap_browse (char* path, struct brow { IMAP_DATA* idata; IMAP_LIST list; - char buf[LONG_STRING]; - char buf2[LONG_STRING]; - char nsbuf[LONG_STRING]; - char mbox[LONG_STRING]; + BUFFER *buf = NULL; + BUFFER *buf2 = NULL; + BUFFER *nsbuf = NULL; + BUFFER *mbox = NULL; char list_cmd[5]; IMAP_NAMESPACE_INFO nsi[16]; int home_namespace = 0; - int n; int i; int nsup; char ctmp; @@ -75,15 +74,19 @@ int imap_browse (char* path, struct brow if (!(idata = imap_conn_find (&(mx.account), 0))) goto fail; + buf = mutt_buffer_size (buf, LONG_STRING); + mbox = mutt_buffer_size (mbox, LONG_STRING); + nsbuf = mutt_buffer_size (nsbuf, LONG_STRING); + if (!mx.mbox) { + /* Do not replace "" with "INBOX" here */ home_namespace = 1; - mbox[0] = '\0'; /* Do not replace "" with "INBOX" here */ mx.mbox = safe_strdup(ImapHomeNamespace); if (mutt_bit_isset(idata->capabilities,NAMESPACE)) { mutt_message _("Getting namespaces..."); - if (browse_get_namespace (idata, nsbuf, sizeof (nsbuf), + if (browse_get_namespace (idata, nsbuf, nsi, sizeof (nsi), &nns) != 0) goto fail; if (browse_verify_namespace (idata, nsi, nns) != 0) @@ -97,21 +100,22 @@ int imap_browse (char* path, struct brow if (mx.mbox && mx.mbox[0] != '\0') { int rc; - imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox)); - imap_munge_mbox_name (buf, sizeof (buf), mbox); - imap_unquote_string(buf); /* As kludgy as it gets */ - mbox[sizeof (mbox) - 1] = '\0'; - strncpy (mbox, buf, sizeof (mbox) - 1); - n = mutt_strlen (mbox); + imap_fix_path (idata, mx.mbox, mbox); + buf->dptr = buf->data; + imap_munge_mbox_name (buf, mbox->data); + imap_unquote_string(buf->data); /* As kludgy as it gets */ + mbox->dptr = mbox->data; + mutt_buffer_addstr (mbox, buf->data); - dprint (3, (debugfile, "imap_browse: mbox: %s\n", mbox)); + dprint (3, (debugfile, "imap_browse: mbox: %s\n", mbox->data)); /* if our target exists and has inferiors, enter it if we * aren't already going to */ - if (mbox[n-1] != idata->delim) + if (*(mbox->dptr - 1) != idata->delim) { - snprintf (buf, sizeof (buf), "%s \"\" \"%s\"", list_cmd, mbox); - imap_cmd_start (idata, buf); + buf->dptr = buf->data; + mutt_buffer_printf (buf, "%s \"\" \"%s\"", list_cmd, mbox->data); + imap_cmd_start (idata, buf->data); idata->cmddata = &list; do { @@ -120,12 +124,8 @@ int imap_browse (char* path, struct brow if (rc == IMAP_CMD_CONTINUE && list.name) { if (!list.noinferiors && list.name[0] && - !imap_mxcmp (list.name, mbox) && - (n = strlen (mbox)) < sizeof (mbox) - 1) - { - mbox[n++] = list.delim; - mbox[n] = '\0'; - } + !imap_mxcmp (list.name, mbox->data)) + mutt_buffer_addch (mbox, list.delim); } } while (rc == IMAP_CMD_CONTINUE); @@ -133,14 +133,15 @@ int imap_browse (char* path, struct brow } /* if we're descending a folder, mark it as current in browser_state */ - if (mbox[n-1] == list.delim) + if (*(mbox->dptr - 1) == list.delim) { /* don't show parents in the home namespace */ if (!home_namespace) showparents = 1; - imap_qualify_path (buf, sizeof (buf), &mx, mbox); - state->folder = safe_strdup (buf); - n--; + buf->dptr = buf->data; + imap_qualify_path (buf, &mx, mbox->data); + state->folder = safe_strdup (buf->data); + mbox->dptr--; } /* Find superiors to list @@ -149,44 +150,46 @@ int imap_browse (char* path, struct brow * and tack on delimiter ourselves. * Further note: UW-IMAP servers return nothing when asked for * NAMESPACES without delimiters at the end. Argh! */ - for (n--; n >= 0 && mbox[n] != list.delim ; n--); - if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */ + for (mbox->dptr--; mbox->dptr >= mbox->data && *mbox->dptr != list.delim ; mbox->dptr--); + if (mbox->dptr > mbox->data) /* "aaaa/bbbb/" -> "aaaa" */ { /* forget the check, it is too delicate (see above). Have we ever * had the parent not exist? */ - ctmp = mbox[n]; - mbox[n] = '\0'; + ctmp = *mbox->dptr; + *mbox->dptr = '\0'; if (showparents) { - dprint (3, (debugfile, "imap_init_browse: adding parent %s\n", mbox)); - imap_add_folder (list.delim, mbox, 1, 0, state, 1); + dprint (3, (debugfile, "imap_init_browse: adding parent %s\n", mbox->data)); + imap_add_folder (list.delim, mbox->data, 1, 0, state, 1); } /* if our target isn't a folder, we are in our superior */ if (!state->folder) { /* store folder with delimiter */ - mbox[n++] = ctmp; - ctmp = mbox[n]; - mbox[n] = '\0'; - imap_qualify_path (buf, sizeof (buf), &mx, mbox); - state->folder = safe_strdup (buf); + *mbox->dptr = ctmp; + ctmp = *mbox->dptr++; + *mbox->dptr = '\0'; + buf->dptr = buf->data; + imap_qualify_path (buf, &mx, mbox->data); + state->folder = safe_strdup (buf->data); } - mbox[n] = ctmp; + *mbox->dptr = ctmp; } /* "/bbbb/" -> add "/", "aaaa/" -> add "" */ else { char relpath[2]; /* folder may be "/" */ - snprintf (relpath, sizeof (relpath), "%c" , n < 0 ? '\0' : idata->delim); + snprintf (relpath, sizeof (relpath), "%c" , mbox->dptr < mbox->data ? '\0' : idata->delim); if (showparents) imap_add_folder (idata->delim, relpath, 1, 0, state, 1); if (!state->folder) { - imap_qualify_path (buf, sizeof (buf), &mx, relpath); - state->folder = safe_strdup (buf); + buf->dptr = buf->data; + imap_qualify_path (buf, &mx, relpath); + state->folder = safe_strdup (buf->data); } } } @@ -194,11 +197,12 @@ int imap_browse (char* path, struct brow /* no namespace, no folder: set folder to host only */ if (!state->folder) { - imap_qualify_path (buf, sizeof (buf), &mx, NULL); - state->folder = safe_strdup (buf); + buf->dptr = buf->data; + imap_qualify_path (buf, &mx, NULL); + state->folder = safe_strdup (buf->data); } - if (home_namespace && mbox[0] != '\0') + if (home_namespace && *mbox->data != '\0') { /* Listing the home namespace, so INBOX should be included. Home * namespace is not "", so we have to list it explicitly. We ask the @@ -210,12 +214,17 @@ int imap_browse (char* path, struct brow nsup = state->entrylen; - dprint (3, (debugfile, "imap_browse: Quoting mailbox scan: %s -> ", mbox)); - snprintf (buf, sizeof (buf), "%s%%", mbox); - imap_quote_string (buf2, sizeof (buf2), buf); - dprint (3, (debugfile, "%s\n", buf2)); - snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, buf2); - if (browse_add_list_result (idata, buf, state, 0)) + dprint (3, (debugfile, "imap_browse: Quoting mailbox scan: %s -> ", mbox->data)); + buf->dptr = buf->data; + mutt_buffer_addstr (buf, mbox->data); + mutt_buffer_addch (buf, '%'); + buf2 = mutt_buffer_size (buf2, LONG_STRING); + imap_quote_string (buf2, buf->data); + dprint (3, (debugfile, "%s\n", buf2->data)); + buf->dptr = buf->data; + mutt_buffer_printf (buf, "%s \"\" %s", list_cmd, buf2->data); + mutt_buffer_free (&buf2); + if (browse_add_list_result (idata, buf->data, state, 0)) goto fail; if (!state->entrylen) @@ -243,12 +252,18 @@ int imap_browse (char* path, struct brow set_option (OPTIMAPCHECKSUBSCRIBED); FREE (&mx.mbox); + mutt_buffer_free (&nsbuf); + mutt_buffer_free (&buf); + mutt_buffer_free (&mbox); return 0; fail: if (save_lsub) set_option (OPTIMAPCHECKSUBSCRIBED); FREE (&mx.mbox); + mutt_buffer_free (&nsbuf); + mutt_buffer_free (&buf); + mutt_buffer_free (&mbox); return -1; } @@ -257,7 +272,7 @@ int imap_mailbox_create (const char* fol { IMAP_DATA* idata; IMAP_MBOX mx; - char buf[LONG_STRING]; + BUFFER *buf = NULL; short n; if (imap_parse_path (folder, &mx) < 0) @@ -272,38 +287,39 @@ int imap_mailbox_create (const char* fol dprint (1, (debugfile, "imap_mailbox_create: Couldn't find open connection to %s", mx.account.host)); goto fail; } - - strfcpy (buf, NONULL (mx.mbox), sizeof (buf)); + + n = mutt_strlen (mx.mbox); + buf = mutt_buffer_size (buf, n + LONG_STRING); + mutt_buffer_add (buf, NONULL (mx.mbox), n); /* append a delimiter if necessary */ - n = mutt_strlen (buf); - if (n && (n < sizeof (buf) - 1) && (buf[n-1] != idata->delim)) - { - buf[n++] = idata->delim; - buf[n] = '\0'; - } + if (n && (*(buf->dptr - 1) != idata->delim)) + mutt_buffer_addch (buf, idata->delim); - if (mutt_get_field (_("Create mailbox: "), buf, sizeof (buf), M_FILE) < 0) + if (mutt_get_field (_("Create mailbox: "), buf->data, buf->dsize, M_FILE) < 0) goto fail; - if (!mutt_strlen (buf)) + if (!*buf->data) { mutt_error (_("Mailbox must have a name.")); mutt_sleep(1); + mutt_buffer_free (&buf); goto fail; } - if (imap_create_mailbox (idata, buf) < 0) + if (imap_create_mailbox (idata, buf->data) < 0) goto fail; mutt_message _("Mailbox created."); mutt_sleep (0); FREE (&mx.mbox); + mutt_buffer_free (&buf); return 0; fail: FREE (&mx.mbox); + mutt_buffer_free (&buf); return -1; } @@ -399,8 +415,8 @@ static int browse_add_list_result (IMAP_ static void imap_add_folder (char delim, char *folder, int noselect, int noinferiors, struct browser_state *state, short isparent) { - char tmp[LONG_STRING]; - char relpath[LONG_STRING]; + BUFFER *tmp = NULL; + BUFFER *relpath = NULL; IMAP_MBOX mx; if (imap_parse_path (state->folder, &mx)) @@ -416,35 +432,37 @@ static void imap_add_folder (char delim, (sizeof (struct folder_file) * (state->entrymax - state->entrylen))); } + relpath = mutt_buffer_size (relpath, LONG_STRING); /* render superiors as unix-standard ".." */ if (isparent) - strfcpy (relpath, "../", sizeof (relpath)); + mutt_buffer_add (relpath, "../", 3); /* strip current folder from target, to render a relative path */ else if (!mutt_strncmp (mx.mbox, folder, mutt_strlen (mx.mbox))) - strfcpy (relpath, folder + mutt_strlen (mx.mbox), sizeof (relpath)); + mutt_buffer_addstr (relpath, folder + mutt_strlen (mx.mbox)); else - strfcpy (relpath, folder, sizeof (relpath)); + mutt_buffer_addstr (relpath, folder); /* apply filemask filter. This should really be done at menu setup rather * than at scan, since it's so expensive to scan. But that's big changes * to browser.c */ - if (!((regexec (Mask.rx, relpath, 0, NULL, 0) == 0) ^ Mask.not)) + if (!((regexec (Mask.rx, relpath->data, 0, NULL, 0) == 0) ^ Mask.not)) { FREE (&mx.mbox); + mutt_buffer_free (&relpath); return; } - imap_qualify_path (tmp, sizeof (tmp), &mx, folder); - (state->entry)[state->entrylen].name = safe_strdup (tmp); + tmp = mutt_buffer_size (tmp, LONG_STRING); + imap_qualify_path (tmp, &mx, folder); + (state->entry)[state->entrylen].name = tmp->data; + FREE (&tmp); /* mark desc with delim in browser if it can have subfolders */ - if (!isparent && !noinferiors && strlen (relpath) < sizeof (relpath) - 1) - { - relpath[strlen (relpath) + 1] = '\0'; - relpath[strlen (relpath)] = delim; - } + if (!isparent && !noinferiors) + mutt_buffer_addch (relpath, delim); - (state->entry)[state->entrylen].desc = safe_strdup (relpath); + (state->entry)[state->entrylen].desc = relpath->data; + FREE (&relpath); (state->entry)[state->entrylen].imap = 1; /* delimiter at the root is useless. */ @@ -463,7 +481,7 @@ static int compare_names(struct folder_f return mutt_strcmp(a->name, b->name); } -static int browse_get_namespace (IMAP_DATA* idata, char* nsbuf, int nsblen, +static int browse_get_namespace (IMAP_DATA* idata, BUFFER* nsbuf, IMAP_NAMESPACE_INFO* nsi, int nsilen, int* nns) { char *s; @@ -471,11 +489,14 @@ static int browse_get_namespace (IMAP_DA char ns[LONG_STRING]; char delim = '/'; int type; - int nsbused = 0; int rc; + IMAP_NAMESPACE_INFO* onsi = nsi; + size_t *offsets; *nns = 0; - nsbuf[nsblen-1] = '\0'; + nsbuf->dptr = nsbuf->data; + + offsets = safe_calloc (nsilen, sizeof (size_t)); imap_cmd_start (idata, "NAMESPACE"); @@ -505,7 +526,7 @@ static int browse_get_namespace (IMAP_DA if (*s == '\"') { s++; - while (*s && *s != '\"') + while (*s && *s != '\"' && n < sizeof (ns) - 1) { if (*s == '\\') s++; @@ -516,12 +537,14 @@ static int browse_get_namespace (IMAP_DA s++; } else - while (*s && !ISSPACE (*s)) + while (*s && !ISSPACE (*s) && n < sizeof (ns) - 1) { ns[n++] = *s; s++; } ns[n] = '\0'; + if (n == sizeof (ns)) + dprint (1, (debugfile, "browse_get_namespace: too long: [%s]\n", ns)); /* delim? */ s = imap_next_word (s); /* delimiter is meaningless if namespace is "". Why does @@ -534,7 +557,7 @@ static int browse_get_namespace (IMAP_DA delim = s[2]; } /* skip "" namespaces, they are already listed at the root */ - if ((ns[0] != '\0') && (nsbused < nsblen) && (*nns < nsilen)) + if ((ns[0] != '\0') && (*nns < nsilen)) { dprint (3, (debugfile, "browse_get_namespace: adding %s\n", ns)); nsi->type = type; @@ -543,9 +566,12 @@ static int browse_get_namespace (IMAP_DA * as if it were a normal directory, from the browser */ if (n && (ns[n-1] == delim)) ns[--n] = '\0'; - strncpy (nsbuf+nsbused,ns,nsblen-nsbused-1); - nsi->prefix = nsbuf+nsbused; - nsbused += n+1; + /* Store the offset for nsi->prefix + * because nsbuf->data may change. + * (See some 20 lines below) */ + offsets[*nns] = nsbuf->dptr - nsbuf->data; + mutt_buffer_add (nsbuf, ns, n); + nsbuf->dptr++; nsi->delim = delim; nsi++; (*nns)++; @@ -561,6 +587,11 @@ static int browse_get_namespace (IMAP_DA } while (rc == IMAP_CMD_CONTINUE); + /* adjust prefixes */ + for (n = 0; n < *nns; n++) + onsi[n].prefix = nsbuf->data + offsets[n]; + FREE (&offsets); + if (rc != IMAP_CMD_OK) return -1; @@ -571,25 +602,27 @@ static int browse_get_namespace (IMAP_DA static int browse_verify_namespace (IMAP_DATA* idata, IMAP_NAMESPACE_INFO *nsi, int nns) { - char buf[LONG_STRING]; + BUFFER *buf = NULL; IMAP_LIST list; int i = 0; int rc; + buf = mutt_buffer_size (buf, LONG_STRING); for (i = 0; i < nns; i++, nsi++) { + buf->dptr = buf->data; /* Cyrus gives back nothing if the % isn't added. This may return lots * of data in some cases, I guess, but I currently feel that's better * than invisible namespaces */ if (nsi->delim) - snprintf (buf, sizeof (buf), "%s \"\" \"%s%c%%\"", + mutt_buffer_printf (buf, "%s \"\" \"%s%c%%\"", option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix, nsi->delim); else - snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"", + mutt_buffer_printf (buf, "%s \"\" \"%s%%\"", option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix); - imap_cmd_start (idata, buf); + imap_cmd_start (idata, buf->data); idata->cmddata = &list; nsi->listable = 0; nsi->home_namespace = 0; @@ -603,9 +636,13 @@ static int browse_verify_namespace (IMAP idata->cmddata = NULL; if (rc != IMAP_CMD_OK) + { + mutt_buffer_free (&buf); return -1; + } } + mutt_buffer_free (&buf); return 0; } Index: imap/command.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/command.c,v retrieving revision 3.39 diff -p -u -r3.39 command.c --- imap/command.c 26 May 2006 16:38:18 -0000 3.39 +++ imap/command.c 11 Jun 2006 13:54:54 -0000 @@ -633,7 +633,7 @@ static void cmd_parse_list (IMAP_DATA* i static void cmd_parse_lsub (IMAP_DATA* idata, char* s) { - char buf[STRING]; + BUFFER *buf = NULL; char errstr[STRING]; BUFFER err, token; ciss_url_t url; @@ -657,18 +657,20 @@ static void cmd_parse_lsub (IMAP_DATA* i dprint (2, (debugfile, "Subscribing to %s\n", list.name)); - strfcpy (buf, "mailboxes \"", sizeof (buf)); + buf = mutt_buffer_size (buf, STRING); + mutt_buffer_add (buf, "mailboxes \"", 11); mutt_account_tourl (&idata->conn->account, &url); url.path = list.name; if (!mutt_strcmp (url.user, ImapUser)) url.user = NULL; - url_ciss_tostring (&url, buf + 11, sizeof (buf) - 10, 0); - safe_strcat (buf, sizeof (buf), "\""); + url_ciss_tostring (&url, buf, 0); + mutt_buffer_add (buf, "\"", 1); memset (&token, 0, sizeof (token)); err.data = errstr; err.dsize = sizeof (errstr); - if (mutt_parse_rc_line (buf, &token, &err)) + if (mutt_parse_rc_line (buf->data, &token, &err)) dprint (1, (debugfile, "Error adding subscribed mailbox: %s\n", errstr)); + mutt_buffer_free (&buf); FREE (&token.data); } @@ -836,8 +838,12 @@ static void cmd_parse_status (IMAP_DATA* { if (mx.mbox) { - value = safe_strdup (mx.mbox); - imap_fix_path (idata, mx.mbox, value, mutt_strlen (value) + 1); + BUFFER *tmpbuf = NULL; + tmpbuf = mutt_buffer_from (tmpbuf, mx.mbox); + imap_fix_path (idata, mx.mbox, tmpbuf); + value = tmpbuf->data; + + FREE (&tmpbuf); FREE (&mx.mbox); } else Index: imap/imap.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/imap.c,v retrieving revision 3.81 diff -p -u -r3.81 imap.c --- imap/imap.c 18 May 2006 18:35:10 -0000 3.81 +++ imap/imap.c 11 Jun 2006 13:54:56 -0000 @@ -51,7 +51,7 @@ static char* imap_get_flags (LIST** hflags, char* s); static int imap_check_capabilities (IMAP_DATA* idata); static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag, - const char* str, char* flags, size_t flsize); + const char* str, BUFFER* flags); /* imap_access: Check permissions on an IMAP mailbox. * TODO: ACL checks. Right now we assume if it exists we can @@ -60,9 +60,9 @@ int imap_access (const char* path, int f { IMAP_DATA* idata; IMAP_MBOX mx; - char buf[LONG_STRING]; - char mailbox[LONG_STRING]; - char mbox[LONG_STRING]; + BUFFER *buf = NULL; + BUFFER *mailbox = NULL; + BUFFER *mbox = NULL; if (imap_parse_path (path, &mx)) return -1; @@ -74,70 +74,89 @@ int imap_access (const char* path, int f return -1; } - imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox)); + mailbox = mutt_buffer_size (mailbox, LONG_STRING); + imap_fix_path (idata, mx.mbox, mailbox); /* we may already be in the folder we're checking */ if (!ascii_strcmp(idata->mailbox, mx.mbox)) { FREE (&mx.mbox); + mutt_buffer_free (&mailbox); return 0; } FREE (&mx.mbox); - imap_munge_mbox_name (mbox, sizeof (mbox), mailbox); + mbox = mutt_buffer_size (mbox, LONG_STRING); + imap_munge_mbox_name (mbox, mailbox->data); + mutt_buffer_free (&mailbox); + buf = mutt_buffer_size (buf, LONG_STRING); if (mutt_bit_isset (idata->capabilities, IMAP4REV1)) - snprintf (buf, sizeof (buf), "STATUS %s (UIDVALIDITY)", mbox); + mutt_buffer_printf (buf, "STATUS %s (UIDVALIDITY)", mbox->data); else if (mutt_bit_isset (idata->capabilities, STATUS)) - snprintf (buf, sizeof (buf), "STATUS %s (UID-VALIDITY)", mbox); + mutt_buffer_printf (buf, "STATUS %s (UID-VALIDITY)", mbox->data); else { dprint (2, (debugfile, "imap_access: STATUS not supported?\n")); + mutt_buffer_free (&mbox); + mutt_buffer_free (&buf); return -1; } - if (imap_exec (idata, buf, IMAP_CMD_FAIL_OK) < 0) + if (imap_exec (idata, buf->data, IMAP_CMD_FAIL_OK) < 0) { - dprint (1, (debugfile, "imap_access: Can't check STATUS of %s\n", mbox)); + dprint (1, (debugfile, "imap_access: Can't check STATUS of %s\n", mbox->data)); + mutt_buffer_free (&mbox); + mutt_buffer_free (&buf); return -1; } + mutt_buffer_free (&mbox); + mutt_buffer_free (&buf); return 0; } int imap_create_mailbox (IMAP_DATA* idata, char* mailbox) { - char buf[LONG_STRING], mbox[LONG_STRING]; + BUFFER *buf = NULL; - imap_munge_mbox_name (mbox, sizeof (mbox), mailbox); - snprintf (buf, sizeof (buf), "CREATE %s", mbox); - - if (imap_exec (idata, buf, 0) != 0) + buf = mutt_buffer_size (buf, LONG_STRING); + mutt_buffer_add (buf, "CREATE ", 7); + imap_munge_mbox_name (buf, mailbox); + + if (imap_exec (idata, buf->data, 0) != 0) + { + mutt_buffer_free (&buf); return -1; + } + mutt_buffer_free (&buf); return 0; } int imap_rename_mailbox (IMAP_DATA* idata, IMAP_MBOX* mx, const char* newname) { - char oldmbox[LONG_STRING]; - char newmbox[LONG_STRING]; - char buf[LONG_STRING]; + BUFFER *buf = NULL; - imap_munge_mbox_name (oldmbox, sizeof (oldmbox), mx->mbox); - imap_munge_mbox_name (newmbox, sizeof (newmbox), newname); + buf = mutt_buffer_size (buf, LONG_STRING); + mutt_buffer_add (buf, "RENAME ", 7); + imap_munge_mbox_name (buf, mx->mbox); + mutt_buffer_addch (buf, ' '); + imap_munge_mbox_name (buf, newname); - snprintf (buf, sizeof (buf), "RENAME %s %s", oldmbox, newmbox); - - if (imap_exec (idata, buf, 0) != 0) + if (imap_exec (idata, buf->data, 0) != 0) + { + mutt_buffer_free (&buf); return -1; + } + mutt_buffer_free (&buf); return 0; } int imap_delete_mailbox (CONTEXT* ctx, IMAP_MBOX mx) { - char buf[LONG_STRING], mbox[LONG_STRING]; + BUFFER *buf = NULL; IMAP_DATA *idata; if (!ctx || !ctx->data) { @@ -151,12 +170,17 @@ int imap_delete_mailbox (CONTEXT* ctx, I idata = ctx->data; } - imap_munge_mbox_name (mbox, sizeof (mbox), mx.mbox); - snprintf (buf, sizeof (buf), "DELETE %s", mbox); + buf = mutt_buffer_size (buf, LONG_STRING); + mutt_buffer_add (buf, "DELETE ", 7); + imap_munge_mbox_name (buf, mx.mbox); - if (imap_exec ((IMAP_DATA*) idata, buf, 0) != 0) + if (imap_exec ((IMAP_DATA*) idata, buf->data, 0) != 0) + { + mutt_buffer_free (&buf); return -1; + } + mutt_buffer_free (&buf); return 0; } @@ -262,7 +286,7 @@ void imap_expunge_mailbox (IMAP_DATA* id #if USE_HCACHE if (hc) { - sprintf (uidbuf, "/%u", HEADER_DATA(h)->uid); + snprintf (uidbuf, sizeof (uidbuf), "/%u", HEADER_DATA(h)->uid); mutt_hcache_delete (hc, uidbuf, imap_hcache_keylen); } #endif @@ -390,8 +414,6 @@ IMAP_DATA* imap_conn_find (const ACCOUNT int imap_open_connection (IMAP_DATA* idata) { - char buf[LONG_STRING]; - if (mutt_socket_open (idata->conn) < 0) return -1; @@ -459,7 +481,7 @@ int imap_open_connection (IMAP_DATA* ida } else { - imap_error ("imap_open_connection()", buf); + imap_error ("imap_open_connection()", idata->buf); goto bail; } @@ -537,8 +559,8 @@ int imap_open_mailbox (CONTEXT* ctx) CONNECTION *conn; IMAP_DATA *idata; IMAP_STATUS* status, sb; - char buf[LONG_STRING]; - char bufout[LONG_STRING]; + BUFFER *buf = NULL; + BUFFER *bufout = NULL; int count = 0; IMAP_MBOX mx, pmx; int rc; @@ -561,13 +583,15 @@ int imap_open_mailbox (CONTEXT* ctx) ctx->data = idata; /* Clean up path and replace the one in the ctx */ - imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); + buf = mutt_buffer_size (buf, LONG_STRING); + imap_fix_path (idata, mx.mbox, buf); FREE(&(idata->mailbox)); - idata->mailbox = safe_strdup (buf); - imap_qualify_path (buf, sizeof (buf), &mx, idata->mailbox); + idata->mailbox = safe_strdup (buf->data); + buf->dptr = buf->data; + imap_qualify_path (buf, &mx, idata->mailbox); FREE (&(ctx->path)); - ctx->path = safe_strdup (buf); + ctx->path = safe_strdup (buf->data); idata->ctx = ctx; @@ -577,13 +601,15 @@ int imap_open_mailbox (CONTEXT* ctx) idata->newMailCount = 0; mutt_message (_("Selecting %s..."), idata->mailbox); - imap_munge_mbox_name (buf, sizeof(buf), idata->mailbox); + buf->dptr = buf->data; + imap_munge_mbox_name (buf, idata->mailbox); /* pipeline ACL test */ + bufout = mutt_buffer_size (bufout, LONG_STRING); if (mutt_bit_isset (idata->capabilities, ACL)) { - snprintf (bufout, sizeof (bufout), "MYRIGHTS %s", buf); - imap_cmd_queue (idata, bufout); + mutt_buffer_printf (bufout, "MYRIGHTS %s", buf->data); + imap_cmd_queue (idata, bufout->data); } /* assume we have all rights if ACL is unavailable */ else @@ -602,12 +628,15 @@ int imap_open_mailbox (CONTEXT* ctx) && mutt_account_match (&pmx.account, &mx.account)) imap_status (Postponed, 1); - snprintf (bufout, sizeof (bufout), "%s %s", - ctx->readonly ? "EXAMINE" : "SELECT", buf); + bufout->dptr = bufout->data; + mutt_buffer_printf (bufout, "%s %s", + ctx->readonly ? "EXAMINE" : "SELECT", buf->data); + mutt_buffer_free (&buf); idata->state = IMAP_SELECTED; - imap_cmd_start (idata, bufout); + imap_cmd_start (idata, bufout->data); + mutt_buffer_free (&bufout); if (!(status = imap_mboxcache_get (idata, idata->mailbox))) { @@ -756,7 +785,7 @@ int imap_open_mailbox_append (CONTEXT *c CONNECTION *conn; IMAP_DATA *idata; char buf[LONG_STRING]; - char mailbox[LONG_STRING]; + BUFFER *mailbox = NULL; IMAP_MBOX mx; if (imap_parse_path (ctx->path, &mx)) @@ -776,20 +805,31 @@ int imap_open_mailbox_append (CONTEXT *c ctx->magic = M_IMAP; ctx->data = idata; - imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox)); + mailbox = mutt_buffer_size (mailbox, LONG_STRING); + imap_fix_path (idata, mx.mbox, mailbox); FREE (&mx.mbox); /* really we should also check for W_OK */ if (!imap_access (ctx->path, F_OK)) + { + mutt_buffer_free (&mailbox); return 0; + } - snprintf (buf, sizeof (buf), _("Create %s?"), mailbox); + snprintf (buf, sizeof (buf), _("Create %s?"), mailbox->data); if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1) + { + mutt_buffer_free (&mailbox); return -1; + } - if (imap_create_mailbox (idata, mailbox) < 0) + if (imap_create_mailbox (idata, mailbox->data) < 0) + { + mutt_buffer_free (&mailbox); return -1; + } + mutt_buffer_free (&mailbox); return 0; } @@ -810,11 +850,11 @@ void imap_logout (IMAP_DATA* idata) /* imap_set_flag: append str to flags if we currently have permission * according to aclbit */ static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag, - const char *str, char *flags, size_t flsize) + const char *str, BUFFER *flags) { if (mutt_bit_isset (idata->rights, aclbit)) if (flag && imap_has_flag (idata->flags, str)) - safe_strcat (flags, flsize, str); + mutt_buffer_addstr (flags, str); } /* imap_has_flag: do a caseless comparison of the flag against a flag list, @@ -843,7 +883,6 @@ int imap_has_flag (LIST* flag_list, cons * headers, given a flag enum to filter on. * Params: idata: IMAP_DATA containing context containing header set * buf: to write message set into - * buflen: length of buffer * flag: enum of flag type on which to filter * changed: include only changed messages in message set * invert: invert sense of flag, eg M_READ matches unread messages @@ -964,7 +1003,7 @@ static int compare_flags (HEADER* h) int imap_sync_message (IMAP_DATA *idata, HEADER *hdr, BUFFER *cmd, int *err_continue) { - char flags[LONG_STRING]; + BUFFER *flags = NULL; char uid[11]; hdr->changed = 0; @@ -975,47 +1014,44 @@ int imap_sync_message (IMAP_DATA *idata, return 0; } - snprintf (uid, sizeof (uid), "%u", HEADER_DATA(hdr)->uid); + if (snprintf (uid, sizeof (uid), "%u", HEADER_DATA(hdr)->uid) >= sizeof (uid)) + dprint (1, (debugfile, "imap_sync_message: UID too large\n")); cmd->dptr = cmd->data; mutt_buffer_addstr (cmd, "UID STORE "); mutt_buffer_addstr (cmd, uid); - flags[0] = '\0'; + flags = mutt_buffer_size (flags, STRING); - imap_set_flag (idata, IMAP_ACL_SEEN, hdr->read, "\\Seen ", - flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_WRITE, hdr->old, - "Old ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_WRITE, hdr->flagged, - "\\Flagged ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_WRITE, hdr->replied, - "\\Answered ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_DELETE, hdr->deleted, - "\\Deleted ", flags, sizeof (flags)); + imap_set_flag (idata, IMAP_ACL_SEEN, hdr->read, "\\Seen ", flags); + imap_set_flag (idata, IMAP_ACL_WRITE, hdr->old, "Old ", flags); + imap_set_flag (idata, IMAP_ACL_WRITE, hdr->flagged, "\\Flagged ", flags); + imap_set_flag (idata, IMAP_ACL_WRITE, hdr->replied, "\\Answered ", flags); + imap_set_flag (idata, IMAP_ACL_DELETE, hdr->deleted, "\\Deleted ", flags); /* now make sure we don't lose custom tags */ if (mutt_bit_isset (idata->rights, IMAP_ACL_WRITE)) - imap_add_keywords (flags, hdr, idata->flags, sizeof (flags)); + imap_add_keywords (flags, hdr, idata->flags); - mutt_remove_trailing_ws (flags); + mutt_remove_trailing_ws (flags->data); /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to * explicitly revoke all system flags (if we have permission) */ - if (!*flags) + if (!*flags->data) { - imap_set_flag (idata, IMAP_ACL_SEEN, 1, "\\Seen ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_WRITE, 1, "Old ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Flagged ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Answered ", flags, sizeof (flags)); - imap_set_flag (idata, IMAP_ACL_DELETE, 1, "\\Deleted ", flags, sizeof (flags)); + flags->dptr = flags->data; + imap_set_flag (idata, IMAP_ACL_SEEN, 1, "\\Seen ", flags); + imap_set_flag (idata, IMAP_ACL_WRITE, 1, "Old ", flags); + imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Flagged ", flags); + imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Answered ", flags); + imap_set_flag (idata, IMAP_ACL_DELETE, 1, "\\Deleted ", flags); - mutt_remove_trailing_ws (flags); + mutt_remove_trailing_ws (flags->data); mutt_buffer_addstr (cmd, " -FLAGS.SILENT ("); } else mutt_buffer_addstr (cmd, " FLAGS.SILENT ("); - mutt_buffer_addstr (cmd, flags); + mutt_buffer_addstr (cmd, flags->data); mutt_buffer_addstr (cmd, ")"); /* dumb hack for bad UW-IMAP 4.7 servers spurious FLAGS updates */ @@ -1023,18 +1059,22 @@ int imap_sync_message (IMAP_DATA *idata, /* after all this it's still possible to have no flags, if you * have no ACL rights */ - if (*flags && (imap_exec (idata, cmd->data, 0) != 0) && + if (*flags->data && (imap_exec (idata, cmd->data, 0) != 0) && err_continue && (*err_continue != M_YES)) { *err_continue = imap_continue ("imap_sync_message: STORE failed", idata->buf); if (*err_continue != M_YES) + { + mutt_buffer_free (&flags); return -1; + } } hdr->active = 1; idata->ctx->changed--; + mutt_buffer_free (&flags); return 0; } @@ -1383,7 +1423,7 @@ int imap_check_mailbox (CONTEXT *ctx, in } /* split path into (idata,mailbox name) */ -static int imap_get_mailbox (const char* path, IMAP_DATA** hidata, char* buf, size_t blen) +static int imap_get_mailbox (const char* path, IMAP_DATA** hidata, BUFFER* buf) { IMAP_MBOX mx; @@ -1399,7 +1439,7 @@ static int imap_get_mailbox (const char* return -1; } - imap_fix_path (*hidata, mx.mbox, buf, blen); + imap_fix_path (*hidata, mx.mbox, buf); FREE (&mx.mbox); return 0; @@ -1413,11 +1453,13 @@ int imap_buffy_check (int force) IMAP_DATA* idata; IMAP_DATA* lastdata = NULL; BUFFY* mailbox; - char name[LONG_STRING]; - char command[LONG_STRING]; - char munged[LONG_STRING]; + BUFFER *name = NULL; + BUFFER *command = NULL; int buffies = 0; + command = mutt_buffer_size (command, LONG_STRING); + name = mutt_buffer_size (name, LONG_STRING); + for (mailbox = Incoming; mailbox; mailbox = mailbox->next) { /* Init newly-added mailboxes */ @@ -1432,12 +1474,13 @@ int imap_buffy_check (int force) mailbox->new = 0; - if (imap_get_mailbox (mailbox->path, &idata, name, sizeof (name)) < 0) + name->dptr = name->data; + if (imap_get_mailbox (mailbox->path, &idata, name) < 0) continue; /* Don't issue STATUS on the selected mailbox, it will be NOOPed or * IDLEd elsewhere */ - if (!imap_mxcmp (name, idata->mailbox)) + if (!imap_mxcmp (name->data, idata->mailbox)) continue; if (!lastdata) @@ -1460,10 +1503,12 @@ int imap_buffy_check (int force) continue; } - imap_munge_mbox_name (munged, sizeof (munged), name); - snprintf (command, sizeof (command), "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN)", munged); + command->dptr = command->data; + mutt_buffer_add (command, "STATUS ", 7); + imap_munge_mbox_name (command, name->data); + mutt_buffer_add (command, " (UIDNEXT UIDVALIDITY UNSEEN)", 29); - if (imap_cmd_queue (idata, command) < 0) + if (imap_cmd_queue (idata, command->data) < 0) { /* pipeline must be full, drain it */ dprint (2, (debugfile, "IMAP command pipeline full, draining\n")); @@ -1471,14 +1516,18 @@ int imap_buffy_check (int force) if (imap_exec (idata, NULL, 0) != IMAP_CMD_OK) dprint (1, (debugfile, "Error polling mailboxes\n")); - if (imap_cmd_queue (idata, command) < 0) { + if (imap_cmd_queue (idata, command->data) < 0) { /* real trouble */ dprint (1, (debugfile, "Error queueing command\n")); + mutt_buffer_free (&command); return 0; } } } + mutt_buffer_free (&command); + mutt_buffer_free (&name); + if (lastdata && (imap_exec (lastdata, NULL, 0) != IMAP_CMD_OK)) { dprint (1, (debugfile, "Error polling mailboxes")); @@ -1503,41 +1552,61 @@ int imap_status (char* path, int queue) static int queued = 0; IMAP_DATA *idata; - char buf[LONG_STRING]; - char mbox[LONG_STRING]; + BUFFER *buf = NULL; + char *mbox; IMAP_STATUS* status; - if (imap_get_mailbox (path, &idata, buf, sizeof (buf)) < 0) + buf = mutt_buffer_size (buf, LONG_STRING); + if (imap_get_mailbox (path, &idata, buf) < 0) + { + mutt_buffer_free (&buf); return -1; + } - if (!imap_mxcmp (buf, idata->mailbox)) + if (!imap_mxcmp (buf->data, idata->mailbox)) + { /* We are in the folder we're polling - just return the mailbox count */ + mutt_buffer_free (&buf); return idata->ctx->msgcount; + } else if (mutt_bit_isset(idata->capabilities,IMAP4REV1) || mutt_bit_isset(idata->capabilities,STATUS)) { - imap_munge_mbox_name (mbox, sizeof(mbox), buf); - snprintf (buf, sizeof (buf), "STATUS %s (%s)", mbox, "MESSAGES"); - imap_unmunge_mbox_name (mbox); + mbox = safe_strdup (buf->data); + buf->dptr = buf->data; + mutt_buffer_add (buf, "STATUS ", 7); + imap_munge_mbox_name (buf, mbox); + mutt_buffer_add (buf, " (MESSAGES)", 11); } else + { /* Server does not support STATUS, and this is not the current mailbox. * There is no lightweight way to check recent arrivals */ + mutt_buffer_free (&buf); return -1; + } if (queue) { - imap_cmd_queue (idata, buf); + imap_cmd_queue (idata, buf->data); queued = 1; + mutt_buffer_free (&buf); + FREE (&mbox); return 0; } else if (!queued) - imap_exec (idata, buf, 0); + imap_exec (idata, buf->data, 0); + + mutt_buffer_free (&buf); queued = 0; if ((status = imap_mboxcache_get (idata, mbox))) + { + FREE (&mbox); return status->messages; + } + FREE (&mbox); return 0; } @@ -1646,7 +1715,6 @@ static int imap_compile_search (const pa } else { - char term[STRING]; char *delim; switch (pat->op) @@ -1661,26 +1729,22 @@ static int imap_compile_search (const pa return -1; } *delim = '\0'; - imap_quote_string (term, sizeof (term), pat->p.str); - mutt_buffer_addstr (buf, term); + imap_quote_string (buf, pat->p.str); mutt_buffer_addch (buf, ' '); /* and field */ *delim = ':'; delim++; SKIPWS(delim); - imap_quote_string (term, sizeof (term), delim); - mutt_buffer_addstr (buf, term); + imap_quote_string (buf, delim); break; case M_BODY: mutt_buffer_addstr (buf, "BODY "); - imap_quote_string (term, sizeof (term), pat->p.str); - mutt_buffer_addstr (buf, term); + imap_quote_string (buf, pat->p.str); break; case M_WHOLE_MSG: mutt_buffer_addstr (buf, "TEXT "); - imap_quote_string (term, sizeof (term), pat->p.str); - mutt_buffer_addstr (buf, term); + imap_quote_string (buf, pat->p.str); break; } } @@ -1721,8 +1785,8 @@ int imap_subscribe (char *path, int subs { CONNECTION *conn; IMAP_DATA *idata; - char buf[LONG_STRING]; - char mbox[LONG_STRING]; + BUFFER *buf = NULL; + BUFFER *mbox = NULL; char errstr[STRING]; BUFFER err, token; IMAP_MBOX mx; @@ -1737,29 +1801,33 @@ int imap_subscribe (char *path, int subs conn = idata->conn; - imap_fix_path (idata, mx.mbox, buf, sizeof (buf)); + buf = mutt_buffer_size (buf, LONG_STRING); + imap_fix_path (idata, mx.mbox, buf); + mbox = mutt_buffer_size (mbox, LONG_STRING); if (option (OPTIMAPCHECKSUBSCRIBED)) { memset (&token, 0, sizeof (token)); err.data = errstr; err.dsize = sizeof (errstr); - snprintf (mbox, sizeof (mbox), "%smailboxes \"%s\"", + mutt_buffer_printf (mbox, "%smailboxes \"%s\"", subscribe ? "" : "un", path); - if (mutt_parse_rc_line (mbox, &token, &err)) + if (mutt_parse_rc_line (mbox->data, &token, &err)) dprint (1, (debugfile, "Error adding subscribed mailbox: %s\n", errstr)); FREE (&token.data); } if (subscribe) - mutt_message (_("Subscribing to %s..."), buf); + mutt_message (_("Subscribing to %s..."), buf->data); else - mutt_message (_("Unsubscribing from %s..."), buf); - imap_munge_mbox_name (mbox, sizeof(mbox), buf); + mutt_message (_("Unsubscribing from %s..."), buf->data); + mbox->dptr = mbox->data; + imap_munge_mbox_name (mbox, buf->data); - snprintf (buf, sizeof (buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mbox); + buf->dptr = buf->data; + mutt_buffer_printf (buf, "%sSUBSCRIBE %s", subscribe ? "" : "UN", mbox->data); - if (imap_exec (idata, buf, 0) < 0) + if (imap_exec (idata, buf->data, 0) < 0) goto fail; imap_unmunge_mbox_name(mx.mbox); @@ -1768,10 +1836,14 @@ int imap_subscribe (char *path, int subs else mutt_message (_("Unsubscribed from %s"), mx.mbox); FREE (&mx.mbox); + mutt_buffer_free (&buf); + mutt_buffer_free (&mbox); return 0; fail: FREE (&mx.mbox); + mutt_buffer_free (&buf); + mutt_buffer_free (&mbox); return -1; } @@ -1798,6 +1870,7 @@ imap_complete_hosts (char *dest, size_t CONNECTION* conn; int rc = -1; int matchlen; + BUFFER *urlstr = NULL; matchlen = mutt_strlen (dest); for (mailbox = Incoming; mailbox && mailbox->next; mailbox = mailbox->next) @@ -1813,11 +1886,11 @@ imap_complete_hosts (char *dest, size_t longest_common_prefix (dest, mailbox->path, matchlen, len); } } - + + urlstr = mutt_buffer_size (urlstr, LONG_STRING); for (conn = mutt_socket_head (); conn && conn->next; conn = conn->next) { ciss_url_t url; - char urlstr[LONG_STRING]; if (conn->account.type != M_ACCT_TYPE_IMAP) continue; @@ -1826,19 +1899,21 @@ imap_complete_hosts (char *dest, size_t /* FIXME: how to handle multiple users on the same host? */ url.user = NULL; url.path = NULL; - url_ciss_tostring (&url, urlstr, sizeof (urlstr), 0); - if (!mutt_strncmp (dest, urlstr, matchlen)) + urlstr->dptr = urlstr->data; + url_ciss_tostring (&url, urlstr, 0); + if (!mutt_strncmp (dest, urlstr->data, matchlen)) { if (rc) { - strfcpy (dest, urlstr, len); + strfcpy (dest, urlstr->data, len); rc = 0; } else - longest_common_prefix (dest, urlstr, matchlen, len); + longest_common_prefix (dest, urlstr->data, matchlen, len); } } + mutt_buffer_free (&urlstr); return rc; } @@ -1847,8 +1922,8 @@ imap_complete_hosts (char *dest, size_t int imap_complete(char* dest, size_t dlen, char* path) { CONNECTION* conn; IMAP_DATA* idata; - char list[LONG_STRING]; - char buf[LONG_STRING]; + BUFFER *list = NULL; + BUFFER *buf = NULL; IMAP_LIST listresp; char completion[LONG_STRING]; int clen, matchlen = 0; @@ -1874,16 +1949,19 @@ int imap_complete(char* dest, size_t dle /* reformat path for IMAP list, and append wildcard */ /* don't use INBOX in place of "" */ + list = mutt_buffer_size (list, LONG_STRING); if (mx.mbox && mx.mbox[0]) - imap_fix_path (idata, mx.mbox, list, sizeof(list)); + imap_fix_path (idata, mx.mbox, list); else - list[0] = '\0'; + *list->data = '\0'; /* fire off command */ - snprintf (buf, sizeof(buf), "%s \"\" \"%s%%\"", - option (OPTIMAPLSUB) ? "LSUB" : "LIST", list); + buf = mutt_buffer_size (buf, LONG_STRING); + mutt_buffer_printf (buf, "%s \"\" \"%s%%\"", + option (OPTIMAPLSUB) ? "LSUB" : "LIST", list->data); + mutt_buffer_free (&list); - imap_cmd_start (idata, buf); + imap_cmd_start (idata, buf->data); /* and see what the results are */ strfcpy (completion, NONULL(mx.mbox), sizeof(completion)); @@ -1922,12 +2000,16 @@ int imap_complete(char* dest, size_t dle if (completions) { /* reformat output */ - imap_qualify_path (dest, dlen, &mx, completion); - mutt_pretty_mailbox (dest); + buf->dptr = buf->data; + imap_qualify_path (buf, &mx, completion); + mutt_pretty_mailbox (buf->data); + strfcpy (dest, buf->data, dlen); + mutt_buffer_free (&buf); FREE (&mx.mbox); return 0; } + mutt_buffer_free (&buf); return -1; } Index: imap/message.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/message.c,v retrieving revision 3.51 diff -p -u -r3.51 message.c --- imap/message.c 26 May 2006 16:38:18 -0000 3.51 +++ imap/message.c 11 Jun 2006 13:54:57 -0000 @@ -58,8 +58,8 @@ static char* msg_parse_flags (IMAP_HEADE int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend) { CONTEXT* ctx; - char buf[LONG_STRING]; - char hdrreq[STRING]; + BUFFER *buf = NULL; + BUFFER *hdrreq = NULL; FILE *fp; char tempfile[_POSIX_PATH_MAX]; int msgno; @@ -79,21 +79,23 @@ int imap_read_headers (IMAP_DATA* idata, #endif /* USE_HCACHE */ ctx = idata->ctx; + hdrreq = mutt_buffer_size (hdrreq, STRING); if (mutt_bit_isset (idata->capabilities,IMAP4REV1)) { - snprintf (hdrreq, sizeof (hdrreq), "BODY.PEEK[HEADER.FIELDS (%s%s%s)]", + mutt_buffer_printf (hdrreq, "BODY.PEEK[HEADER.FIELDS (%s%s%s)]", want_headers, ImapHeaders ? " " : "", ImapHeaders ? ImapHeaders : ""); } else if (mutt_bit_isset (idata->capabilities,IMAP4)) { - snprintf (hdrreq, sizeof (hdrreq), "RFC822.HEADER.LINES (%s%s%s)", + mutt_buffer_printf (hdrreq, "RFC822.HEADER.LINES (%s%s%s)", want_headers, ImapHeaders ? " " : "", ImapHeaders ? ImapHeaders : ""); } else { /* Unable to fetch headers for lower versions */ mutt_error _("Unable to fetch headers from this IMAP server version."); mutt_sleep (2); /* pause a moment to let the user see the error */ + mutt_buffer_free (&hdrreq); return -1; } @@ -104,6 +106,7 @@ int imap_read_headers (IMAP_DATA* idata, { mutt_error (_("Could not create temporary file %s"), tempfile); mutt_sleep (2); + mutt_buffer_free (&hdrreq); return -1; } unlink (tempfile); @@ -115,6 +118,7 @@ int imap_read_headers (IMAP_DATA* idata, oldmsgcount = ctx->msgcount; idata->reopen &= ~IMAP_NEWMAIL_PENDING; idata->newMailCount = 0; + buf = mutt_buffer_size (buf, LONG_STRING); #if USE_HCACHE if (!msgbegin) @@ -131,11 +135,11 @@ int imap_read_headers (IMAP_DATA* idata, } if (evalhc) { - snprintf (buf, sizeof (buf), + mutt_buffer_printf (buf, "UID FETCH 1:%u (UID FLAGS)", *uidnext - 1); FREE (&uidnext); - imap_cmd_start (idata, buf); + imap_cmd_start (idata, buf->data); for (msgno = msgbegin; msgno <= msgend ; msgno++) { @@ -158,7 +162,7 @@ int imap_read_headers (IMAP_DATA* idata, else if (mfhrc < 0) break; - sprintf(uid_buf, "/%u", h.data->uid); /* XXX --tg 21:41 04-07-11 */ + snprintf (uid_buf, sizeof (uid_buf), "/%u", h.data->uid); /* XXX --tg 21:41 04-07-11 */ uid_validity = (unsigned int*)mutt_hcache_fetch (hc, uid_buf, &imap_hcache_keylen); if (uid_validity != NULL && *uid_validity == idata->uid_validity) @@ -192,6 +196,8 @@ int imap_read_headers (IMAP_DATA* idata, imap_free_header_data ((void**) &h.data); fclose (fp); mutt_hcache_close (hc); + mutt_buffer_free (&hdrreq); + mutt_buffer_free (&buf); return -1; } } @@ -225,12 +231,15 @@ int imap_read_headers (IMAP_DATA* idata, * If we get more messages while doing this, we make another * request for all the new messages. */ - snprintf (buf, sizeof (buf), + buf->dptr = buf->data; + mutt_buffer_printf (buf, "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1, - fetchlast, hdrreq); + fetchlast, hdrreq->data); - imap_cmd_start (idata, buf); + imap_cmd_start (idata, buf->data); } + mutt_buffer_free (&hdrreq); + mutt_buffer_free (&buf); /* freshen fp, h */ rewind (fp); @@ -287,7 +296,7 @@ int imap_read_headers (IMAP_DATA* idata, ctx->hdrs[msgno]->content->length = h.content_length; #if USE_HCACHE - sprintf(uid_buf, "/%u", h.data->uid); + snprintf (uid_buf, sizeof (uid_buf), "/%u", h.data->uid); mutt_hcache_store(hc, uid_buf, ctx->hdrs[msgno], idata->uid_validity, &imap_hcache_keylen); #endif /* USE_HCACHE */ @@ -552,9 +561,9 @@ int imap_append_message (CONTEXT *ctx, M { IMAP_DATA* idata; FILE *fp; + BUFFER *dbuf = NULL; + BUFFER *mailbox = NULL; char buf[LONG_STRING]; - char mbox[LONG_STRING]; - char mailbox[LONG_STRING]; size_t len; progress_t progressbar; size_t sent; @@ -567,7 +576,8 @@ int imap_append_message (CONTEXT *ctx, M if (imap_parse_path (ctx->path, &mx)) return -1; - imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox)); + mailbox = mutt_buffer_size (mailbox, LONG_STRING); + imap_fix_path (idata, mx.mbox, mailbox); if ((fp = fopen (msg->path, "r")) == NULL) { @@ -594,8 +604,11 @@ int imap_append_message (CONTEXT *ctx, M progressbar.size = len; mutt_progress_bar (&progressbar, 0); - imap_munge_mbox_name (mbox, sizeof (mbox), mailbox); - snprintf (buf, sizeof (buf), "APPEND %s (%s%s%s%s%s) {%lu}", mbox, + dbuf = mutt_buffer_size (dbuf, LONG_STRING); + mutt_buffer_add (dbuf, "APPEND ", 7); + imap_munge_mbox_name (dbuf, mailbox->data); + mutt_buffer_free (&mailbox); + mutt_buffer_printf (dbuf, " (%s%s%s%s%s) {%lu}", msg->flags.read ? "\\Seen" : "", msg->flags.read && (msg->flags.replied || msg->flags.flagged) ? " " : "", msg->flags.replied ? "\\Answered" : "", @@ -603,7 +616,8 @@ int imap_append_message (CONTEXT *ctx, M msg->flags.flagged ? "\\Flagged" : "", (unsigned long) len); - imap_cmd_start (idata, buf); + imap_cmd_start (idata, dbuf->data); + mutt_buffer_free (&dbuf); do rc = imap_cmd_step (idata); @@ -683,8 +697,8 @@ int imap_copy_messages (CONTEXT* ctx, HE IMAP_DATA* idata; BUFFER cmd, sync_cmd; char uid[11]; - char mbox[LONG_STRING]; - char mmbox[LONG_STRING]; + BUFFER *mbox = NULL; + char buf[LONG_STRING]; int rc; int n; IMAP_MBOX mx; @@ -711,8 +725,9 @@ int imap_copy_messages (CONTEXT* ctx, HE dprint (3, (debugfile, "imap_copy_messages: Message contains attachments to be deleted\n")); return 1; } - - imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox)); + + mbox = mutt_buffer_size (mbox, LONG_STRING); + imap_fix_path (idata, mx.mbox, mbox); memset (&sync_cmd, 0, sizeof (sync_cmd)); memset (&cmd, 0, sizeof (cmd)); @@ -729,6 +744,7 @@ int imap_copy_messages (CONTEXT* ctx, HE if (ctx->hdrs[n]->tagged && ctx->hdrs[n]->attach_del) { dprint (3, (debugfile, "imap_copy_messages: Message contains attachments to be deleted\n")); + mutt_buffer_free (&mbox); return 1; } @@ -750,11 +766,11 @@ int imap_copy_messages (CONTEXT* ctx, HE dprint (1, (debugfile, "imap_copy_messages: No messages tagged\n")); goto fail; } - mutt_message (_("Copying %d messages to %s..."), rc, mbox); + mutt_message (_("Copying %d messages to %s..."), rc, mbox->data); } else { - mutt_message (_("Copying message %d to %s..."), h->index+1, mbox); + mutt_message (_("Copying message %d to %s..."), h->index+1, mbox->data); snprintf (uid, sizeof (uid), "%u", HEADER_DATA (h)->uid); mutt_buffer_addstr (&cmd, uid); @@ -771,8 +787,7 @@ int imap_copy_messages (CONTEXT* ctx, HE /* let's get it on */ mutt_buffer_addstr (&cmd, " "); - imap_munge_mbox_name (mmbox, sizeof (mmbox), mbox); - mutt_buffer_addstr (&cmd, mmbox); + imap_munge_mbox_name (&cmd, mbox->data); rc = imap_exec (idata, cmd.data, IMAP_CMD_FAIL_OK); if (rc == -2) @@ -784,13 +799,13 @@ int imap_copy_messages (CONTEXT* ctx, HE goto fail; } dprint (2, (debugfile, "imap_copy_messages: server suggests TRYCREATE\n")); - snprintf (mmbox, sizeof (mmbox), _("Create %s?"), mbox); - if (option (OPTCONFIRMCREATE) && mutt_yesorno (mmbox, 1) < 1) + snprintf (buf, sizeof (buf), _("Create %s?"), mbox->data); + if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1) { mutt_clear_error (); goto fail; } - if (imap_create_mailbox (idata, mbox) < 0) + if (imap_create_mailbox (idata, mbox->data) < 0) goto fail; /* try again */ @@ -823,6 +838,7 @@ int imap_copy_messages (CONTEXT* ctx, HE } } + mutt_buffer_free (&mbox); if (cmd.data) FREE (&cmd.data); if (sync_cmd.data) @@ -831,6 +847,7 @@ int imap_copy_messages (CONTEXT* ctx, HE return 0; fail: + mutt_buffer_free (&mbox); if (cmd.data) FREE (&cmd.data); if (sync_cmd.data) @@ -938,7 +955,7 @@ int imap_cache_del (IMAP_DATA* idata, HE /* imap_add_keywords: concatenate custom IMAP tags to list, if they * appear in the folder flags list. Why wouldn't they? */ -void imap_add_keywords (char* s, HEADER* h, LIST* mailbox_flags, size_t slen) +void imap_add_keywords (BUFFER* s, HEADER* h, LIST* mailbox_flags) { LIST *keywords; @@ -951,8 +968,8 @@ void imap_add_keywords (char* s, HEADER* { if (imap_has_flag (mailbox_flags, keywords->data)) { - safe_strcat (s, slen, keywords->data); - safe_strcat (s, slen, " "); + mutt_buffer_addstr (s, keywords->data); + mutt_buffer_addch (s, ' '); } keywords = keywords->next; } @@ -1105,7 +1122,7 @@ static int msg_parse_fetch (IMAP_HEADER } s++; ptmp = tmp; - while (*s && *s != '\"') + while (*s && *s != '\"' && (ptmp - tmp) < (sizeof (tmp) - 1)) *ptmp++ = *s++; if (*s != '\"') return -1; @@ -1118,7 +1135,7 @@ static int msg_parse_fetch (IMAP_HEADER s += 11; SKIPWS (s); ptmp = tmp; - while (isdigit ((unsigned char) *s)) + while (isdigit ((unsigned char) *s) && (ptmp - tmp) < (sizeof (tmp) - 1)) *ptmp++ = *s++; *ptmp = 0; h->content_length = atoi (tmp); Index: imap/util.c =================================================================== RCS file: /home/roessler/cvs/mutt/imap/util.c,v retrieving revision 3.23 diff -p -u -r3.23 util.c --- imap/util.c 18 May 2006 17:35:30 -0000 3.23 +++ imap/util.c 11 Jun 2006 13:54:57 -0000 @@ -43,24 +43,23 @@ /* imap_expand_path: IMAP implementation of mutt_expand_path. Rewrite * an IMAP path in canonical and absolute form. - * Inputs: a buffer containing an IMAP path, and the number of bytes in - * that buffer. + * Inputs: a buffer containing an IMAP path. * Outputs: The buffer is rewritten in place with the canonical IMAP path. - * Returns 0 on success, or -1 if imap_parse_path chokes or url_ciss_tostring - * fails, which it might if there isn't enough room in the buffer. */ -int imap_expand_path (char* path, size_t len) + * Returns 0 on success, or -1 if imap_parse_path chokes. */ +int imap_expand_path (BUFFER *path) { IMAP_MBOX mx; ciss_url_t url; int rc; - if (imap_parse_path (path, &mx) < 0) + if (imap_parse_path (path->data, &mx) < 0) return -1; mutt_account_tourl (&mx.account, &url); url.path = mx.mbox; - rc = url_ciss_tostring (&url, path, len, U_DECODE_PASSWD); + path->dptr = path->data; + rc = url_ciss_tostring (&url, path, U_DECODE_PASSWD); FREE (&mx.mbox); return rc; @@ -137,9 +136,18 @@ int imap_parse_path (const char* path, I if ((c = strrchr (tmp, '@'))) { *c = '\0'; - strfcpy (mx->account.user, tmp, sizeof (mx->account.user)); - strfcpy (tmp, c+1, sizeof (tmp)); - mx->account.flags |= M_ACCT_USER; + if ((c - tmp) >= sizeof (mx->account.user)) + { + dprint (1, (debugfile, "imap_parse_path: too long username.\n")); + FREE (&mx->mbox); + return -1; + } + else + { + strfcpy (mx->account.user, tmp, sizeof (mx->account.user)); + strfcpy (tmp, c+1, sizeof (tmp)); + mx->account.flags |= M_ACCT_USER; + } } if ((n = sscanf (tmp, "%127[^:/]%127s", mx->account.host, tmp)) < 1) @@ -183,7 +191,7 @@ int imap_mxcmp (const char* mx1, const c /* imap_pretty_mailbox: called by mutt_pretty_mailbox to make IMAP paths * look nice. */ -void imap_pretty_mailbox (char* path) +void imap_pretty_mailbox (BUFFER* path) { IMAP_MBOX home, target; ciss_url_t url; @@ -192,7 +200,7 @@ void imap_pretty_mailbox (char* path) int hlen = 0; char home_match = 0; - if (imap_parse_path (path, &target) < 0) + if (imap_parse_path (path->data, &target) < 0) return; tlen = mutt_strlen (target.mbox); @@ -213,23 +221,20 @@ void imap_pretty_mailbox (char* path) FREE (&home.mbox); } + path->dptr = path->data; /* do the '=' substitution */ if (home_match) { - *path++ = '='; + mutt_buffer_addch (path, '='); /* copy remaining path, skipping delimiter */ if (! hlen) hlen = -1; - memcpy (path, target.mbox + hlen + 1, tlen - hlen - 1); - path[tlen - hlen - 1] = '\0'; + mutt_buffer_add (path, target.mbox + hlen + 1, tlen - hlen - 1); } else { mutt_account_tourl (&target.account, &url); url.path = target.mbox; - /* FIXME: That hard-coded constant is bogus. But we need the actual - * size of the buffer from mutt_pretty_mailbox. And these pretty - * operations usually shrink the result. Still... */ - url_ciss_tostring (&url, path, 1024, 0); + url_ciss_tostring (&url, path, 0); } FREE (&target.mbox); @@ -289,34 +294,30 @@ void imap_free_idata (IMAP_DATA** idata) * are not required to do this. * Moreover, IMAP servers may dislike the path ending with the delimiter. */ -char *imap_fix_path (IMAP_DATA *idata, char *mailbox, char *path, - size_t plen) +BUFFER *imap_fix_path (IMAP_DATA *idata, char *mailbox, BUFFER *path) { - int x = 0; - if (!mailbox || !*mailbox) { - strfcpy (path, "INBOX", plen); + mutt_buffer_add (path, "INBOX", 5); return path; } - while (mailbox && *mailbox && (x < (plen - 1))) + while (mailbox && *mailbox) { if ((*mailbox == '/') || (*mailbox == idata->delim)) { while ((*mailbox == '/') || (*mailbox == idata->delim)) mailbox++; - path[x] = idata->delim; + mutt_buffer_addch (path, idata->delim); } else { - path[x] = *mailbox; + mutt_buffer_addch (path, *mailbox); mailbox++; } - x++; } - if (x && path[--x] != idata->delim) - x++; - path[x] = '\0'; + if (*(--path->dptr) != idata->delim) + path->dptr++; + *path->dptr = '\0'; return path; } @@ -425,49 +426,39 @@ time_t imap_parse_date (char *s) /* imap_qualify_path: make an absolute IMAP folder target, given IMAP_MBOX * and relative path. */ -void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path) +void imap_qualify_path (BUFFER *dest, IMAP_MBOX *mx, char* path) { ciss_url_t url; mutt_account_tourl (&mx->account, &url); url.path = path; - url_ciss_tostring (&url, dest, len, 0); + url_ciss_tostring (&url, dest, 0); } /* imap_quote_string: quote string according to IMAP rules: * surround string with quotes, escape " and \ with \ */ -void imap_quote_string (char *dest, size_t dlen, const char *src) +void imap_quote_string (BUFFER *dest, const char *src) { - char quote[] = "\"\\", *pt; + char quote[] = "\"\\"; const char *s; - pt = dest; s = src; - *pt++ = '"'; - /* save room for trailing quote-char */ - dlen -= 2; - - for (; *s && dlen; s++) + mutt_buffer_addch (dest, '"'); + + for (; *s; s++) { if (strchr (quote, *s)) { - dlen -= 2; - if (!dlen) - break; - *pt++ = '\\'; - *pt++ = *s; + mutt_buffer_addch (dest, '\\'); + mutt_buffer_addch (dest, *s); } else - { - *pt++ = *s; - dlen--; - } + mutt_buffer_addch (dest, *s); } - *pt++ = '"'; - *pt = 0; + mutt_buffer_addch (dest, '"'); } /* imap_unquote_string: equally stupid unquoting routine */ @@ -505,14 +496,14 @@ void imap_unquote_string (char *s) * Quoting and UTF-7 conversion */ -void imap_munge_mbox_name (char *dest, size_t dlen, const char *src) +void imap_munge_mbox_name (BUFFER *dest, const char *src) { char *buf; buf = safe_strdup (src); imap_utf7_encode (&buf); - imap_quote_string (dest, dlen, buf); + imap_quote_string (dest, buf); FREE (&buf); }