From ef892f747f21b7cd62181ead6c253f6405303d09 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Tue, 3 Nov 2026 15:28:34 +0000 Subject: [PATCH] fix(engine): scripts load effect plug-ins only with Allow Scripts to Write Files on --- crates/engine/src/cmd/effect.rs | 8 ++++++++ crates/engine/src/tests/settings.rs | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/crates/engine/src/cmd/effect.rs b/crates/engine/src/cmd/effect.rs index f41ba3f9c..2d73a2801 100644 --- a/crates/engine/src/cmd/effect.rs +++ b/crates/engine/src/cmd/effect.rs @@ -35,6 +35,14 @@ fn plugins_list(s: &mut Session, _: &Value) -> Result { /// folder) through the host's loader ([`Session::plugin_loader`]). fn plugins_load(s: &mut Session, p: &Value) -> Result { let c = "effect.plugins.load"; + // A plug-in is code, and a file that fails to load comes back in the error: a script may + // load one only with the access it would need to read and write files anywhere. + if s.running_for_script() && !s.prefs.scripting.allow_scripts_write_files { + return Err(bad( + c, + "scripts can't load effect plug-ins unless Settings ▸ Scripting & Expressions ▸ Allow Scripts to Write Files and Access Network is on", + )); + } let loader = s.plugin_loader.ok_or_else(|| EngineError::Other("WebAssembly effect plug-ins are not available in this build".into()))?; let files: Vec = match (str_p(p, "path"), str_p(p, "folder")) { (Some(path), _) => vec![path.to_string()], diff --git a/crates/engine/src/tests/settings.rs b/crates/engine/src/tests/settings.rs index 5e38c90a3..0dac9e6ed 100644 --- a/crates/engine/src/tests/settings.rs +++ b/crates/engine/src/tests/settings.rs @@ -651,6 +651,18 @@ fn context_shortcuts_on_the_same_keys_conflict() { assert!(t.conflicts(b, "F9").iter().any(|c| c.key == "test.paint" && !c.overrides)); } +/// A script loads effect plug-ins only with Allow Scripts to Write Files on. +#[test] +fn scripts_load_effect_plugins_only_with_file_access() { + let mut s = Session::default(); + let p = json!({"path": "/etc/hostname"}); + let e = s.execute_for_script("effect.plugins.load", p.clone()).unwrap_err().to_string(); + assert!(e.contains("Allow Scripts to Write Files"), "{e}"); + s.prefs.scripting.allow_scripts_write_files = true; + let e = s.execute_for_script("effect.plugins.load", p).unwrap_err().to_string(); + assert!(!e.contains("Allow Scripts to Write Files"), "{e}"); +} + // ---------------------------------------------------------------- auto-save / recovery /// The names in `d`, sorted.