1
1
use std:: collections:: HashSet ;
2
2
3
- use wasmer:: wasmparser:: { Export , ExportSectionReader , ExternalKind } ;
3
+ use wasmer:: wasmparser:: {
4
+ Export , ExportSectionReader , ExternalKind , Parser , Payload , ValidPayload , Validator ,
5
+ WasmFeatures ,
6
+ } ;
4
7
5
8
use crate :: errors:: VmResult ;
6
9
@@ -13,29 +16,56 @@ pub const REQUIRED_IBC_EXPORTS: &[&str] = &[
13
16
"ibc_packet_timeout" ,
14
17
] ;
15
18
19
+ /// Validates the given wasm code and calls the callback for each payload.
20
+ /// "Validates" in this case refers to general WebAssembly validation, not specific to CosmWasm.
21
+ pub fn validate_wasm < ' a > (
22
+ wasm_code : & ' a [ u8 ] ,
23
+ mut handle_payload : impl FnMut ( Payload < ' a > ) -> VmResult < ( ) > ,
24
+ ) -> VmResult < ( ) > {
25
+ let mut validator = Validator :: new_with_features ( WasmFeatures {
26
+ mutable_global : false ,
27
+ saturating_float_to_int : false ,
28
+ sign_extension : true ,
29
+ reference_types : true ,
30
+ multi_value : false ,
31
+ bulk_memory : false ,
32
+ component_model : false ,
33
+ simd : false ,
34
+ relaxed_simd : false ,
35
+ threads : false ,
36
+ tail_call : false ,
37
+ deterministic_only : true ,
38
+ multi_memory : false ,
39
+ exceptions : false ,
40
+ memory64 : false ,
41
+ extended_const : false ,
42
+ } ) ;
43
+
44
+ for p in Parser :: new ( 0 ) . parse_all ( wasm_code) {
45
+ let p = p?;
46
+ // validate the payload
47
+ if let ValidPayload :: Func ( fv, body) = validator. payload ( & p) ? {
48
+ // also validate function bodies
49
+ fv. into_validator ( Default :: default ( ) ) . validate ( & body) ?;
50
+ }
51
+ // tell caller about the payload
52
+ handle_payload ( p) ?;
53
+ }
54
+
55
+ Ok ( ( ) )
56
+ }
57
+
16
58
/// A small helper macro to validate the wasm module and extract a reader for a specific section.
17
59
macro_rules! extract_reader {
18
60
( $wasm_code: expr, $payload: ident, $t: ty) => { {
19
- fn extract( wasm_code: & [ u8 ] ) -> crate :: VmResult <Option <$t>> {
20
- use wasmer:: wasmparser:: { Parser , Payload , ValidPayload , Validator } ;
21
-
22
- let mut validator = Validator :: new( ) ;
23
- let parser = Parser :: new( 0 ) ;
24
-
61
+ fn extract( wasm_code: & [ u8 ] ) -> $crate:: VmResult <Option <$t>> {
25
62
let mut value = None ;
26
- for p in parser. parse_all( wasm_code) {
27
- let p = p?;
28
- // validate the payload
29
- if let ValidPayload :: Func ( mut fv, body) = validator. payload( & p) ? {
30
- // also validate function bodies
31
- fv. validate( & body) ?;
32
- }
33
- if let Payload :: $payload( e) = p {
34
- // do not return immediately, as we want to validate the entire module
35
- value = Some ( e) ;
63
+ $crate:: static_analysis:: validate_wasm( wasm_code, |p| {
64
+ if let Payload :: $payload( p) = p {
65
+ value = Some ( p) ;
36
66
}
37
- }
38
-
67
+ Ok ( ( ) )
68
+ } ) ? ;
39
69
Ok ( value)
40
70
}
41
71
0 commit comments