Skip to content

Commit

Permalink
net_imap: Fix keywords not persisting.
Browse files Browse the repository at this point in the history
* Properly parse filename to find start of keywords, to avoid creating
  invalid maildir filename that results in loss of keywords when
  reformatted.
* Actually process the \Answered flag, which was previously ignored.
  • Loading branch information
InterLinked1 committed Mar 19, 2024
1 parent ca02735 commit f0822b2
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 2 deletions.
4 changes: 4 additions & 0 deletions nets/net_imap/imap_server_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,10 @@ static const char *keywords_start(const char *restrict filename)
if (!flagstr++) {
return NULL;
}
/* Skip 2, before flags */
while (*flagstr == '2' || *flagstr == ',') {
flagstr++;
}
while (isupper(*flagstr)) {
flagstr++;
}
Expand Down
13 changes: 12 additions & 1 deletion nets/net_imap/imap_server_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,15 @@ int parse_flags_letters(const char *restrict f, const char **keywords)
case FLAG_TRASHED:
flags |= FLAG_BIT_DELETED;
break;
case FLAG_REPLIED:
flags |= FLAG_BIT_ANSWERED;
break;
case 'a' ... 'z':
if (keywords) {
*keywords = f;
}
return flags; /* If we encounter keywords (custom flags), we know we're done parsing builtin flags */
case FLAG_PASSED:
case FLAG_REPLIED:
default:
bbs_warning("Unhandled flag: %c\n", *f);
}
Expand Down Expand Up @@ -272,6 +274,7 @@ void gen_flag_letters(int flags, char *buf, size_t len)

SET_LETTER_IF_FLAG(FLAG_BIT_DRAFT, FLAG_DRAFT); /* D */
SET_LETTER_IF_FLAG(FLAG_BIT_FLAGGED, FLAG_FLAGGED); /* F */
SET_LETTER_IF_FLAG(FLAG_BIT_ANSWERED, FLAG_REPLIED); /* D */
SET_LETTER_IF_FLAG(FLAG_BIT_SEEN, FLAG_SEEN); /* S */
SET_LETTER_IF_FLAG(FLAG_BIT_DELETED, FLAG_TRASHED); /* T */
*buf = '\0';
Expand All @@ -284,6 +287,7 @@ void gen_flag_names(const char *flagstr, char *fullbuf, size_t len)
*buf = '\0';
SAFE_FAST_COND_APPEND(fullbuf, len, buf, left, strchr(flagstr, FLAG_DRAFT), FLAG_NAME_DRAFT);
SAFE_FAST_COND_APPEND(fullbuf, len, buf, left, strchr(flagstr, FLAG_FLAGGED), FLAG_NAME_FLAGGED);
SAFE_FAST_COND_APPEND(fullbuf, len, buf, left, strchr(flagstr, FLAG_REPLIED), FLAG_NAME_ANSWERED);
SAFE_FAST_COND_APPEND(fullbuf, len, buf, left, strchr(flagstr, FLAG_SEEN), FLAG_NAME_SEEN);
SAFE_FAST_COND_APPEND(fullbuf, len, buf, left, strchr(flagstr, FLAG_TRASHED), FLAG_NAME_DELETED);
SAFE_FAST_COND_APPEND(fullbuf, len, buf, left, strchr(flagstr, FLAG_RECENT), FLAG_NAME_RECENT);
Expand Down Expand Up @@ -434,6 +438,13 @@ int maildir_msg_setflags_modseq(struct imap_session *imap, int seqno, const char
return -1;
}

if (strchr(newflagletters, ',')) {
/* This should just contain upper and lower case letters.
* If there's a comma, something got concatenated wrong somewhere,
* and we'll create an invalid maildir filename. */
bbs_warning("Invalid flag letters: '%s'\n", newflagletters);
}

/* First, check if the filename itself would actually change, without updating MODSEQ.
* If not, then don't update MODSEQ, or do any rename at all. */
snprintf(fullfilename, sizeof(fullfilename), "%s/%s:2,%s", dirpath, filename, newflagletters);
Expand Down
2 changes: 1 addition & 1 deletion nets/net_imap/imap_server_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
/* maildir flags, that appear in a single string and must appear in ASCII order: https://cr.yp.to/proto/maildir.html */
#define FLAG_DRAFT 'D'
#define FLAG_FLAGGED 'F'
#define FLAG_PASSED 'P'
#define FLAG_PASSED 'P' /* Not currently used anywhere */
#define FLAG_REPLIED 'R'
#define FLAG_SEEN 'S'
#define FLAG_TRASHED 'T'
Expand Down

0 comments on commit f0822b2

Please sign in to comment.