Skip to content

Commit af76844

Browse files
authored
Merge pull request #2188 from CosmWasm/co/wasm-params-check-docs
Add doc comments and tests for params validation
2 parents 4308226 + a6a53f5 commit af76844

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

packages/vm/src/compatibility.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,23 @@ const TABLE_SIZE_LIMIT: u32 = 2500; // entries
7878
/// when a user accidentally includes wasm-bindgen, they get a bunch of unsupported imports.
7979
const MAX_IMPORTS: usize = 100;
8080

81+
/// The maximum number of functions a contract can have.
82+
/// Any contract with more functions than this will be rejected during static validation.
8183
const MAX_FUNCTIONS: usize = 20_000;
8284

85+
/// The maximum number of parameters a wasm function can have.
86+
/// Any contract with a function type with more parameters than this will be rejected
87+
/// during static validation.
8388
const MAX_FUNCTION_PARAMS: usize = 100;
8489

90+
/// The maximum total number of parameters of all functions in the wasm.
91+
/// For each function in the wasm, take the number of parameters and sum all of these up.
92+
/// If that sum exceeds this limit, the wasm will be rejected during static validation.
8593
const MAX_TOTAL_FUNCTION_PARAMS: usize = 10_000;
8694

95+
/// The maximum number of results a wasm function can have.
96+
/// Any contract with a function type with more results than this will be rejected
97+
/// during static validation.
8798
const MAX_FUNCTION_RESULTS: usize = 1;
8899

89100
/// Checks if the data is valid wasm and compatibility with the CosmWasm API (imports and exports)
@@ -935,4 +946,63 @@ mod tests {
935946
_ => panic!("Got unexpected error"),
936947
}
937948
}
949+
950+
#[test]
951+
fn check_wasm_fails_for_big_functions() {
952+
// too many arguments
953+
let args = " i32".repeat(MAX_FUNCTION_PARAMS + 1);
954+
let wasm = wat::parse_str(format!(
955+
r#"(module
956+
(type (func (param {args})))
957+
(func (type 0) nop)
958+
)"#
959+
))
960+
.unwrap();
961+
let module = ParsedWasm::parse(&wasm).unwrap();
962+
963+
match check_wasm_functions(&module).unwrap_err() {
964+
VmError::StaticValidationErr { msg, .. } => assert_eq!(
965+
msg,
966+
"Wasm contract contains function with more than 100 parameters"
967+
),
968+
_ => panic!("Got unexpected error"),
969+
}
970+
971+
// too many returns
972+
let return_types = " i32".repeat(MAX_FUNCTION_RESULTS + 1);
973+
let returns = " i32.const 42".repeat(MAX_FUNCTION_RESULTS + 1);
974+
let wasm = wat::parse_str(format!(
975+
r#"(module
976+
(type (func (result {return_types})))
977+
(func (type 0) {returns})
978+
)"#
979+
))
980+
.unwrap();
981+
let module = ParsedWasm::parse(&wasm).unwrap();
982+
match check_wasm_functions(&module).unwrap_err() {
983+
VmError::StaticValidationErr { msg, .. } => assert_eq!(
984+
msg,
985+
"Wasm contract contains function with more than 1 results"
986+
),
987+
_ => panic!("Got unexpected error"),
988+
}
989+
990+
// too many functions
991+
let functions = ["(func (type 0) nop)"; MAX_FUNCTIONS + 1];
992+
let functions = functions.join("\n");
993+
let wasm = wat::parse_str(format!(
994+
r#"(module
995+
(type (func))
996+
{functions}
997+
)"#
998+
))
999+
.unwrap();
1000+
let module = ParsedWasm::parse(&wasm).unwrap();
1001+
match check_wasm_functions(&module).unwrap_err() {
1002+
VmError::StaticValidationErr { msg, .. } => {
1003+
assert_eq!(msg, "Wasm contract contains more than 20000 functions")
1004+
}
1005+
_ => panic!("Got unexpected error"),
1006+
}
1007+
}
9381008
}

packages/vm/src/parsed_wasm.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,45 @@ mod test {
249249
.unwrap();
250250
assert!(ParsedWasm::parse(&wasm_data).is_err());
251251
}
252+
253+
#[test]
254+
fn parsed_wasm_counts_functions_correctly() {
255+
let wasm = wat::parse_str(r#"(module)"#).unwrap();
256+
let module = ParsedWasm::parse(&wasm).unwrap();
257+
assert_eq!(module.function_count, 0);
258+
259+
let wasm = wat::parse_str(
260+
r#"(module
261+
(type (func))
262+
(func (type 0) nop)
263+
(func (type 0) nop)
264+
(export "foo" (func 0))
265+
(export "bar" (func 0))
266+
)"#,
267+
)
268+
.unwrap();
269+
let module = ParsedWasm::parse(&wasm).unwrap();
270+
assert_eq!(module.function_count, 2);
271+
}
272+
273+
#[test]
274+
fn parsed_wasm_counts_func_io_correctly() {
275+
let wasm = wat::parse_str(r#"(module)"#).unwrap();
276+
let module = ParsedWasm::parse(&wasm).unwrap();
277+
assert_eq!(module.max_func_params, 0);
278+
assert_eq!(module.max_func_results, 0);
279+
280+
let wasm = wat::parse_str(
281+
r#"(module
282+
(type (func (param i32 i32 i32) (result i32)))
283+
(type (func (param i32) (result i32 i32)))
284+
(func (type 1) i32.const 42 i32.const 42)
285+
(func (type 0) i32.const 42)
286+
)"#,
287+
)
288+
.unwrap();
289+
let module = ParsedWasm::parse(&wasm).unwrap();
290+
assert_eq!(module.max_func_params, 3);
291+
assert_eq!(module.max_func_results, 2);
292+
}
252293
}

0 commit comments

Comments
 (0)