diff --git a/crates/ide-host/src/plugins/api.rs b/crates/ide-host/src/plugins/api.rs index 26cc5a4b9..6c8ba2dfc 100644 --- a/crates/ide-host/src/plugins/api.rs +++ b/crates/ide-host/src/plugins/api.rs @@ -1122,7 +1122,9 @@ impl HostApi for PluginApi { let binary = self.approved_program(program)?; let cwd = cwd.map(Path::to_path_buf).unwrap_or_else(|| self.shared.data_dir.join(self.id())); let _ = std::fs::create_dir_all(&cwd); - let mut child = std::process::Command::new(&binary) + let mut cmd = std::process::Command::new(&binary); + ide_core::process::prepare(&mut cmd); + let mut child = cmd .args(&args) .current_dir(&cwd) .stdin(if stdin.is_some() { std::process::Stdio::piped() } else { std::process::Stdio::null() }) diff --git a/crates/ide-host/tests/plugins.rs b/crates/ide-host/tests/plugins.rs index 937dc581c..ddb5c8d88 100644 --- a/crates/ide-host/tests/plugins.rs +++ b/crates/ide-host/tests/plugins.rs @@ -3863,3 +3863,26 @@ fn project_lookup_works_in_commands_and_provider_calls_without_an_invocation_pro f.host.set_capability("test.path-events", "events", false).unwrap(); assert!(f.run("test.path-events", "filter", Some("*")).unwrap_err().contains("events")); } + +#[test] +fn view_messages_accept_multi_megabyte_snapshots_and_cap_at_8_mib() { + let f = fixture(Limits::default()); + f.install(&sample("jobs")); + f.take_events(); + let two_mib = "x".repeat(2 << 20); + f.host.view_event("jobs", "jobs", ide_plugin::ViewEvent::Message { text: two_mib.clone() }, f.inv()).unwrap(); + let echoed = f + .take_events() + .into_iter() + .find_map(|(_, e)| match e { + PluginEvent::ViewMessage { view, message, .. } if view == "jobs" => Some(message), + _ => None, + }) + .expect("2 MiB view message round-trips"); + assert_eq!(echoed.len(), 2 << 20); + + let too_large = "x".repeat((8 << 20) + 1); + let err = + f.host.view_event("jobs", "jobs", ide_plugin::ViewEvent::Message { text: too_large }, f.inv()).unwrap_err(); + assert!(err.message.contains("limited to"), "{}", err.message); +} diff --git a/crates/ide-plugin/src/wit_host.rs b/crates/ide-plugin/src/wit_host.rs index 84229dcb4..2d1da0fb6 100644 --- a/crates/ide-plugin/src/wit_host.rs +++ b/crates/ide-plugin/src/wit_host.rs @@ -1127,7 +1127,7 @@ fn too_much_to_write(path: &str) -> wit::Error { } /// Largest message between a plugin and its view's frame. -const MAX_VIEW_MESSAGE: usize = 1 << 20; +const MAX_VIEW_MESSAGE: usize = 8 << 20; pub(crate) mod indexing_bindings { wasmtime::component::bindgen!({ diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm index cdb25003e..4fda3080c 100644 Binary files a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm and b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm differ diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources index 591da1285..f163bf61a 100644 --- a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources @@ -1 +1 @@ -bd79d7641d84e919a83ea082b00eca78d4d1427e1e3345fba7d289b06862edde +6d3880d15cbc1e1f04364514e7cb61fc6d300b177c074b7b079cebc28b404a1e diff --git a/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs b/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs index bfcc3b646..6373b8e5e 100644 --- a/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs +++ b/crates/ide-plugin/tests/fixtures/jobs/src/lib.rs @@ -141,6 +141,7 @@ impl Views for Jobs { ViewEvent::Button(b) if b == "follow" => return self.follow(), ViewEvent::Button(b) if b == "log" => return host::open_location("jobs.log", 2, 4), ViewEvent::Button(b) if b == "outside" => return host::open_location("../outside.log", 0, 0), + ViewEvent::Message(msg) => return host::post_view_message(VIEW, &msg), _ => return Ok(()), } host::refresh_view(VIEW);