forked from 1b-agent/opencadstudio-upstream
feat(plugin): wrap external-plugin calls in a panic guard
A buggy external plugin that panicked anywhere — during load (version, register, manifest), during ribbon build / dispatch, or inside an interactive command (prompt, on_point, on_enter, on_object_pick) — took the host down with it (#134). Run every cdylib entry point under catch_unwind so the host stays up: the plugin's call is treated as inert (load fails, dispatch returns "didn't handle it", interactive hooks resolve to Cancel) and a "Plugin <hook> panicked: …" line lands in the command line on the next tick. (#145) Scope is Rust panics across the cdylib boundary, not genuine UB — real isolation (segfault-proof) still requires out-of-process plugins. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
2a260be31d
commit
f860fb39c2
5 files changed
+122
-14
No files matched your search
+14
-3
@@ -23,8 +23,15 @@ pub fn ribbon_modules_enabled(
|
||||
let mut addons: Vec<(i32, Box<dyn CadModule>)> = Vec::new();
|
||||
crate::plugin::external::with_loaded(|loaded| {
|
||||
for lp in loaded {
|
||||
if !disabled.contains(lp.id.as_str()) {
|
||||
addons.push((lp.plugin().manifest().ribbon_order, lp.plugin().ribbon()));
|
||||
if disabled.contains(lp.id.as_str()) {
|
||||
continue;
|
||||
}
|
||||
// Guard the plugin's ribbon build so a panic there can't take
|
||||
// down the host — the plugin just contributes no tab. (#145)
|
||||
if let Some(entry) = crate::plugin::guard("ribbon", || {
|
||||
(lp.plugin().manifest().ribbon_order, lp.plugin().ribbon())
|
||||
}) {
|
||||
addons.push(entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -48,7 +55,11 @@ pub(crate) fn try_dispatch(app: &mut OpenCADStudio, tab: usize, cmd: &str) -> bo
|
||||
if disabled.contains(lp.id.as_str()) {
|
||||
continue;
|
||||
}
|
||||
if lp.plugin().dispatch(&mut host, cmd) {
|
||||
// A panic inside the plugin's dispatch must not crash the host;
|
||||
// treat a panicking plugin as "didn't handle it". (#145)
|
||||
if crate::plugin::guard("dispatch", || lp.plugin().dispatch(&mut host, cmd))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user