Skip to content

Commit

Permalink
viewer, editor: Various robustness and UX improvements.
Browse files Browse the repository at this point in the history
* viewer.c: Fix was_unicode calculation to avoid spurious aborts.
* Reduce FETCHLIST interval, since even an interval of 180
  can take up to 15 seconds to load a folder.
* SMTP: Don't send addresses with double <<>> for RCPT.
* editor: Add spaces at beginning of quoted lines, as with viewer, for
  readability.
* editor: Fix erroneous extra spaces at end of format=flowed lines,
  caused by duplicate logic that would add a space in this case.
* editor: Distinguish between message not sent and sent but not saved.
* imap: Avoid infinite loop by breaking early if flushed input is empty.
* IMAP APPEND: Fix memory leak of flags.
  • Loading branch information
InterLinked1 committed Apr 26, 2024
1 parent c485687 commit 4bcb2c7
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 12 deletions.
38 changes: 29 additions & 9 deletions editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,8 @@ static int send_message(struct client *client, FIELD *fields[NUM_FIELDS + 1], st
increment_stats_by_size(client->sent_mbox, msglen, 0);
increment_stats_by_size(&client->mailboxes[0], msglen, 0); /* Aggregate stats */
}
} else {
res = 2;
}
}
}
Expand Down Expand Up @@ -811,6 +813,13 @@ static void format_and_quote_body(FORM *form, const char *body, int addquotes)
#endif
if (!strncmp(s, "\r\n", 2)) {
if (outputcol > 0 && s[-1] == ' ' && *(s + 2) && next_n_quotes(s + 2, quote_depth)) {
/* We just printed the format=flowed space at the end of the input line,
* but that conflicts with this path:
* if (addquotes && inputcol == 0 && quote_depth == 0) {
*/
form_driver(form, REQ_DEL_PREV);
outputcol--;

client_debug(9, "format=flowed line break on row %d, col %d", row, outputcol);
/* This is a format=flowed soft line wrap, don't actually wrap */
s += STRLEN("\r\n"); /* Skip CR LF */
Expand All @@ -820,6 +829,9 @@ static void format_and_quote_body(FORM *form, const char *body, int addquotes)
/* Skip space, since we already printed the format=flowed space at end of previous line */
inputcol++;
s++;
client_debug(9, "Skipped format=flowed space, next character is '%c'", *s);
} else {
client_debug(9, "Didn't skip format=flowed space, next character is '%c'", *s);
}
/* Resume */
} else {
Expand Down Expand Up @@ -853,14 +865,18 @@ static void format_and_quote_body(FORM *form, const char *body, int addquotes)
last_sp = memrchr(s - outputcol, ' ', outputcol);
if (last_sp) {
int diff = s - 1 - last_sp;
client_debug(9, "Backing up %d characters", diff);
for (j = 0; j < diff; j++) {
form_driver(form, REQ_DEL_PREV);
if (diff < outputcol - 2) {
client_debug(9, "Backing up %d characters", diff);
for (j = 0; j < diff; j++) {
form_driver(form, REQ_DEL_PREV);
}
/* Back up and break the line there instead */
s -= diff;
outputcol -= diff;
inputcol -= diff;
} else {
client_debug(1, "Can't wrap this line: %d/%d", diff, outputcol);
}
/* Back up and break the line there instead */
s -= diff;
outputcol -= diff;
inputcol -= diff;
}
outputcol = 0;
form_driver(form, REQ_NEW_LINE);
Expand All @@ -871,7 +887,7 @@ static void format_and_quote_body(FORM *form, const char *body, int addquotes)
for (j = 0; j < quote_depth; j++) {
FORM_PUTC('>');
}
if (quote_depth) { /* Condition added since down below we also add a space, but only if quote_depth is 0 */
if (quote_depth || *s != ' ') { /* Condition added since down below we also add a space, but only if quote_depth is 0 */
/* Ensure there's a space after the quotes before continuing */
FORM_PUTC(' ');
}
Expand Down Expand Up @@ -901,6 +917,10 @@ static void format_and_quote_body(FORM *form, const char *body, int addquotes)
int linelen = line_len(s);
in_quotes = 0;
client_debug(10, "Quote depth of row %d is %d (%d chars left on line)", row, quote_depth, linelen);
/* It doesn't start with space, add one for readability */
if (*s != ' ') {
FORM_PUTC(' ');
}
}
}
if (addquotes && inputcol == 0 && quote_depth == 0) {
Expand Down Expand Up @@ -2093,7 +2113,7 @@ static int __editor(struct client *client, struct pollfd *pfds, uint32_t uid, st
if (res < 0) {
goto done;
} else if (res > 0) {
client_set_status_nout(client, msgc.error[0] ? msgc.error : "Error sending message");
client_set_status_nout(client, msgc.error[0] ? msgc.error : res == 2 ? "Sent, error saving message" : "Error sending message");
beep();
if (needresize) {
goto resize;
Expand Down
2 changes: 1 addition & 1 deletion evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ static void adjust_start_seqno(struct client *client, uint32_t current, int offs
/* Going up */
uint32_t max_start_seqno;

if (client->sel_mbox->total > FETCHLIST_INTERVAL) {
if (client->sel_mbox->total > (uint32_t) FETCHLIST_INTERVAL) {
max_start_seqno = client->sel_mbox->total - FETCHLIST_INTERVAL;
} else {
max_start_seqno = 1;
Expand Down
2 changes: 1 addition & 1 deletion evergreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* In return, more messages can be scrolled at once without
* having to re-download another set of headers.
*/
#define FETCHLIST_INTERVAL 180
#define FETCHLIST_INTERVAL (2 * LINES)

/* Window dimension settings */
#define MIN_COLS_FOR_EXPANDED_LIST_INFO 97
Expand Down
18 changes: 18 additions & 0 deletions imap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2298,6 +2298,10 @@ static int client_flush_pending_output(struct client *client)
line = mailimap_read_line(client->imap);
/* Read and discard */
client_debug(1, "Flushing output '%s'", line);
if (strlen_zero(line)) {
/* Avoid infinite loop if we keep reading nothing */
break;
}
} else {
break;
}
Expand Down Expand Up @@ -2879,6 +2883,8 @@ static int __handle_store(struct client *client, int sign, struct mailimap_set *
int res;
struct mailimap_store_att_flags *att_flags;

assert(!client->idling);

if (sign > 0) {
att_flags = mailimap_store_att_flags_new_add_flags_silent(flag_list);
} else {
Expand Down Expand Up @@ -2909,6 +2915,8 @@ int client_store(struct client *client, int sign, struct message *msg, int flags
struct mailimap_flag_list *flag_list;
struct mailimap_set *set;

assert(!client->idling);

if (msg) {
set = mailimap_set_new_single(msg->uid);
} else {
Expand Down Expand Up @@ -2954,6 +2962,8 @@ int client_store_keyword(struct client *client, int sign, struct message *msg, c
char *keyword_dup = NULL;
struct mailimap_flag *flag;

assert(!client->idling);

if (msg) {
set = mailimap_set_new_single(msg->uid);
} else {
Expand Down Expand Up @@ -2993,6 +3003,8 @@ int client_copy(struct client *client, struct message *msg, const char *newmbox)
int res;
struct mailimap_set *set;

assert(!client->idling);

client_debug(3, "=> COPY %u %s\n", msg->uid, newmbox);
set = mailimap_set_new_single(msg->uid);
if (!set) {
Expand All @@ -3013,6 +3025,8 @@ int client_move(struct client *client, struct message *msg, const char *newmbox)
int res;
struct mailimap_set *set;

assert(!client->idling);

client_debug(3, "=> MOVE %u %s", msg->uid, newmbox);
set = mailimap_set_new_single(msg->uid);
if (!set) {
Expand Down Expand Up @@ -3041,6 +3055,7 @@ int client_move(struct client *client, struct message *msg, const char *newmbox)

int client_expunge(struct client *client)
{
assert(!client->idling);
return mailimap_expunge(client->imap);
}

Expand All @@ -3049,6 +3064,8 @@ int client_append(struct client *client, const char *mailbox, int flags, const c
int res;
struct mailimap_flag_list *flag_list;

assert(!client->idling);

/* Automark anything we upload as \Seen */
flag_list = mailimap_flag_list_new_empty();
if (flags & IMAP_MESSAGE_FLAG_SEEN) {
Expand All @@ -3059,6 +3076,7 @@ int client_append(struct client *client, const char *mailbox, int flags, const c
}

res = mailimap_append(client->imap, mailbox, flag_list, NULL, msg, len);
mailimap_flag_list_free(flag_list);
if (res != MAILIMAP_NO_ERROR) {
client_warning("APPEND failed: %s", maildriver_strerror(res));
return -1;
Expand Down
8 changes: 8 additions & 0 deletions smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ static int add_recipients(struct message_constructor *msgc, struct mailsmtp *smt
client_debug(3, "Malformed recipient?");
continue;
}
/* mailesmtp_rcpt does not want <> surrounding the address, strip em here */
*recipient++ = '\0';
tmp = strchr(recipient, '>');
if (!tmp) {
client_debug(3, "Malformed recipient?");
continue;
}
*tmp = '\0';
} else {
/* The spaces we trimmed must have been at the end */
}
Expand Down
6 changes: 5 additions & 1 deletion viewer.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ static int pad_add(WINDOW *pad, const char *restrict data, size_t len, int flags
client_debug(1, "WARNING: Parsed NUL character in message output?");
break;
}
#if 0
/* Extra extra debug for assertion failures: */
client_debug(5, "outputcol is %d, at row %d, col %d (char %d: '%c')", outputcol, y, x, *c, isprint(*c) ? *c : ' ');
#endif
if (x != outputcol) {
client_debug(1, "WARNING! outputcol is %d, but actually at row %d, col %d? (char %d: '%c')", outputcol, y, x, *c, isprint(*c) ? *c : ' ');
if (*c <= 127) {
Expand All @@ -228,7 +232,7 @@ static int pad_add(WINDOW *pad, const char *restrict data, size_t len, int flags
was_unicode = 0;
}
} else {
was_unicode = 0;
was_unicode = *c >= 128;
}
if (*c == '\r') {
outputcol--; /* We're not drawing anything, and loop post will increment again */
Expand Down

0 comments on commit 4bcb2c7

Please sign in to comment.