Skipped 2 existing revision(s) on branch '1.4'.

commit 444601a1e07b8b3e74a4a20b31c71b16f3c61994
Merge: a86e6f8 ed3bfda
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Thu Jun 3 11:04:56 2021 +0200

    Merge branch '1.3' into 1.4
    
    Conflicts:
            configure.ac
            src/drv_imap.c

 src/drv_imap.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --cc src/drv_imap.c
index edae95c,4cc3b2a..3c85c4d
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@@ -110,142 -94,111 +110,141 @@@ typedef struct 
  
  typedef struct imap_cmd imap_cmd_t;
  
 -struct imap_store {
 +union imap_store {
        store_t gen;
 -      const char *label; /* foreign */
 -      const char *prefix;
 -      const char *name;
 -      int ref_count;
 -      uint opts;
 -      enum { SST_BAD, SST_HALF, SST_GOOD } state;
 -      /* trash folder's existence is not confirmed yet */
 -      enum { TrashUnknown, TrashChecking, TrashKnown } trashnc;
 -      uint got_namespace:1;
 -      char delimiter[2]; /* hierarchy delimiter */
 -      list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
 -      string_list_t *boxes; // _list results
 -      char listed; // was _list already run with these flags?
 -      // note that the message counts do _not_ reflect stats from msgs,
 -      // but mailbox totals. also, don't trust them beyond the initial load.
 -      int total_msgs, recent_msgs;
 -      uint uidvalidity, uidnext;
 -      message_t *msgs;
 -      message_t **msgapp; /* FETCH results */
 -      uint caps; /* CAPABILITY results */
 -      string_list_t *auth_mechs;
 -      parse_list_state_t parse_list_sts;
 -      /* command queue */
 -      int nexttag, num_in_progress;
 -      imap_cmd_t *pending, **pending_append;
 -      imap_cmd_t *in_progress, **in_progress_append;
 -      int buffer_mem; /* memory currently occupied by buffers in the queue */
 -
 -      /* Used during sequential operations like connect */
 -      enum { GreetingPending = 0, GreetingBad, GreetingOk, GreetingPreauth } 
greeting;
 -      int expectBYE; /* LOGOUT is in progress */
 -      int expectEOF; /* received LOGOUT's OK or unsolicited BYE */
 -      int canceling; /* imap_cancel() is in progress */
 -      union {
 -              void (*imap_open)( int sts, void *aux );
 -              void (*imap_cancel)( void *aux );
 -      } callbacks;
 -      void *callback_aux;
 +      struct {
 +              STORE(union imap_store)
 +              const char *label;  // foreign
 +              const char *name;
 +              char *prefix;
 +              uint ref_count;
 +              uint opts;
 +              enum { SST_BAD, SST_HALF, SST_GOOD } state;
 +              // The trash folder's existence is not confirmed yet
 +              enum { TrashUnknown, TrashChecking, TrashKnown } trashnc;
 +              // What kind of BODY-less FETCH response we're expecting
 +              enum { FetchNone, FetchMsgs, FetchUidNext } fetch_sts;
 +              uint got_namespace:1;
 +              uint has_forwarded:1;
 +              char delimiter[2];  // Hierarchy delimiter
 +              char *ns_prefix, ns_delimiter;  // NAMESPACE info
 +              string_list_t *boxes;  // _list results
 +              char listed;  // was _list already run with these flags?
 +              // note that the message counts do _not_ reflect stats from 
msgs,
 +              // but mailbox totals.
 +              int total_msgs, recent_msgs;
 +              uint uidvalidity, uidnext;
 +              imap_message_t **msgapp, *msgs;  // FETCH results
 +              uint caps;  // CAPABILITY results
 +              string_list_t *auth_mechs;
 +              parse_list_state_t parse_list_sts;
 +              // Command queue
 +              imap_cmd_t *pending, **pending_append;
 +              imap_cmd_t *in_progress, **in_progress_append;
 +              imap_cmd_t *wait_check, **wait_check_append;
 +              int nexttag, num_in_progress, num_wait_check;
 +              uint buffer_mem;  // Memory currently occupied by buffers in 
the queue
 +
 +              // Used during sequential operations like connect
 +              enum { GreetingPending = 0, GreetingBad, GreetingOk, 
GreetingPreauth } greeting;
 +              int expectBYE;  // LOGOUT is in progress
 +              int expectEOF;  // received LOGOUT's OK or unsolicited BYE
 +              int canceling;  // imap_cancel() is in progress
 +              union {
 +                      void (*imap_open)( int sts, void *aux );
 +                      void (*imap_cancel)( void *aux );
 +              } callbacks;
 +              void *callback_aux;
  #ifdef HAVE_LIBSASL
 -      sasl_conn_t *sasl;
 -      int sasl_cont;
 +              sasl_conn_t *sasl;
 +              int sasl_cont;
  #endif
  
 -      void (*bad_callback)( void *aux );
 -      void *bad_callback_aux;
 +              void (*bad_callback)( void *aux );
 +              void *bad_callback_aux;
  
 -      conn_t conn; /* this is BIG, so put it last */
 +              conn_t conn;  // This is BIG, so put it last
 +      };
  };
  
 -struct imap_cmd {
 -      struct imap_cmd *next;
 -      char *cmd;
 -      int tag;
 -
 -      struct {
 -              /* Will be called on each continuation request until it resets 
this pointer.
 -               * Needs to invoke bad_callback and return -1 on error, 
otherwise return 0. */
 -              int (*cont)( imap_store_t *ctx, imap_cmd_t *cmd, const char 
*prompt );
 -              void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response 
);
 -              char *data;
 -              int data_len;
 -              uint uid; /* to identify fetch responses */
 -              char high_prio; /* if command is queued, put it at the front of 
the queue. */
 -              char to_trash; /* we are storing to trash, not current. */
 -              char create; /* create the mailbox if we get an error which 
suggests so. */
 -              char failok; /* Don't complain about NO response. */
 -              char lastuid; /* querying the last UID in the mailbox. */
 +#define IMAP_CMD \
 +      struct imap_cmd *next; \
 +      char *cmd; \
 +      int tag; \
 +      \
 +      struct { \
 +              /* Will be called on each continuation request until it resets 
this pointer. \
 +               * Needs to invoke bad_callback and return -1 on error, 
otherwise return 0. */ \
 +              int (*cont)( imap_store_t *ctx, imap_cmd_t *cmd, const char 
*prompt ); \
 +              void (*done)( imap_store_t *ctx, imap_cmd_t *cmd, int response 
); \
 +              char *data; \
 +              uint data_len; \
 +              uint uid;  /* to identify fetch responses */ \
 +              char high_prio;  /* if command is queued, put it at the front 
of the queue. */ \
 +              char wait_check;  /* Don't report success until subsequent 
CHECK success. */ \
 +              char to_trash;  /* we are storing to trash, not current. */ \
 +              char create;  /* create the mailbox if we get an error which 
suggests so. */ \
 +              char failok;  /* Don't complain about NO response. */ \
        } param;
 +
 +struct imap_cmd {
 +      IMAP_CMD
  };
  
 -typedef struct {
 -      imap_cmd_t gen;
 -      void (*callback)( int sts, void *aux );
 +#define IMAP_CMD_SIMPLE \
 +      IMAP_CMD \
 +      void (*callback)( int sts, void *aux ); \
        void *callback_aux;
 +
 +typedef union {
 +      imap_cmd_t gen;
 +      struct {
 +              IMAP_CMD_SIMPLE
 +      };
  } imap_cmd_simple_t;
  
 -typedef struct {
 +typedef union {
        imap_cmd_simple_t gen;
 -      msg_data_t *msg_data;
 +      struct {
 +              IMAP_CMD_SIMPLE
 +              msg_data_t *msg_data;
 +      };
  } imap_cmd_fetch_msg_t;
  
 -typedef struct {
 +typedef union {
        imap_cmd_t gen;
 -      void (*callback)( int sts, uint uid, void *aux );
 -      void *callback_aux;
 +      struct {
 +              IMAP_CMD
 +              void (*callback)( int sts, uint uid, void *aux );
 +              void *callback_aux;
-               uint out_uid;
 +      };
  } imap_cmd_out_uid_t;
  
 -typedef struct {
 +typedef union {
        imap_cmd_t gen;
 -      void (*callback)( int sts, message_t *msgs, void *aux );
 -      void *callback_aux;
 -      message_t **out_msgs;
 -      uint uid;
 +      struct {
 +              IMAP_CMD
 +              void (*callback)( int sts, message_t *msgs, void *aux );
 +              void *callback_aux;
 +              imap_message_t **out_msgs;
 +              uint uid;
 +      };
  } imap_cmd_find_new_t;
  
 -typedef struct {
 -      int ref_count;
 +#define IMAP_CMD_REFCOUNTED_STATE \
 +      uint ref_count; \
        int ret_val;
 -} imap_cmd_refcounted_state_t;
  
  typedef struct {
 +      IMAP_CMD_REFCOUNTED_STATE
 +} imap_cmd_refcounted_state_t;
 +
 +typedef union {
        imap_cmd_t gen;
 -      imap_cmd_refcounted_state_t *state;
 +      struct {
 +              IMAP_CMD
 +              imap_cmd_refcounted_state_t *state;
 +      };
  } imap_cmd_refcounted_t;
  
  #define CAP(cap) (ctx->caps & (1 << (cap)))
@@@ -1283,17 -1181,24 +1282,28 @@@ parse_response_code( imap_store_t *ctx
                /* RFC2060 says that these messages MUST be displayed
                 * to the user
                 */
 -              for (; isspace( (uchar)*p ); p++);
 -              error( "*** IMAP ALERT *** %s\n", p );
 +              if (!s) {
 +                      error( "IMAP error: malformed ALERT status\n" );
 +                      return RESP_CANCEL;
 +              }
 +              for (; isspace( (uchar)*s ); s++);
 +              error( "*** IMAP ALERT *** %s\n", s );
-       } else if (cmd && !strcmp( "APPENDUID", arg )) {
+       } else if (!strcmp( "APPENDUID", arg )) {
+               // The checks ensure that:
+               // - cmd => this is the final tagged response of a command, at 
which
+               //   point cmd was already removed from ctx->in_progress, so 
param.uid
+               //   is available for reuse.
+               // - !param.uid => the command isn't actually a FETCH. This 
doesn't
+               //   really matter, as the field is safe to overwrite given the
+               //   previous condition; it just has no effect for non-APPENDs.
+               if (!cmd || cmd->param.uid) {
+                       error( "IMAP error: unexpected APPENDUID status\n" );
+                       return RESP_CANCEL;
+               }
                if (!(arg = next_arg( &s )) ||
                    (ctx->uidvalidity = strtoul( arg, &earg, 10 ), *earg) ||
                    !(arg = next_arg( &s )) ||
-                   (((imap_cmd_out_uid_t *)cmd)->out_uid = strtoul( arg, 
&earg, 10 ), *earg != ']'))
 -                  (cmd->param.uid = strtoul( arg, &earg, 10 ), *earg))
++                  (cmd->param.uid = strtoul( arg, &earg, 10 ), *earg != ']'))
                {
                        error( "IMAP error: malformed APPENDUID status\n" );
                        return RESP_CANCEL;
@@@ -3165,15 -2965,14 +3175,14 @@@ imap_store_msg( store_t *gctx, msg_data
  
        INIT_IMAP_CMD(imap_cmd_out_uid_t, cmd, cb, aux)
        ctx->buffer_mem += data->len;
 -      cmd->gen.param.data_len = data->len;
 -      cmd->gen.param.data = data->data;
 +      cmd->param.data_len = data->len;
 +      cmd->param.data = data->data;
-       cmd->out_uid = 0;
  
        if (to_trash) {
 -              cmd->gen.param.create = 1;
 -              cmd->gen.param.to_trash = 1;
 +              cmd->param.create = 1;
 +              cmd->param.to_trash = 1;
                if (prepare_trash( &buf, ctx ) < 0) {
 -                      cb( DRV_BOX_BAD, -1, aux );
 +                      cb( DRV_BOX_BAD, 0, aux );
                        return;
                }
        } else {
@@@ -3203,7 -2999,7 +3212,7 @@@ imap_store_msg_p2( imap_store_t *ctx AT
        imap_cmd_out_uid_t *cmdp = (imap_cmd_out_uid_t *)cmd;
  
        transform_msg_response( &response );
-       cmdp->callback( response, cmdp->out_uid, cmdp->callback_aux );
 -      cmdp->callback( response, cmdp->gen.param.uid, cmdp->callback_aux );
++      cmdp->callback( response, cmdp->param.uid, cmdp->callback_aux );
  }
  
  /******************* imap_find_new_msgs *******************/

===== Full diff against 1st parent =====

diff --git a/src/drv_imap.c b/src/drv_imap.c
index edae95c..3c85c4d 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -217,7 +217,6 @@ typedef union {
                IMAP_CMD
                void (*callback)( int sts, uint uid, void *aux );
                void *callback_aux;
-               uint out_uid;
        };
 } imap_cmd_out_uid_t;
 
@@ -1289,11 +1288,22 @@ parse_response_code( imap_store_t *ctx, imap_cmd_t 
*cmd, char *s )
                }
                for (; isspace( (uchar)*s ); s++);
                error( "*** IMAP ALERT *** %s\n", s );
-       } else if (cmd && !strcmp( "APPENDUID", arg )) {
+       } else if (!strcmp( "APPENDUID", arg )) {
+               // The checks ensure that:
+               // - cmd => this is the final tagged response of a command, at 
which
+               //   point cmd was already removed from ctx->in_progress, so 
param.uid
+               //   is available for reuse.
+               // - !param.uid => the command isn't actually a FETCH. This 
doesn't
+               //   really matter, as the field is safe to overwrite given the
+               //   previous condition; it just has no effect for non-APPENDs.
+               if (!cmd || cmd->param.uid) {
+                       error( "IMAP error: unexpected APPENDUID status\n" );
+                       return RESP_CANCEL;
+               }
                if (!(arg = next_arg( &s )) ||
                    (ctx->uidvalidity = strtoul( arg, &earg, 10 ), *earg) ||
                    !(arg = next_arg( &s )) ||
-                   (((imap_cmd_out_uid_t *)cmd)->out_uid = strtoul( arg, 
&earg, 10 ), *earg != ']'))
+                   (cmd->param.uid = strtoul( arg, &earg, 10 ), *earg != ']'))
                {
                        error( "IMAP error: malformed APPENDUID status\n" );
                        return RESP_CANCEL;
@@ -3167,7 +3177,6 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
        ctx->buffer_mem += data->len;
        cmd->param.data_len = data->len;
        cmd->param.data = data->data;
-       cmd->out_uid = 0;
 
        if (to_trash) {
                cmd->param.create = 1;
@@ -3203,7 +3212,7 @@ imap_store_msg_p2( imap_store_t *ctx ATTR_UNUSED, 
imap_cmd_t *cmd, int response
        imap_cmd_out_uid_t *cmdp = (imap_cmd_out_uid_t *)cmd;
 
        transform_msg_response( &response );
-       cmdp->callback( response, cmdp->out_uid, cmdp->callback_aux );
+       cmdp->callback( response, cmdp->param.uid, cmdp->callback_aux );
 }
 
 /******************* imap_find_new_msgs *******************/


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to