fix mixing MaxMessages with MaxSize

this is actually a useful combination for resource-constrained devices.
This commit is contained in:
Oswald Buddenhagen 2022-02-22 16:42:22 +01:00
parent 882c9825cd
commit 8f39d06015
3 changed files with 152 additions and 3 deletions

2
NEWS
View File

@ -9,6 +9,8 @@ is now the file's containing directory.
Placeholders will be now created for messages exceeding MaxSize even if Placeholders will be now created for messages exceeding MaxSize even if
they are flagged on the source side. they are flagged on the source side.
MaxMessages and MaxSize can be used together now.
The unfiltered list of mailboxes in each Store can be printed now. The unfiltered list of mailboxes in each Store can be printed now.
A proper summary is now printed prior to exiting. A proper summary is now printed prior to exiting.

View File

@ -1313,6 +1313,131 @@ my @X38 = (
); );
test("max messages + expunge", \@x38, \@X38, \@O38); test("max messages + expunge", \@x38, \@X38, \@O38);
# Expiration with size restriction tests
my @x40 = (
P, 0, P,
A, "**", "*>", "*?",
B, "**", "*>", "*S?",
C, "**", "*>S", "*S?",
D, "*S*", "*>S", "*S?",
E, "*S*", "*>", "*S?",
F, "*S*", "*>S", "*?",
G, "*S*", "*>", "*?",
H, "**", "*>S", "*?",
I, "*F*", "*>", "*?",
J, "*F*", "*>", "*S?",
K, "*F*", "*>S", "*S?",
L, "*FS*", "*>S", "*S?",
M, "*FS*", "*>", "*S?",
N, "*FS*", "*>S", "*?",
O, "*FS*", "*>", "*?",
P, "*F*", "*>S", "*?",
Q, "**", "", "",
R, "*FS*", "", "",
S, "*S*", "", "",
T, "**", "", "",
U, "*FS*", "", "",
V, "*S*", "", "",
);
my @O41 = ("", "", "MaxSize 1k\nMaxMessages 3\nExpireUnread no\n");
my @X41 = (
V, S, V,
C, "", "-S", "-S",
D, "", "+~", "+T",
E, "", "+~S", "+T",
F, "-S", "-S", "",
G, "", "+~S", "+ST",
H, "", "-S", "",
K, "", "-S", "-S",
M, "", "+S", "",
N, "-S", "-S", "",
O, "", "+S", "+S",
P, "", "-S", "",
Q, "", "*>", "*?",
R, "", "*>S", "*S?",
T, "", "*>", "*?",
U, "", "*>S", "*S?",
V, "", "*>S", "*S?",
);
test("max size without upgrade + max messages", \@x40, \@X41, \@O41);
my @x42 = (
T, Q, T,
A, "**", "*>", "*F?",
B, "**", "*>", "*FS?",
C, "**", "*>S", "*FS?",
D, "*S*", "*>S", "*FS?",
E, "*S*", "*>", "*FS?",
F, "*S*", "*>S", "*F?",
G, "*S*", "*>", "*F?",
H, "**", "*>S", "*F?",
I, "*F*", "*>", "*F?",
J, "*F*", "*>", "*FS?",
K, "*F*", "*>S", "*FS?",
L, "*FS*", "*>S", "*FS?",
M, "*FS*", "*>", "*FS?",
N, "*FS*", "*>S", "*F?",
O, "*FS*", "*>", "*F?",
P, "*F*", "*>S", "*F?",
Q, "*S", "", "",
R, "*", "*", "*",
S, "*", "*", "*",
T, "*", "*", "*",
);
my @X43 = (
T, Q, P,
A, "", ">->", "^*",
A, "&", "^", "&1+T",
B, "", ">->", "^*",
B, "&", "^", "&1+T",
C, "", ">->S", "^*",
C, "&", "^", "&1+T",
D, "", "/", "",
D, "&", "^", "&1+T",
E, "", "/", "",
E, "&", "^", "&1+T",
F, "-S", ">->S", "^*",
F, "&", "^", "&1+T",
G, "", "/", "",
G, "&", "^", "&1+T",
H, "", ">->S", "^*",
H, "&", "^", "&1+T",
I, "", ">->+F", "^F*",
I, "&", "^", "&1+T",
J, "", ">->+F", "^F*",
J, "&", "^", "&1+T",
K, "", ">->S+F", "^F*",
K, "&", "^", "&1+T",
L, "", ">->+F", "^FS*",
L, "&", "^", "&1+T",
M, "", ">->+FS", "^FS*",
M, "&", "^", "&1+T",
N, "-S", ">->S+F", "^F*",
N, "&", "^", "&1+T",
O, "", ">->+FS", "^FS*",
O, "&", "^", "&1+T",
P, "", ">->S+F", "^F*",
P, "&", "^", "&1+T",
);
test("max size with upgrade + max messages", \@x42, \@X43, \@O41);
# Test for legacy/tampered states with inaccurate maxuid tracking # Test for legacy/tampered states with inaccurate maxuid tracking
# Joined post-push & post-pull state to have just one test - # Joined post-push & post-pull state to have just one test -

View File

@ -799,7 +799,9 @@ box_opened2( sync_vars_t *svars, int t )
svars->any_expiring = 1; svars->any_expiring = 1;
if (svars->any_expiring) { if (svars->any_expiring) {
opts[N] |= OPEN_OLD | OPEN_FLAGS; opts[N] |= OPEN_OLD | OPEN_FLAGS;
if (chan->ops[N] & (OP_NEW | OP_RENEW)) if (any_dummies[N])
opts[F] |= OPEN_OLD | OPEN_FLAGS;
else if (chan->ops[N] & (OP_NEW | OP_RENEW))
opts[F] |= OPEN_FLAGS; opts[F] |= OPEN_FLAGS;
} }
svars->opts[F] = svars->drv[F]->prepare_load_box( ctx[F], opts[F] ); svars->opts[F] = svars->drv[F]->prepare_load_box( ctx[F], opts[F] );
@ -1284,10 +1286,30 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
// to expire in the first place. // to expire in the first place.
if (!srec->msg[N]) if (!srec->msg[N])
continue; continue;
nflags = (srec->msg[N]->flags | srec->aflags[N]) & ~srec->dflags[N]; nflags = srec->msg[N]->flags;
if (srec->status & S_DUMMY(N)) {
if (!srec->msg[F])
continue;
// We need to pull in the real Flagged and Seen even if flag
// propagation was not requested, as the placeholder's ones are
// useless (except for un-seeing).
// This results in the somewhat weird situation that messages
// which are not visibly flagged remain unexpired.
sflags = srec->msg[F]->flags;
aflags = (sflags & ~srec->flags) & (F_SEEN | F_FLAGGED);
dflags = (~sflags & srec->flags) & F_SEEN;
nflags = (nflags & (~(F_SEEN | F_FLAGGED) | (srec->flags & F_SEEN)) & ~dflags) | aflags;
}
nflags = (nflags | srec->aflags[N]) & ~srec->dflags[N];
} else {
if (srec->status & S_UPGRADE) {
// The dummy's F & S flags are mostly masked out anyway,
// but we may be pulling in the real ones.
nflags = (srec->pflags | srec->aflags[N]) & ~srec->dflags[N];
} else { } else {
nflags = srec->msg[F]->flags; nflags = srec->msg[F]->flags;
} }
}
if (!(nflags & F_DELETED) || (srec->status & (S_EXPIRE | S_EXPIRED))) { if (!(nflags & F_DELETED) || (srec->status & (S_EXPIRE | S_EXPIRED))) {
// The message is not deleted, or it is, but only due to being expired. // The message is not deleted, or it is, but only due to being expired.
arecs[alive++] = (alive_srec_t){ srec, nflags }; arecs[alive++] = (alive_srec_t){ srec, nflags };