1
1
use arbitrary:: { Result , Unstructured } ;
2
- use wasmparser:: { Validator , WasmFeatures } ;
2
+ use wasmparser:: { Parser , Validator , WasmFeatures } ;
3
3
4
4
pub fn run ( u : & mut Unstructured < ' _ > ) -> Result < ( ) > {
5
5
// Either use `wasm-smith` to generate a module with possibly invalid
@@ -21,14 +21,13 @@ pub fn validate_maybe_invalid_module(u: &mut Unstructured<'_>) -> Result<()> {
21
21
config. allow_invalid_funcs = true ;
22
22
Ok ( ( ) )
23
23
} ) ?;
24
- let mut validator = crate :: validator_for_config ( & config) ;
25
- drop ( validator. validate_all ( & wasm) ) ;
24
+ validate_all ( crate :: validator_for_config ( & config) , & wasm) ;
26
25
Ok ( ( ) )
27
26
}
28
27
29
28
pub fn validate_raw_bytes ( u : & mut Unstructured < ' _ > ) -> Result < ( ) > {
30
29
// Enable arbitrary combinations of features to validate the input bytes.
31
- let mut validator = Validator :: new_with_features ( WasmFeatures {
30
+ let validator = Validator :: new_with_features ( WasmFeatures {
32
31
reference_types : u. arbitrary ( ) ?,
33
32
multi_value : u. arbitrary ( ) ?,
34
33
threads : u. arbitrary ( ) ?,
@@ -55,6 +54,65 @@ pub fn validate_raw_bytes(u: &mut Unstructured<'_>) -> Result<()> {
55
54
} ) ;
56
55
let wasm = u. bytes ( u. len ( ) ) ?;
57
56
crate :: log_wasm ( wasm, "" ) ;
58
- drop ( validator . validate_all ( wasm) ) ;
57
+ validate_all ( validator , wasm) ;
59
58
Ok ( ( ) )
60
59
}
60
+
61
+ fn validate_all ( mut validator : Validator , wasm : & [ u8 ] ) {
62
+ for payload in Parser :: new ( 0 ) . parse_all ( wasm) {
63
+ let payload = match payload {
64
+ Ok ( p) => p,
65
+ Err ( _) => return ,
66
+ } ;
67
+
68
+ if validator. payload ( & payload) . is_err ( ) {
69
+ return ;
70
+ }
71
+
72
+ // Check that the payload's range is in bounds, since the payload is
73
+ // supposedly valid.
74
+ use wasmparser:: Payload :: * ;
75
+ match payload {
76
+ Version { range, .. } => assert ! ( wasm. get( range) . is_some( ) ) ,
77
+ TypeSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
78
+ ImportSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
79
+ FunctionSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
80
+ TableSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
81
+ MemorySection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
82
+ TagSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
83
+ GlobalSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
84
+ ExportSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
85
+ StartSection { range, .. } => assert ! ( wasm. get( range) . is_some( ) ) ,
86
+ ElementSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
87
+ DataCountSection { range, .. } => assert ! ( wasm. get( range) . is_some( ) ) ,
88
+ DataSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
89
+ CodeSectionStart { range, .. } => assert ! ( wasm. get( range) . is_some( ) ) ,
90
+ CodeSectionEntry ( body) => assert ! ( wasm. get( body. range( ) ) . is_some( ) ) ,
91
+ InstanceSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
92
+ CoreTypeSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
93
+ ComponentInstanceSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
94
+ ComponentAliasSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
95
+ ComponentTypeSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
96
+ ComponentCanonicalSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
97
+ ComponentStartSection { range, .. } => assert ! ( wasm. get( range) . is_some( ) ) ,
98
+ ComponentImportSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
99
+ ComponentExportSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
100
+ CustomSection ( s) => assert ! ( wasm. get( s. range( ) ) . is_some( ) ) ,
101
+ UnknownSection { range, .. } => assert ! ( wasm. get( range) . is_some( ) ) ,
102
+
103
+ // In order to support streaming parsing and validation, these
104
+ // sections' ranges are not checked during validation, since they
105
+ // contain nested sections and we don't want to require all nested
106
+ // sections are present before we can parse/validate any of them.
107
+ ComponentSection {
108
+ unchecked_range : _, ..
109
+ }
110
+ | ModuleSection {
111
+ unchecked_range : _, ..
112
+ } => { }
113
+
114
+ // No associated range.
115
+ End ( _) => { }
116
+ }
117
+ }
118
+ }
0 commit comments