diff --git a/.gitmessage b/.gitmessage new file mode 100644 index 0000000..ac6a0d7 --- /dev/null +++ b/.gitmessage @@ -0,0 +1,6 @@ +# TITLE +# No more than 50 chars ##### 50 chars is here: # + +# Leave a blank line between title and body +# BODY +# Wrap at 72 chars ################################ 72 chars is here: # diff --git a/configure.ac b/configure.ac index 4b1d6fe..6974638 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # $Id$ -AC_INIT(fdm, 2.2) -RELEASE=2.2 +AC_INIT(fdm_i, 2.2i.0) +RELEASE=2.2i.0 AC_SUBST(RELEASE) AC_CONFIG_AUX_DIR(etc) diff --git a/imap-common.c b/imap-common.c index a086992..cf41caa 100644 --- a/imap-common.c +++ b/imap-common.c @@ -1150,7 +1150,7 @@ imap_state_gmext_start(struct account *a, struct fetch_ctx *fctx) struct mail *m = fctx->mail; struct fetch_imap_mail *aux = m->auxdata; - if (imap_putln(a, "%u FETCH %u (X-GM-MSGID X-GM-THRID X-GM-LABELS)", + if (imap_putln(a, "%u UID FETCH %u (X-GM-MSGID X-GM-THRID X-GM-LABELS)", ++data->tag, aux->uid) != 0) return (FETCH_ERROR); @@ -1169,6 +1169,12 @@ imap_state_gmext_body(struct account *a, struct fetch_ctx *fctx) u_int n; uint64_t thrid, msgid; size_t lblen; + // 0. new variables + struct fetch_imap_mail *aux = m->auxdata; /* required to know what is the current UID */ + char uid_search_buffer[32]; + char *uid_terminator; + char original_char; + unsigned int guid; for (;;) { if (imap_getln(a, fctx, IMAP_RAW, &line) != 0) @@ -1193,10 +1199,36 @@ imap_state_gmext_body(struct account *a, struct fetch_ctx *fctx) if ((lb = strchr(lb, '(')) == NULL) return (imap_invalid(a, line)); lb++; /* drop '(' */ + + // 1. Find the unique UID terminator: " UID n)" where n is aux->uid + if (snprintf(uid_search_buffer, sizeof(uid_search_buffer), " UID %u)", aux->uid) <= 0) + return (imap_invalid(a, line)); + + uid_terminator = strstr(line, uid_search_buffer); + if (uid_terminator == NULL) + return (imap_invalid(a, line)); + + // 2. Temporarily null-terminate the string before " UID n)" + original_char = *uid_terminator; + *uid_terminator = '\0'; + lblen = strlen(lb); - if (lblen < 2 || lb[lblen - 1] != ')' || lb[lblen - 2] != ')') - return (imap_invalid(a, line)); - lblen -= 2; /* drop '))' from the end */ + + // 3. Handle empty labels () and non-empty labels (check + strip trailing ')') + if (lblen == 1 && lb[0] == ')') { + lblen = 0; // No labels found (a gmail label is like a virtual IMAP folder), set length to zero + } + else { + // Non-empty labels: check for final ')' and remove it + if (lblen < 2 || lb[lblen - 1] != ')') { + *uid_terminator = original_char; // bring back original terminator + return (imap_invalid(a, line)); + } + lblen -= 1; // drop ')' from the end + } + + // 4. Restore the character temporarily overwritten + *uid_terminator = original_char; // maybe necessary for logging add_tag(&m->tags, "gmail_msgid", "%llu", msgid); add_tag(&m->tags, "gmail_thrid", "%llu", thrid);