> Date: 2026-09-30 12:45:45+0800 > From: "Kevin J. McCarthy" <[email protected]> > > The ACCOUNT structure is unusual inside the Mutt codebase. It's never > dynamically allocated: instead it's a member of the CONNECTION and > IMAP_MBOX structures. This commit doesn't change that. > > This commit does change the individual string fields from fixed size > char arrays to dynamically allocated strings. This is done because > other variables, such as $imap_user and $imap_pass, have no fixed size > limit. In the past, I've had to bump up the size of the fields to > accomodate users with extra large username or passwords. > > Unfortunately, this change leads to lifecyle issues. We need to track > and free the fields. > > This commit therefore creates helper functions: > - mutt_account_free() to free the fields > - mutt_account_copy() to strdup the fields > - imap_mbox_free() to free the IMAP_MBOX and its ACCOUNT fields. > > A call to mutt_account_free() is added to mutt_socket_free(): the only > place that cleans up CONNECTION structures. > > Other places in the code swap out a call to FREE(imapbox.mbox) to > imap_mbox_free(&imapmbox); > > IMAP_MBOX variables are all initialized to { 0 } to ensure the dynamic > string fields are initilized to NULL, and thus ensure the free > function works correctly. > > Another potential complication is the ciss_url_t structure. It points > directly at ACCOUNT fields, instead of allocating them. This is > dangerous, of course, but this commit doesn't change the lifecycle of > the ACCOUNT or ciss_url_t. > ---
Reviewed-by: Alejandro Colomar <[email protected]> Cheers, Alex > account.c | 72 ++++++++++++++++++++++++++++++++++++++------------ > account.h | 10 ++++--- > browser.c | 5 ++-- > imap/browse.c | 26 +++++++++--------- > imap/command.c | 7 ++--- > imap/imap.c | 52 ++++++++++++++++++------------------ > imap/imap.h | 1 + > imap/message.c | 10 +++---- > imap/util.c | 42 ++++++++++++++++++----------- > mutt_socket.c | 4 ++- > pop_auth.c | 2 +- > 11 files changed, 144 insertions(+), 87 deletions(-) > > diff --git a/account.c b/account.c > index 70fe2705..dcb59b36 100644 > --- a/account.c > +++ b/account.c > @@ -27,6 +27,40 @@ > #include "url.h" > #include "mutt_curses.h" > > +/* Accounts aren't independently allocated. They are members of the > + * CONNECTION and IMAP_DATA structs. This function frees the char* > + * members of the ACCOUNT and resets the integer values in case the > + * structure is reused in a loop. > + */ > +void mutt_account_free(ACCOUNT *account) > +{ > + if (!account) > + return; > + > + FREE(&account->user); > + FREE(&account->login); > + FREE(&account->pass); > + FREE(&account->host); > + account->port = 0; > + account->type = 0; > + account->flags = 0; > +} > + > +void mutt_account_copy(ACCOUNT *dest, const ACCOUNT *src) > +{ > + if (!dest || !src) > + return; > + > + dest->user = safe_strdup(src->user); > + dest->login = safe_strdup(src->login); > + dest->pass = safe_strdup(src->pass); > + dest->host = safe_strdup(src->host); > + dest->port = src->port; > + dest->type = src->type; > + dest->flags = src->flags; > +} > + > + > /* mutt_account_match: compare account info (host/port/user) */ > int mutt_account_match(const ACCOUNT *a1, const ACCOUNT *a2) > { > @@ -53,11 +87,11 @@ int mutt_account_match(const ACCOUNT *a1, const ACCOUNT > *a2) > #endif > > if (a1->flags & a2->flags & MUTT_ACCT_USER) > - return (!strcmp(a1->user, a2->user)); > + return (!mutt_strcmp(a1->user, a2->user)); > if (a1->flags & MUTT_ACCT_USER) > - return (!strcmp(a1->user, user)); > + return (!mutt_strcmp(a1->user, user)); > if (a2->flags & MUTT_ACCT_USER) > - return (!strcmp(a2->user, user)); > + return (!mutt_strcmp(a2->user, user)); > > return 1; > } > @@ -67,19 +101,19 @@ int mutt_account_fromurl(ACCOUNT *account, ciss_url_t > *url) > { > /* must be present */ > if (url->host) > - strfcpy(account->host, url->host, sizeof(account->host)); > + mutt_str_replace(&account->host, url->host); > else > return -1; > > if (url->user) > { > - strfcpy(account->user, url->user, sizeof(account->user)); > + mutt_str_replace(&account->user, url->user); > account->flags |= MUTT_ACCT_USER; > account->flags |= MUTT_ACCT_USER_FROM_URL; > } > if (url->pass) > { > - strfcpy(account->pass, url->pass, sizeof(account->pass)); > + mutt_str_replace(&account->pass, url->pass); > account->flags |= MUTT_ACCT_PASS; > account->flags |= MUTT_ACCT_PASS_FROM_URL; > } > @@ -161,17 +195,18 @@ void mutt_account_tourl(ACCOUNT *account, ciss_url_t > *url, int force_user) > int mutt_account_getuser(ACCOUNT *account) > { > char prompt[SHORT_STRING]; > + char userbuf[LONG_STRING]; > > /* already set */ > if (account->flags & MUTT_ACCT_USER) > return 0; > #ifdef USE_IMAP > else if ((account->type == MUTT_ACCT_TYPE_IMAP) && ImapUser) > - strfcpy(account->user, ImapUser, sizeof(account->user)); > + mutt_str_replace(&account->user, ImapUser); > #endif > #ifdef USE_POP > else if ((account->type == MUTT_ACCT_TYPE_POP) && PopUser) > - strfcpy(account->user, PopUser, sizeof(account->user)); > + mutt_str_replace(&account->user, PopUser); > #endif > else if (option(OPTNOCURSES)) > return -1; > @@ -179,9 +214,10 @@ int mutt_account_getuser(ACCOUNT *account) > else > { > snprintf(prompt, sizeof(prompt), _("Username at %s: "), account->host); > - strfcpy(account->user, NONULL(Username), sizeof(account->user)); > - if (mutt_get_field_unbuffered(prompt, account->user, > sizeof(account->user), 0)) > + strfcpy(userbuf, NONULL(Username), sizeof(userbuf)); > + if (mutt_get_field_unbuffered(prompt, userbuf, sizeof(userbuf), 0)) > return -1; > + mutt_str_replace(&account->user, userbuf); > } > > account->flags |= MUTT_ACCT_USER; > @@ -199,7 +235,7 @@ int mutt_account_getlogin(ACCOUNT *account) > { > if (ImapLogin) > { > - strfcpy(account->login, ImapLogin, sizeof(account->login)); > + mutt_str_replace(&account->login, ImapLogin); > account->flags |= MUTT_ACCT_LOGIN; > } > } > @@ -208,7 +244,7 @@ int mutt_account_getlogin(ACCOUNT *account) > if (!(account->flags & MUTT_ACCT_LOGIN)) > { > mutt_account_getuser(account); > - strfcpy(account->login, account->user, sizeof(account->login)); > + mutt_str_replace(&account->login, account->user); > } > > account->flags |= MUTT_ACCT_LOGIN; > @@ -231,29 +267,31 @@ int _mutt_account_getpass(ACCOUNT *account, > void (*prompt_func)(char *, size_t, ACCOUNT *)) > { > char prompt[SHORT_STRING]; > + char passbuf[LONG_STRING]; > > if (account->flags & MUTT_ACCT_PASS) > return 0; > #ifdef USE_IMAP > else if ((account->type == MUTT_ACCT_TYPE_IMAP) && ImapPass) > - strfcpy(account->pass, ImapPass, sizeof(account->pass)); > + mutt_str_replace(&account->pass, ImapPass); > #endif > #ifdef USE_POP > else if ((account->type == MUTT_ACCT_TYPE_POP) && PopPass) > - strfcpy(account->pass, PopPass, sizeof(account->pass)); > + mutt_str_replace(&account->pass, PopPass); > #endif > #ifdef USE_SMTP > else if ((account->type == MUTT_ACCT_TYPE_SMTP) && SmtpPass) > - strfcpy(account->pass, SmtpPass, sizeof(account->pass)); > + mutt_str_replace(&account->pass, SmtpPass); > #endif > else if (option(OPTNOCURSES)) > return -1; > else > { > prompt_func(prompt, sizeof(prompt), account); > - account->pass[0] = '\0'; > - if (mutt_get_password(prompt, account->pass, sizeof(account->pass))) > + passbuf[0] = '\0'; > + if (mutt_get_password(prompt, passbuf, sizeof(passbuf))) > return -1; > + mutt_str_replace(&account->pass, passbuf); > } > > account->flags |= MUTT_ACCT_PASS; > diff --git a/account.h b/account.h > index 3361fdc4..137a7bb6 100644 > --- a/account.h > +++ b/account.h > @@ -44,15 +44,17 @@ enum > > typedef struct > { > - char user[128]; > - char login[128]; > - char pass[256]; > - char host[128]; > + char *user; > + char *login; > + char *pass; > + char *host; > unsigned short port; > unsigned char type; > unsigned char flags; > } ACCOUNT; > > +void mutt_account_free(ACCOUNT *account); > +void mutt_account_copy(ACCOUNT *dest, const ACCOUNT *src); > int mutt_account_match(const ACCOUNT *a1, const ACCOUNT *m2); > int mutt_account_fromurl(ACCOUNT *account, ciss_url_t *url); > void mutt_account_tourl(ACCOUNT *account, ciss_url_t *url, int force_user); > diff --git a/browser.c b/browser.c > index 77d64174..687df3a3 100644 > --- a/browser.c > +++ b/browser.c > @@ -1221,12 +1221,13 @@ void _mutt_buffer_select_file(BUFFER *f, int flags, > char ***files, int *numfiles > else > { > char msg[SHORT_STRING]; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int nentry = menu->current; > > imap_parse_path(state.entry[nentry].full_path, &mx); > if (!mx.mbox) > { > + imap_mbox_free(&mx); > mutt_error _("Cannot delete root folder"); > break; > } > @@ -1256,7 +1257,7 @@ void _mutt_buffer_select_file(BUFFER *f, int flags, > char ***files, int *numfiles > } > else > mutt_message _("Mailbox not deleted."); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > } > break; > #endif > diff --git a/imap/browse.c b/imap/browse.c > index 784eef73..22e5c4df 100644 > --- a/imap/browse.c > +++ b/imap/browse.c > @@ -53,7 +53,7 @@ int imap_browse(const char *path, struct browser_state > *state) > char ctmp; > short showparents = 0; > int save_lsub; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > > if (imap_parse_path(path, &mx)) > { > @@ -218,13 +218,13 @@ int imap_browse(const char *path, struct browser_state > *state) > if (save_lsub) > set_option(OPTIMAPCHECKSUBSCRIBED); > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > > fail: > if (save_lsub) > set_option(OPTIMAPCHECKSUBSCRIBED); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -232,7 +232,7 @@ fail: > int imap_mailbox_create(const char *folder, BUFFER *result) > { > IMAP_DATA *idata; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > char buf[LONG_STRING]; > short n; > > @@ -276,18 +276,18 @@ int imap_mailbox_create(const char *folder, BUFFER > *result) > mutt_message _("Mailbox created."); > mutt_sleep(0); > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > > fail: > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > int imap_mailbox_rename(const char *mailbox, BUFFER *result) > { > IMAP_DATA *idata; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > char buf[LONG_STRING]; > char newname[SHORT_STRING]; > > @@ -336,11 +336,11 @@ int imap_mailbox_rename(const char *mailbox, BUFFER > *result) > mutt_message(_("Mailbox renamed.")); > mutt_sleep(0); > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > > fail: > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -348,7 +348,7 @@ static int browse_add_list_result(IMAP_DATA *idata, const > char *cmd, > struct browser_state *state, short > isparent) > { > IMAP_LIST list; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int rc; > > if (imap_parse_path(state->folder, &mx)) > @@ -379,7 +379,7 @@ static int browse_add_list_result(IMAP_DATA *idata, const > char *cmd, > while (rc == IMAP_CMD_CONTINUE); > idata->cmddata = NULL; > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return rc == IMAP_CMD_OK ? 0 : -1; > } > > @@ -394,7 +394,7 @@ static void imap_add_folder(char delim, char *folder, int > noselect, > { > char tmp[LONG_STRING]; > char relpath[LONG_STRING]; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > BUFFY *b; > > if (imap_parse_path(state->folder, &mx)) > @@ -467,7 +467,7 @@ static void imap_add_folder(char delim, char *folder, int > noselect, > > (state->entrylen)++; > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > } > > static int compare_names(struct folder_file *a, struct folder_file *b) > diff --git a/imap/command.c b/imap/command.c > index 77bb7b8f..15839a3f 100644 > --- a/imap/command.c > +++ b/imap/command.c > @@ -1120,7 +1120,7 @@ static void cmd_parse_status(IMAP_DATA *idata, char *s) > char *mailbox; > char *value; > BUFFY *inc; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > unsigned long ulcount; > unsigned int count; > IMAP_STATUS *status; > @@ -1232,7 +1232,7 @@ static void cmd_parse_status(IMAP_DATA *idata, char *s) > { > value = safe_strdup(mx.mbox); > imap_fix_path(idata, mx.mbox, value, mutt_strlen(value) + 1); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > } > else > value = safe_strdup("INBOX"); > @@ -1274,6 +1274,7 @@ static void cmd_parse_status(IMAP_DATA *idata, char *s) > opened */ > status->uidnext = oldun; > > + imap_mbox_free(&mx); > FREE(&value); > return; > } > @@ -1281,7 +1282,7 @@ static void cmd_parse_status(IMAP_DATA *idata, char *s) > FREE(&value); > } > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > } > } > > diff --git a/imap/imap.c b/imap/imap.c > index a86a8379..20b80dfc 100644 > --- a/imap/imap.c > +++ b/imap/imap.c > @@ -61,7 +61,7 @@ static void imap_set_flag(IMAP_DATA *idata, int aclbit, int > flag, > int imap_access(const char *path) > { > IMAP_DATA *idata; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > char buf[LONG_STRING*2]; > char mailbox[LONG_STRING]; > char mbox[LONG_STRING]; > @@ -73,7 +73,7 @@ int imap_access(const char *path) > if (!(idata = imap_conn_find(&mx.account, > option(OPTIMAPPASSIVE) ? MUTT_IMAP_CONN_NONEW > : 0))) > { > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -84,10 +84,10 @@ int imap_access(const char *path) > /* we may already be in the folder we're checking */ > if (!ascii_strcmp(idata->mailbox, mx.mbox)) > { > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > } > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > if (imap_mboxcache_get(idata, mailbox, 0)) > { > @@ -375,7 +375,7 @@ IMAP_DATA *imap_conn_find(const ACCOUNT *account, int > flags) > if (!creds) > creds = &conn->account; > else > - memcpy(&conn->account, creds, sizeof(ACCOUNT)); > + mutt_account_copy(&conn->account, creds); > > idata = (IMAP_DATA*)conn->data; > if (flags & MUTT_IMAP_CONN_NONEW) > @@ -791,7 +791,7 @@ static int imap_open_mailbox(CONTEXT *ctx) > char buf[LONG_STRING]; > char bufout[LONG_STRING*2]; > int count = 0; > - IMAP_MBOX mx, pmx; > + IMAP_MBOX mx = { 0 }, pmx = { 0 }; > int rc; > const char *condstore; > > @@ -852,11 +852,10 @@ static int imap_open_mailbox(CONTEXT *ctx) > mutt_bit_set(idata->ctx->rights, MUTT_ACL_DELETE); > } > /* pipeline the postponed count if possible */ > - pmx.mbox = NULL; > if (mx_is_imap(Postponed) && !imap_parse_path(Postponed, &pmx) > && mutt_account_match(&pmx.account, &mx.account)) > imap_status(Postponed, 1); > - FREE(&pmx.mbox); > + imap_mbox_free(&pmx); > > #if USE_HCACHE > if (mutt_bit_isset(idata->capabilities, CONDSTORE) && > @@ -1020,14 +1019,14 @@ static int imap_open_mailbox(CONTEXT *ctx) > imap_disallow_reopen(ctx); > > muttdbg(2, "imap_open_mailbox: msgcount is %d", ctx->msgcount); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > > fail: > if (idata->state == IMAP_SELECTED) > idata->state = IMAP_AUTHENTICATED; > fail_noidata: > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -1036,7 +1035,7 @@ static int imap_open_mailbox_append(CONTEXT *ctx, int > flags) > IMAP_DATA *idata; > char buf[LONG_STRING]; > char mailbox[LONG_STRING]; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int rc; > > if (imap_parse_path(ctx->path, &mx)) > @@ -1047,7 +1046,7 @@ static int imap_open_mailbox_append(CONTEXT *ctx, int > flags) > > if (!(idata = imap_conn_find(&(mx.account), 0))) > { > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -1056,7 +1055,7 @@ static int imap_open_mailbox_append(CONTEXT *ctx, int > flags) > imap_fix_path(idata, mx.mbox, mailbox, sizeof(mailbox)); > if (!*mailbox) > strfcpy(mailbox, "INBOX", sizeof(mailbox)); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > if ((rc = imap_access(ctx->path)) == 0) > return 0; > @@ -1861,7 +1860,7 @@ static int imap_save_to_header_cache(CONTEXT *ctx, > HEADER *h) > /* split path into (idata,mailbox name) */ > static int imap_get_mailbox(const char *path, IMAP_DATA **hidata, char *buf, > size_t blen) > { > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > > if (imap_parse_path(path, &mx)) > { > @@ -1870,14 +1869,14 @@ static int imap_get_mailbox(const char *path, > IMAP_DATA **hidata, char *buf, siz > } > if (!(*hidata = imap_conn_find(&(mx.account), option(OPTIMAPPASSIVE) ? > MUTT_IMAP_CONN_NONEW : 0))) > { > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > imap_fix_path(*hidata, mx.mbox, buf, blen); > if (!*buf) > strfcpy(buf, "INBOX", blen); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > return 0; > } > @@ -2270,10 +2269,11 @@ int imap_subscribe(char *path, int subscribe) > IMAP_DATA *idata; > char buf[LONG_STRING*2]; > char mbox[LONG_STRING]; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > > if (!mx_is_imap(path) || imap_parse_path(path, &mx) || !mx.mbox) > { > + imap_mbox_free(&mx); > mutt_error(_("Bad mailbox name")); > return -1; > } > @@ -2308,11 +2308,11 @@ int imap_subscribe(char *path, int subscribe) > mutt_message(_("Subscribed to %s"), mx.mbox); > else > mutt_message(_("Unsubscribed from %s"), mx.mbox); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > > fail: > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -2395,7 +2395,7 @@ int imap_complete(char *dest, size_t dlen, const char > *path) > size_t clen; > size_t matchlen = 0; > int completions = 0; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int rc; > > if (imap_parse_path(path, &mx)) > @@ -2408,7 +2408,7 @@ int imap_complete(char *dest, size_t dlen, const char > *path) > * known mailboxes/hooks/etc */ > if (!(idata = imap_conn_find(&(mx.account), MUTT_IMAP_CONN_NONEW))) > { > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > strfcpy(dest, path, dlen); > return imap_complete_hosts(dest, dlen); > } > @@ -2467,11 +2467,11 @@ int imap_complete(char *dest, size_t dlen, const char > *path) > imap_qualify_path(dest, dlen, &mx, completion); > mutt_pretty_mailbox(dest, dlen); > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > } > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -2488,7 +2488,7 @@ int imap_fast_trash(CONTEXT *ctx, char *dest) > char mmbox[LONG_STRING]; > char prompt[LONG_STRING]; > int n, rc; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int triedcreate = 0; > BUFFER *sync_cmd = NULL; > int err_continue = MUTT_NO; > @@ -2505,7 +2505,7 @@ int imap_fast_trash(CONTEXT *ctx, char *dest) > if (!mutt_account_match(&(CTX_DATA->conn->account), &(mx.account))) > { > muttdbg(3, "%s not same server as %s", dest, ctx->path); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 1; > } > > @@ -2602,7 +2602,7 @@ int imap_fast_trash(CONTEXT *ctx, char *dest) > > out: > mutt_buffer_free(&sync_cmd); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > return rc < 0 ? -1 : rc; > } > diff --git a/imap/imap.h b/imap/imap.h > index f2035e89..efb64cb2 100644 > --- a/imap/imap.h > +++ b/imap/imap.h > @@ -65,6 +65,7 @@ void imap_logout_all(void); > int imap_expand_path(BUFFER *path); > int imap_buffer_remove_path_password(BUFFER *dest, const char *src); > int imap_parse_path(const char *path, IMAP_MBOX *mx); > +void imap_mbox_free(IMAP_MBOX *mbox); > void imap_pretty_mailbox(char *path, size_t pathlen); > > int imap_wait_keepalive(pid_t pid); > diff --git a/imap/message.c b/imap/message.c > index 1924ab21..006ae861 100644 > --- a/imap/message.c > +++ b/imap/message.c > @@ -1323,7 +1323,7 @@ int imap_append_message(CONTEXT *ctx, MESSAGE *msg) > progress_t progressbar; > size_t sent; > int c, last; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int rc; > > idata = (IMAP_DATA*) ctx->data; > @@ -1422,7 +1422,7 @@ int imap_append_message(CONTEXT *ctx, MESSAGE *msg) > if (rc != IMAP_CMD_OK) > goto cmd_step_fail; > > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return 0; > > cmd_step_fail: > @@ -1442,7 +1442,7 @@ cmd_step_fail: > > fail: > safe_fclose(&fp); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > return -1; > } > > @@ -1461,7 +1461,7 @@ int imap_copy_messages(CONTEXT *ctx, HEADER *h, const > char *dest, int delete) > char prompt[LONG_STRING]; > int rc; > int n; > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > int err_continue = MUTT_NO; > int triedcreate = 0; > > @@ -1626,7 +1626,7 @@ int imap_copy_messages(CONTEXT *ctx, HEADER *h, const > char *dest, int delete) > out: > mutt_buffer_pool_release(&sync_cmd); > mutt_buffer_pool_release(&cmd); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > return rc < 0 ? -1 : rc; > } > diff --git a/imap/util.c b/imap/util.c > index 6b9940b7..4c877f8d 100644 > --- a/imap/util.c > +++ b/imap/util.c > @@ -51,7 +51,7 @@ > * fails, which it might if there isn't enough room in the buffer. */ > int imap_expand_path(BUFFER *path) > { > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > IMAP_DATA *idata; > ciss_url_t url; > char fixedpath[LONG_STRING]; > @@ -66,14 +66,14 @@ int imap_expand_path(BUFFER *path) > url.path = fixedpath; > > rc = url_ciss_tobuffer(&url, path, U_DECODE_PASSWD); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > return rc; > } > > int imap_buffer_remove_path_password(BUFFER *dest, const char *src) > { > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > ciss_url_t url; > int rc; > > @@ -87,7 +87,7 @@ int imap_buffer_remove_path_password(BUFFER *dest, const > char *src) > > /* flags = 0 will strip the password, if present */ > rc = url_ciss_tobuffer(&url, dest, 0); > - FREE(&mx.mbox); > + imap_mbox_free(&mx); > > return rc; > } > @@ -158,7 +158,7 @@ static void imap_hcache_namer(const char *path, BUFFER > *dest) > > header_cache_t *imap_hcache_open(IMAP_DATA *idata, const char *path) > { > - IMAP_MBOX mx; > + IMAP_MBOX mx = { 0 }; > ciss_url_t url; > BUFFER *cachepath = NULL; > BUFFER *mbox = NULL; > @@ -176,7 +176,6 @@ header_cache_t *imap_hcache_open(IMAP_DATA *idata, const > char *path) > goto cleanup; > > imap_cachepath(idata, mx.mbox, mbox); > - FREE(&mx.mbox); > } > > if (strstr(mutt_b2s(mbox), "/../") || > @@ -195,6 +194,7 @@ header_cache_t *imap_hcache_open(IMAP_DATA *idata, const > char *path) > rv = mutt_hcache_open(HeaderCache, mutt_b2s(cachepath), imap_hcache_namer); > > cleanup: > + imap_mbox_free(&mx); > mutt_buffer_pool_release(&mbox); > mutt_buffer_pool_release(&cachepath); > return rv; > @@ -321,7 +321,7 @@ int imap_parse_path(const char *path, IMAP_MBOX *mx) > static unsigned short ImapPort = 0; > static unsigned short ImapsPort = 0; > struct servent *service; > - char tmp[128]; > + char tmp[128], tmp2[128]; > ciss_url_t url; > char *c; > const char *constc; > @@ -355,8 +355,9 @@ int imap_parse_path(const char *path, IMAP_MBOX *mx) > url_parse_ciss(&url, c); > if (url.scheme == U_IMAP || url.scheme == U_IMAPS) > { > - if (mutt_account_fromurl(&mx->account, &url) < 0 || !*mx->account.host) > + if (mutt_account_fromurl(&mx->account, &url) < 0 || !mx->account.host) > { > + mutt_account_free(&mx->account); > FREE(&c); > return -1; > } > @@ -385,18 +386,19 @@ int imap_parse_path(const char *path, IMAP_MBOX *mx) > if ((c = strrchr(tmp, '@'))) > { > *c = '\0'; > - strfcpy(mx->account.user, tmp, sizeof(mx->account.user)); > + mx->account.user = safe_strdup(tmp); > strfcpy(tmp, c+1, sizeof(tmp)); > mx->account.flags |= MUTT_ACCT_USER; > mx->account.flags |= MUTT_ACCT_USER_FROM_URL; > } > > - if ((n = sscanf(tmp, "%127[^:/]%127s", mx->account.host, tmp)) < 1) > + if ((n = sscanf(tmp, "%127[^:/]%127s", tmp2, tmp)) < 1) > { > muttdbg(1, "imap_parse_path: NULL host in %s", path); > - FREE(&mx->mbox); > + imap_mbox_free(mx); > return -1; > } > + mx->account.host = safe_strdup(tmp2); > > if (n > 1) > { > @@ -409,7 +411,7 @@ int imap_parse_path(const char *path, IMAP_MBOX *mx) > else > { > muttdbg(1, "imap_parse_path: Unknown connection type in %s", path); > - FREE(&mx->mbox); > + imap_mbox_free(mx); > return -1; > } > } > @@ -422,6 +424,16 @@ int imap_parse_path(const char *path, IMAP_MBOX *mx) > return 0; > } > > +/* The IMAP_MBOX structures aren't dynamically allocated, but its members > are. */ > +void imap_mbox_free(IMAP_MBOX *mbox) > +{ > + if (!mbox) > + return; > + > + mutt_account_free(&mbox->account); > + FREE(&mbox->mbox); > +} > + > /* silly helper for mailbox name string comparisons, because of INBOX */ > int imap_mxcmp(const char *mx1, const char *mx2) > { > @@ -453,7 +465,7 @@ int imap_mxcmp(const char *mx1, const char *mx2) > * look nice. */ > void imap_pretty_mailbox(char *path, size_t pathlen) > { > - IMAP_MBOX home, target; > + IMAP_MBOX home = { 0 }, target = { 0 }; > ciss_url_t url; > char *delim; > int tlen; > @@ -478,7 +490,6 @@ void imap_pretty_mailbox(char *path, size_t pathlen) > if (target.mbox[hlen] == *delim) > home_match = 1; > } > - FREE(&home.mbox); > } > > /* do the '=' substitution */ > @@ -498,7 +509,8 @@ void imap_pretty_mailbox(char *path, size_t pathlen) > url_ciss_tostring(&url, path, pathlen, 0); > } > > - FREE(&target.mbox); > + imap_mbox_free(&home); > + imap_mbox_free(&target); > } > > /* -- library functions -- */ > diff --git a/mutt_socket.c b/mutt_socket.c > index 79314fe9..5065bbdd 100644 > --- a/mutt_socket.c > +++ b/mutt_socket.c > @@ -276,6 +276,7 @@ void mutt_socket_free(CONNECTION *conn) > if (iter == conn) > { > Connections = iter->next; > + mutt_account_free(&iter->account); > FREE(&iter); > return; > } > @@ -286,6 +287,7 @@ void mutt_socket_free(CONNECTION *conn) > { > tmp = iter->next; > iter->next = tmp->next; > + mutt_account_free(&tmp->account); > FREE(&tmp); > return; > } > @@ -319,7 +321,7 @@ CONNECTION *mutt_conn_find(const CONNECTION *start, const > ACCOUNT *account) > } > > conn = socket_new_conn(); > - memcpy(&conn->account, account, sizeof(ACCOUNT)); > + mutt_account_copy(&conn->account, account); > > conn->next = Connections; > Connections = conn; > diff --git a/pop_auth.c b/pop_auth.c > index d22038d2..e3072fbd 100644 > --- a/pop_auth.c > +++ b/pop_auth.c > @@ -352,7 +352,7 @@ static pop_auth_res_t pop_auth_apop(POP_DATA *pop_data, > const char *method) > md5_init_ctx(&ctx); > md5_process_bytes(pop_data->timestamp, strlen(pop_data->timestamp), &ctx); > md5_process_bytes(pop_data->conn->account.pass, > - strlen(pop_data->conn->account.pass), &ctx); > + mutt_strlen(pop_data->conn->account.pass), &ctx); > md5_finish_ctx(&ctx, digest); > > for (i = 0; i < sizeof(digest); i++) > -- > 2.55.0 > -- <https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
