This PR fixes a potential panic that could occur when loading malformed
Wasm files.
We now use the `parse_wasm_extension_version` function that was
previously used just to extract the Zed extension API version from the
Wasm bytes as a pre-validation step. By parsing the entirety of the Wasm
file here instead of returning as soon as we find the version, the
invalid Wasm bytes are now surfaced as an `Err` instead of a panic.
We were able to replicate the panic using the following test:
```rs
#[gpui::test]
async fn test_bad_wasm(cx: &mut TestAppContext) {
init_test(cx);
let wasm_host = cx.update(|cx| {
WasmHost::new(
FakeFs::new(cx.background_executor().clone()),
FakeHttpClient::with_200_response(),
FakeNodeRuntime::new(),
Arc::new(LanguageRegistry::test(cx.background_executor().clone())),
PathBuf::from("/the/work/dir".to_string()),
cx,
)
});
let mut wasm_bytes = std::fs::read("/Users/maxdeviant/Library/Application Support/Zed/extensions/installed/dart/extension.wasm").unwrap();
// This is the error message we were seeing in the stack trace:
// range end index 267037 out of range for slice of length 253952
dbg!(&wasm_bytes.len());
// Truncate the bytes to the same point:
wasm_bytes.truncate(253952);
std::fs::write("/tmp/bad-extension.wasm", wasm_bytes.clone()).unwrap();
let manifest = Arc::new(ExtensionManifest {
id: "the-extension".into(),
name: "The Extension".into(),
version: "0.0.1".into(),
schema_version: SchemaVersion(1),
description: Default::default(),
repository: Default::default(),
authors: Default::default(),
lib: LibManifestEntry {
kind: None,
version: None,
},
themes: Default::default(),
languages: Default::default(),
grammars: Default::default(),
language_servers: Default::default(),
});
// 💥
let result = wasm_host
.load_extension(wasm_bytes, manifest, cx.executor())
.await;
dbg!(result.map(|_| ()));
```
Release Notes:
- Fixed a crash that could occur when loading malformed Wasm extensions
([#10352](https://github.com/zed-industries/zed/issues/10352)).
---------
Co-authored-by: Max <max@zed.dev>
This PR adds the ability for extensions to implement
`language_server_workspace_configuration` to provide workspace
configuration to the language server.
We've used the Dart extension as a motivating example for this, pulling
it out into an extension in the process.
Release Notes:
- Removed built-in support for Dart, in favor of making it available as
an extension. The Dart extension will be suggested for download when you
open a `.dart` file.
---------
Co-authored-by: Max <max@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This PR extracts the `SemanticVersion` out of `util` and into its own
`SemanticVersion` crate.
This allows for making use of `SemanticVersion` without needing to pull
in some of the heavier dependencies included in the `util` crate.
As part of this the public API for `SemanticVersion` has been tidied up
a bit.
Release Notes:
- N/A
* Store extensions versions' wasm API version in the database
* Share a common struct for extension API responses between collab and
client
* Add wasm API version and schema version to extension API responses
Release Notes:
- N/A
Co-authored-by: Marshall <marshall@zed.dev>
We're doing it. Svelte support is moving into an extension. This PR
fixes some issues that came up along the way.
Notes
* extensions need to be able to retrieve the path the `node` binary
installed by Zed
* previously we were silently swallowing any errors that occurred while
loading a grammar
* npm commands ran by extensions weren't run in the right directory
* Tree-sitter's WASM stdlib didn't support a C function (`strncmp`)
needed by the Svelte parser's external scanner
* the way that LSP installation status was reported was unnecessarily
complex
Release Notes:
- Removed built-in support for the Svelte and Gleam languages, because
full support for those languages is now available via extensions. These
extensions will be suggested for download when you open a `.svelte` or
`.gleam` file.
---------
Co-authored-by: Marshall <marshall@zed.dev>
Our goal is to extract Svelte support into an extension, since we've
seen problems with the Tree-sitter Svelte parser crashing due to bugs in
the external scanner. In order to do this, we need a couple more
capabilities in LSP extensions:
* [x] `initialization_options` - programmatically controlling the JSON
initialization params sent to the language server
* [x] `prettier_plugins` - statically specifying a list of prettier
plugins that apply for a given language.
* [x] `npm_install_package`
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
In this PR, we've added two new methods that LSP extensions can call:
* `shell_env()`, for retrieving the environment variables set in the
user's default shell in the worktree
* `which(command)`, for looking up paths to an executable (accounting
for the user's shell env in the worktree)
To test this out, we moved the `uiua` language support into an
extension. We went ahead and removed the built-in support, since this
language is extremely obscure. Sorry @mikayla-maki. To continue coding
in Uiua in Zed, for now you can `Add Dev Extension` from the extensions
pane, and select the `extensions/uiua` directory in the Zed repo. Very
soon, we'll support publishing these extensions so that you'll be able
to just install it normally.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
This PR provides WASM extensions with write access to their own specific
working directory under the Zed `extensions` dir. This directory is set
as the extensions `current_dir` when they run. Extensions can return
relative paths from the `Extension::language_server_command` method, and
those relative paths will be interpreted relative to this working dir.
With this functionality, most language servers that we currently build
into zed can be installed using extensions.
Release Notes:
- N/A
This PR adds **internal** ability to run arbitrary language servers via
WebAssembly extensions. The functionality isn't exposed yet - we're just
landing this in this early state because there have been a lot of
changes to the `LspAdapter` trait, and other language server logic.
## Next steps
* Currently, wasm extensions can only define how to *install* and run a
language server, they can't yet implement the other LSP adapter methods,
such as formatting completion labels and workspace symbols.
* We don't have an automatic way to install or develop these types of
extensions
* We don't have a way to package these types of extensions in our
extensions repo, to make them available via our extensions API.
* The Rust extension API crate, `zed-extension-api` has not yet been
published to crates.io, because we still consider the API a work in
progress.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>