11use arbitrary:: { Result , Unstructured } ;
2- use wasmparser:: { Validator , WasmFeatures } ;
2+ use wasmparser:: { Parser , Validator , WasmFeatures } ;
33
44pub fn run ( u : & mut Unstructured < ' _ > ) -> Result < ( ) > {
55 // 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<()> {
2121 config. allow_invalid_funcs = true ;
2222 Ok ( ( ) )
2323 } ) ?;
24- let mut validator = crate :: validator_for_config ( & config) ;
25- drop ( validator. validate_all ( & wasm) ) ;
24+ validate_all ( crate :: validator_for_config ( & config) , & wasm) ;
2625 Ok ( ( ) )
2726}
2827
2928pub fn validate_raw_bytes ( u : & mut Unstructured < ' _ > ) -> Result < ( ) > {
3029 // 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 {
3231 reference_types : u. arbitrary ( ) ?,
3332 multi_value : u. arbitrary ( ) ?,
3433 threads : u. arbitrary ( ) ?,
@@ -55,6 +54,65 @@ pub fn validate_raw_bytes(u: &mut Unstructured<'_>) -> Result<()> {
5554 } ) ;
5655 let wasm = u. bytes ( u. len ( ) ) ?;
5756 crate :: log_wasm ( wasm, "" ) ;
58- drop ( validator . validate_all ( wasm) ) ;
57+ validate_all ( validator , wasm) ;
5958 Ok ( ( ) )
6059}
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