I’m working on my own (for now) NixOS module for stalwart >0.16 and I noticed that the code to deserialize a Duration specified through a DataStore’s configuration could misinterpret some values; for example, from reading the code it seems likely that the following parser errors occur:
Actual Behavior
1m30s parses as 130 milliseconds - units can combine (m and s becomes ms).
1h0 parses as 10 hours - the position of the unit doesn’t matter.
Not that anyone really would, but 213503982301d overflows u64 when converted to ms - I don’t think this needs fixing.
Final thought; this implementation can’t be negative (eg -30s doesn’t parse because multiplier doesn’t match the pattern -s), though in the context of configuring a DataStore, I think this is correct - no negative values should be accepted.
Stalwart Version
v0.16.x
Installation Method
NixOS
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
Your read of the code is accurate. Looking at duration.rs, the parser splits the input into two buffers, one for all ASCII digits and one for all other non-whitespace characters (case-lowered), regardless of order or position:
for ch in value.chars() {
if ch.is_ascii_digit() {
digits.push(ch);
} else if !ch.is_ascii_whitespace() {
multiplier.push(ch.to_ascii_lowercase());
}
}
So the confirmed behaviors you found do match the implementation:
"1m30s" → digits accumulate to "130", non-digit chars accumulate to "ms", which matches the "ms" branch (multiplier 1) → 130 ms. Confirmed bug.
"1h0" → digits "10", multiplier "h" → 10 hours. Confirmed, since digit/unit interleaving order is discarded.
Large day values can overflow u64 in the num * multiplier multiplication, since it’s not a checked/saturating multiply. Confirmed, though as you note it’s an edge case unlikely to matter in practice.
No negative sign is handled at all (any non-digit, non-whitespace char just gets appended to the unit string, so - would make multiplier invalid unless it’s a recognized suffix), so negative durations correctly fail to parse.
This looks like a genuine parsing implementation issue worth fixing (unit tokens should be matched as a single trailing suffix rather than by scanning all non-digit characters independently of position). A human maintainer will need to follow up on an actual code fix since this isn’t something documentation clarifies.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.
This is an invalid duration value according to the documentation, you should use 90s instead. That said, the parsing code was not correctly rejecting invalid duration and that has been just fixed.