fix: deletable self-sent mail, honest refused-handshake reporting, registration remedy

This commit is contained in:
randogoth 2026-09-29 09:35:46 +03:00
parent 4a780ed648
commit 39c4c4d6a5
3 changed files with 211 additions and 55 deletions

View file

@ -174,7 +174,9 @@ fn hint(error: Option<&fumi::error::Error>) {
}
}
Some(fumi::error::Error::NotRegistered) => {
eprintln!("run: fumi register <user@host>")
eprintln!(
"for a new mailbox:\n fumi register <user@host>\nfor an existing one, pin the server and restore:\n fumi trust <host> <key>\n fumi restore <user@host>"
)
}
_ => {}
}
@ -675,11 +677,17 @@ fn resolve_id_prefixes(store: &Store, ids: &[String]) -> Result<Vec<[u8; ID_LEN]
let mut full = Vec::with_capacity(ids.len());
for id in ids {
let prefix = id.to_ascii_lowercase();
let matches: Vec<[u8; ID_LEN]> = stored
let mut matches: Vec<[u8; ID_LEN]> = stored
.iter()
.filter(|m| hex(m).starts_with(&prefix))
.copied()
.collect();
// A self-addressed message is stored once as received and once as
// sent with the same id; identical ids across folders are one
// message by construction, so dedupe before requiring more
// specificity.
matches.sort_unstable();
matches.dedup();
match matches.len() {
0 => return Err(anyhow!(format!("no message matching {id:?}"))),
1 => full.push(matches[0]),
@ -887,4 +895,30 @@ mod tests {
assert_eq!(format_utc(951_782_400), "2000-02-29 00:00"); // leap day
assert_eq!(format_utc(-1), "1969-12-31 23:59");
}
/// A self-addressed message sits in the inbox and the sent folder with
/// the same id; resolving it must yield one message, not an ambiguity.
#[test]
fn id_resolution_treats_a_self_addressed_message_as_one() {
let store = Store::open_in_memory().unwrap();
let id = [7u8; ID_LEN];
store.store_inbox(&id, b"envelope", 1, false, false).unwrap();
store.store_sent(&id, "fumi@localhost", b"envelope", 1).unwrap();
let full = resolve_id_prefixes(&store, &[hex(&id)]).unwrap();
assert_eq!(full, vec![id]);
}
/// Genuinely distinct messages sharing a prefix must still demand a
/// more specific id.
#[test]
fn id_resolution_rejects_an_ambiguous_prefix() {
let store = Store::open_in_memory().unwrap();
let a = [7u8; ID_LEN];
let mut b = [7u8; ID_LEN];
b[31] = 8;
store.store_inbox(&a, b"a", 1, false, false).unwrap();
store.store_inbox(&b, b"b", 2, false, false).unwrap();
assert!(resolve_id_prefixes(&store, &["0707".into()]).is_err());
assert_eq!(resolve_id_prefixes(&store, &[hex(&a)]).unwrap(), vec![a]);
}
}