> 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>

Attachment: signature.asc
Description: PGP signature

Reply via email to