Implement the allow-unknown-exports option for the run command.
This commit implements the `--allow-unknown-exports` option to the CLI run command that will ignore unknown exports in a command module rather than return an error. Fixes #2587.
This commit is contained in:
@@ -37,6 +37,7 @@ pub struct Linker {
|
||||
strings: Vec<Rc<str>>,
|
||||
map: HashMap<ImportKey, Extern>,
|
||||
allow_shadowing: bool,
|
||||
allow_unknown_exports: bool,
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq)]
|
||||
@@ -69,6 +70,7 @@ impl Linker {
|
||||
string2idx: HashMap::new(),
|
||||
strings: Vec::new(),
|
||||
allow_shadowing: false,
|
||||
allow_unknown_exports: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +104,32 @@ impl Linker {
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures whether this [`Linker`] will allow unknown exports from
|
||||
/// command modules.
|
||||
///
|
||||
/// By default a [`Linker`] will error when unknown exports are encountered
|
||||
/// in a command module while using [`Linker::module`].
|
||||
///
|
||||
/// This method can be used to allow unknown exports from command modules.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use wasmtime::*;
|
||||
/// # fn main() -> anyhow::Result<()> {
|
||||
/// # let store = Store::default();
|
||||
/// # let module = Module::new(store.engine(), "(module)")?;
|
||||
/// let mut linker = Linker::new(&store);
|
||||
/// linker.allow_unknown_exports(true);
|
||||
/// linker.module("mod", &module)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn allow_unknown_exports(&mut self, allow: bool) -> &mut Linker {
|
||||
self.allow_unknown_exports = allow;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines a new item in this [`Linker`].
|
||||
///
|
||||
/// This method will add a new definition, by name, to this instance of
|
||||
@@ -469,7 +497,7 @@ impl Linker {
|
||||
// Allow an exported "__rtti_base" memory for compatibility with
|
||||
// AssemblyScript.
|
||||
warn!("command module exporting '__rtti_base' is deprecated; pass `--runtime half` to the AssemblyScript compiler");
|
||||
} else {
|
||||
} else if !self.allow_unknown_exports {
|
||||
bail!("command export '{}' is not a function", export.name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,10 @@ pub struct RunCommand {
|
||||
#[structopt(flatten)]
|
||||
common: CommonOptions,
|
||||
|
||||
/// Allow unknown exports when running commands.
|
||||
#[structopt(long = "allow-unknown-exports")]
|
||||
allow_unknown_exports: bool,
|
||||
|
||||
/// Grant access to the given host directory
|
||||
#[structopt(long = "dir", number_of_values = 1, value_name = "DIRECTORY")]
|
||||
dirs: Vec<String>,
|
||||
@@ -146,6 +150,8 @@ impl RunCommand {
|
||||
let argv = self.compute_argv();
|
||||
|
||||
let mut linker = Linker::new(&store);
|
||||
linker.allow_unknown_exports(self.allow_unknown_exports);
|
||||
|
||||
populate_with_wasi(
|
||||
&mut linker,
|
||||
preopen_dirs,
|
||||
|
||||
@@ -162,6 +162,24 @@ fn module_interposition() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_unknown_exports() -> Result<()> {
|
||||
let store = Store::default();
|
||||
let mut linker = Linker::new(&store);
|
||||
let module = Module::new(
|
||||
store.engine(),
|
||||
r#"(module (func (export "_start")) (global (export "g") i32 (i32.const 0)))"#,
|
||||
)?;
|
||||
|
||||
assert!(linker.module("module", &module).is_err());
|
||||
|
||||
let mut linker = Linker::new(&store);
|
||||
linker.allow_unknown_exports(true);
|
||||
linker.module("module", &module)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_leak() -> Result<()> {
|
||||
struct DropMe(Rc<Cell<bool>>);
|
||||
|
||||
Reference in New Issue
Block a user