/src/wasm-tools/fuzz/fuzz_targets/validate-valid-module.rs
Line | Count | Source (jump to first uncovered line) |
1 | | #![no_main] |
2 | | |
3 | | use arbitrary::Unstructured; |
4 | | use libfuzzer_sys::fuzz_target; |
5 | | |
6 | | // Define a fuzz target that accepts arbitrary |
7 | | // `Module`s or `Component`s as input. |
8 | | fuzz_target!(|data: &[u8]| { |
9 | | let mut u = Unstructured::new(data); |
10 | | |
11 | | // We want to prioritize fuzzing of modules for the time being |
12 | | // so we'll only generate a component 10% of the time |
13 | | // |
14 | | // TODO: remove this `false && ...` once this fuzzer works again for |
15 | | // components. |
16 | | let generate_component = false |
17 | | && match u.ratio::<u8>(1, 10) { |
18 | | Ok(b) => b, |
19 | | Err(_) => false, |
20 | | }; |
21 | | let (wasm_bytes, config) = if generate_component { |
22 | 0 | match wasm_tools_fuzz::generate_valid_component(&mut u, |c, u| { |
23 | 0 | c.max_components = u.int_in_range(0..=1_000)?; |
24 | 0 | c.max_instances = u.int_in_range(0..=1_000)?; |
25 | 0 | c.max_values = u.int_in_range(0..=1_000)?; |
26 | 0 | Ok(()) |
27 | 0 | }) { |
28 | | Ok(c) => c, |
29 | | Err(_) => return, |
30 | | } |
31 | | } else { |
32 | 9.57k | match wasm_tools_fuzz::generate_valid_module(&mut u, |_, _| Ok(())) { |
33 | | Ok(m) => m, |
34 | | Err(_) => return, |
35 | | } |
36 | | }; |
37 | | |
38 | | // Validate the module or component and assert that it passes validation. |
39 | | let mut validator = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures { |
40 | | component_model: generate_component, |
41 | | multi_value: config.multi_value_enabled, |
42 | | multi_memory: config.max_memories > 1, |
43 | | bulk_memory: true, |
44 | | reference_types: true, |
45 | | simd: config.simd_enabled, |
46 | | relaxed_simd: config.relaxed_simd_enabled, |
47 | | memory64: config.memory64_enabled, |
48 | | threads: config.threads_enabled, |
49 | | exceptions: config.exceptions_enabled, |
50 | | ..wasmparser::WasmFeatures::default() |
51 | | }); |
52 | | if let Err(e) = validator.validate_all(&wasm_bytes) { |
53 | | let component_or_module = if generate_component { |
54 | | "component" |
55 | | } else { |
56 | | "module" |
57 | | }; |
58 | | panic!("Invalid {}: {}", component_or_module, e); |
59 | | } |
60 | | |
61 | | // After validation make sure that binary-to-text and text-to-binary |
62 | | // transforms all work as well. |
63 | 0 | let wat_string = wasmprinter::print_bytes(&wasm_bytes).unwrap_or_else(|e| { |
64 | 0 | panic!( |
65 | 0 | "failed first disassembly of Wasm into wat with `wasmprinter::print_bytes`: {}", |
66 | 0 | e |
67 | 0 | ) |
68 | | }); |
69 | 0 | let wasm_bytes = wat::parse_str(&wat_string).unwrap_or_else(|e| { |
70 | 0 | panic!( |
71 | 0 | "failed to assemble wat into Wasm with `wat::parse_str`: {}", |
72 | 0 | e |
73 | 0 | ) |
74 | | }); |
75 | 0 | let wat_string2 = wasmprinter::print_bytes(&wasm_bytes).unwrap_or_else(|e| { |
76 | 0 | panic!( |
77 | 0 | "failed second disassembly of Wasm into wat with `wasmprinter::print_bytes`: {}", |
78 | 0 | e |
79 | 0 | ) |
80 | | }); |
81 | | |
82 | | if wat_string != wat_string2 { |
83 | | panic!("failed to roundtrip valid module"); |
84 | | } |
85 | | }); |