permchannels: isolate the load-time mode applier in catch_unwind so a panicking mode handler can't leave mode_sudo stuck true — which would silently disable rank/oper gating for every subsequent MODE; the flag is now always reset

This commit is contained in:
Jean Chevronnet 2026-08-19 01:14:34 +00:00
parent 14eb982db5
commit 928026c49e

View file

@ -89,36 +89,43 @@ fn apply_modes(s: &mut Server, name: &str, key: &str, modes: &str) {
return; return;
}; };
let args: Vec<&str> = it.collect(); let args: Vec<&str> = it.collect();
let mut ai = 0usize;
let mut adding = true;
s.mode_sudo = true; s.mode_sudo = true;
for c in letters.chars() { // Isolate a panicking mode handler: otherwise it would leave `mode_sudo` stuck
match c { // on, silently disabling rank/oper gating for every subsequent MODE.
'+' => { let outcome = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
adding = true; let mut ai = 0usize;
continue; let mut adding = true;
for c in letters.chars() {
match c {
'+' => {
adding = true;
continue;
}
'-' => {
adding = false;
continue;
}
_ => {}
} }
'-' => { let Some(h) = crate::mode::chan_mode(c) else {
adding = false;
continue; continue;
} };
_ => {} let param = if h.wants_param(adding) {
let p = args.get(ai).copied();
if p.is_some() {
ai += 1;
}
p
} else {
None
};
let _ = h.apply(s, name, key, 0, adding, param);
} }
let Some(h) = crate::mode::chan_mode(c) else { }));
continue;
};
let param = if h.wants_param(adding) {
let p = args.get(ai).copied();
if p.is_some() {
ai += 1;
}
p
} else {
None
};
let _ = h.apply(s, name, key, 0, adding, param);
}
s.mode_sudo = false; s.mode_sudo = false;
if outcome.is_err() {
eprintln!("[permchannels] a mode handler panicked applying {name}; skipped its remaining modes");
}
} }
/// Recreate one parsed record as a live (member-less) channel. /// Recreate one parsed record as a live (member-less) channel.