1 #![cfg(arc_try_new)]
2 
3 use wasmtime::{Config, Engine, Func, FuncType, Linker, Module, Result, Store};
4 use wasmtime_fuzzing::oom::OomTest;
5 
6 #[test]
linker_new() -> Result<()>7 fn linker_new() -> Result<()> {
8     OomTest::new().test(|| {
9         let mut config = Config::new();
10         config.enable_compiler(false);
11         let engine = Engine::new(&config)?;
12         let _linker = Linker::<()>::new(&engine);
13         Ok(())
14     })
15 }
16 
17 #[test]
linker_func_wrap() -> Result<()>18 fn linker_func_wrap() -> Result<()> {
19     OomTest::new().test(|| {
20         let mut config = Config::new();
21         config.enable_compiler(false);
22         let engine = Engine::new(&config)?;
23         let mut linker = Linker::<()>::new(&engine);
24         linker.func_wrap("module", "func", |x: i32| x * 2)?;
25         Ok(())
26     })
27 }
28 
29 #[test]
linker_instantiate_pre() -> Result<()>30 fn linker_instantiate_pre() -> Result<()> {
31     let module_bytes = {
32         let mut config = Config::new();
33         config.concurrency_support(false);
34         let engine = Engine::new(&config)?;
35         let module = Module::new(
36             &engine,
37             r#"
38                 (module
39                     (import "module" "func" (func (param i32) (result i32)))
40 
41                     (memory (export "memory") 1)
42                     (data (i32.const 0) "a")
43 
44                     (table (export "table") 1 funcref)
45                     (elem (i32.const 0) func 1)
46 
47                     (func (export "func") (param i32) (result i32)
48                         (call 0 (local.get 0))
49                     )
50                 )
51             "#,
52         )?;
53         module.serialize()?
54     };
55 
56     let mut config = Config::new();
57     config.enable_compiler(false);
58     config.concurrency_support(false);
59 
60     let engine = Engine::new(&config)?;
61 
62     let mut linker = Linker::<()>::new(&engine);
63     linker.func_wrap("module", "func", |x: i32| x * 2)?;
64 
65     let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
66 
67     OomTest::new().test(|| {
68         let _ = linker.instantiate_pre(&module)?;
69         Ok(())
70     })
71 }
72 
73 #[test]
linker_define() -> Result<()>74 fn linker_define() -> Result<()> {
75     let mut config = Config::new();
76     config.enable_compiler(false);
77     config.concurrency_support(false);
78     let engine = Engine::new(&config)?;
79 
80     OomTest::new().test(|| {
81         let mut store = Store::try_new(&engine, ())?;
82         let mut linker = Linker::<()>::new(&engine);
83         let func = Func::try_wrap(&mut store, || {})?;
84         linker.define(&store, "mod", "func", func)?;
85         Ok(())
86     })
87 }
88 
89 #[test]
linker_func_new() -> Result<()>90 fn linker_func_new() -> Result<()> {
91     let mut config = Config::new();
92     config.enable_compiler(false);
93     config.concurrency_support(false);
94     let engine = Engine::new(&config)?;
95 
96     OomTest::new().test(|| {
97         let mut linker = Linker::<()>::new(&engine);
98         linker.func_new(
99             "mod",
100             "func",
101             FuncType::try_new(&engine, [], [])?,
102             |_caller, _params, _results| Ok(()),
103         )?;
104         Ok(())
105     })
106 }
107 
108 #[test]
linker_instance() -> Result<()>109 fn linker_instance() -> Result<()> {
110     let module_bytes = {
111         let mut config = Config::new();
112         config.concurrency_support(false);
113         let engine = Engine::new(&config)?;
114         Module::new(
115             &engine,
116             r#"(module (func (export "f")) (memory (export "m") 1))"#,
117         )?
118         .serialize()?
119     };
120     let mut config = Config::new();
121     config.enable_compiler(false);
122     config.concurrency_support(false);
123     let engine = Engine::new(&config)?;
124     let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
125     let pre_linker = Linker::<()>::new(&engine);
126     let instance_pre = pre_linker.instantiate_pre(&module)?;
127 
128     OomTest::new().test(|| {
129         let mut store = Store::try_new(&engine, ())?;
130         let instance = instance_pre.instantiate(&mut store)?;
131         let mut linker = Linker::<()>::new(&engine);
132         linker.instance(&mut store, "inst", instance)?;
133         Ok(())
134     })
135 }
136 
137 #[test]
linker_get() -> Result<()>138 fn linker_get() -> Result<()> {
139     let mut config = Config::new();
140     config.enable_compiler(false);
141     config.concurrency_support(false);
142     let engine = Engine::new(&config)?;
143 
144     let mut linker = Linker::<()>::new(&engine);
145     linker.func_wrap("mod", "func", || {})?;
146 
147     OomTest::new().test(|| {
148         let mut store = Store::try_new(&engine, ())?;
149         let _item = linker.get(&mut store, "mod", "func")?;
150         Ok(())
151     })
152 }
153 
154 #[test]
linker_get_by_import() -> Result<()>155 fn linker_get_by_import() -> Result<()> {
156     let module_bytes = {
157         let mut config = Config::new();
158         config.concurrency_support(false);
159         let engine = Engine::new(&config)?;
160         Module::new(&engine, r#"(module (import "mod" "func" (func)))"#)?.serialize()?
161     };
162     let mut config = Config::new();
163     config.enable_compiler(false);
164     config.concurrency_support(false);
165     let engine = Engine::new(&config)?;
166     let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
167 
168     let mut linker = Linker::<()>::new(&engine);
169     linker.func_wrap("mod", "func", || {})?;
170 
171     let import = module.imports().next().unwrap();
172 
173     OomTest::new().test(|| {
174         let mut store = Store::try_new(&engine, ())?;
175         let ext = linker.try_get_by_import(&mut store, &import)?;
176         assert!(ext.is_some());
177         Ok(())
178     })
179 }
180 
181 #[test]
linker_get_default() -> Result<()>182 fn linker_get_default() -> Result<()> {
183     let module_bytes = {
184         let mut config = Config::new();
185         config.concurrency_support(false);
186         let engine = Engine::new(&config)?;
187         Module::new(&engine, r#"(module (func (export "_start")))"#)?.serialize()?
188     };
189     let mut config = Config::new();
190     config.enable_compiler(false);
191     config.concurrency_support(false);
192     let engine = Engine::new(&config)?;
193     let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
194     let linker = Linker::<()>::new(&engine);
195     let instance_pre = linker.instantiate_pre(&module)?;
196 
197     OomTest::new().test(|| {
198         let mut store = Store::try_new(&engine, ())?;
199         let instance = instance_pre.instantiate(&mut store)?;
200         let mut linker = Linker::<()>::new(&engine);
201         linker.instance(&mut store, "inst", instance)?;
202         let _default = linker.get_default(&mut store, "inst")?;
203         Ok(())
204     })
205 }
206 
207 #[test]
linker_define_name() -> Result<()>208 fn linker_define_name() -> Result<()> {
209     let mut config = Config::new();
210     config.enable_compiler(false);
211     config.concurrency_support(false);
212     let engine = Engine::new(&config)?;
213 
214     OomTest::new().test(|| {
215         let mut store = Store::try_new(&engine, ())?;
216         let mut linker = Linker::<()>::new(&engine);
217         let func = Func::try_wrap(&mut store, || {})?;
218         linker.define_name(&store, "func", func)?;
219         Ok(())
220     })
221 }
222 
223 // Note: linker_define_unknown_imports_as_traps and
224 // linker_define_unknown_imports_as_default_values are not tested under OOM
225 // because UnknownImportError::new uses infallible String allocations
226 // (to_string) that cannot be made fallible without changing the public API.
227 
228 #[test]
linker_alias() -> Result<()>229 fn linker_alias() -> Result<()> {
230     let mut config = Config::new();
231     config.enable_compiler(false);
232     config.concurrency_support(false);
233     let engine = Engine::new(&config)?;
234 
235     OomTest::new().test(|| {
236         let mut linker = Linker::<()>::new(&engine);
237         linker.func_wrap("mod", "func", || {})?;
238         linker.alias("mod", "func", "mod2", "func2")?;
239         Ok(())
240     })
241 }
242 
243 #[test]
linker_alias_module() -> Result<()>244 fn linker_alias_module() -> Result<()> {
245     let mut config = Config::new();
246     config.enable_compiler(false);
247     config.concurrency_support(false);
248     let engine = Engine::new(&config)?;
249 
250     OomTest::new().test(|| {
251         let mut linker = Linker::<()>::new(&engine);
252         linker.func_wrap("mod", "func1", || {})?;
253         linker.func_wrap("mod", "func2", || {})?;
254         linker.alias_module("mod", "mod2")?;
255         Ok(())
256     })
257 }
258