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:
parent
14eb982db5
commit
928026c49e
1 changed files with 32 additions and 25 deletions
|
|
@ -89,36 +89,43 @@ fn apply_modes(s: &mut Server, name: &str, key: &str, modes: &str) {
|
|||
return;
|
||||
};
|
||||
let args: Vec<&str> = it.collect();
|
||||
let mut ai = 0usize;
|
||||
let mut adding = true;
|
||||
s.mode_sudo = true;
|
||||
for c in letters.chars() {
|
||||
match c {
|
||||
'+' => {
|
||||
adding = true;
|
||||
continue;
|
||||
// Isolate a panicking mode handler: otherwise it would leave `mode_sudo` stuck
|
||||
// on, silently disabling rank/oper gating for every subsequent MODE.
|
||||
let outcome = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
let mut ai = 0usize;
|
||||
let mut adding = true;
|
||||
for c in letters.chars() {
|
||||
match c {
|
||||
'+' => {
|
||||
adding = true;
|
||||
continue;
|
||||
}
|
||||
'-' => {
|
||||
adding = false;
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
'-' => {
|
||||
adding = false;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue