Contract import/export validation (#2203)

* Reject validation of contract with unknown exports

* Validate imports eagerly

* Increment spec version
This commit is contained in:
Andrew Jones
2019-04-06 12:23:56 +01:00
committed by Sergei Pepyakin
parent decddaab0f
commit 03f3fb1442
2 changed files with 71 additions and 3 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node"),
impl_name: create_runtime_str!("substrate-node"),
authoring_version: 10,
spec_version: 57,
spec_version: 58,
impl_version: 59,
apis: RUNTIME_API_VERSIONS,
};
+70 -2
View File
@@ -108,6 +108,8 @@ impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
///
/// - 'call'
/// - 'deploy'
///
/// Any other exports are not allowed.
fn scan_exports(&self) -> Result<(), &'static str> {
let mut deploy_found = false;
let mut call_found = false;
@@ -147,7 +149,7 @@ impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
match export.field() {
"call" => call_found = true,
"deploy" => deploy_found = true,
_ => continue,
_ => return Err("unknown export: expecting only deploy and call functions"),
}
// Then check the export kind. "call" and "deploy" are
@@ -218,12 +220,19 @@ impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
}
let type_idx = match import.external() {
&External::Table(_) => return Err("Cannot import tables"),
&External::Global(_) => return Err("Cannot import globals"),
&External::Function(ref type_idx) => type_idx,
&External::Memory(ref memory_type) => {
if import.field() != "memory" {
return Err("Memory import must have the field name 'memory'")
}
if imported_mem_type.is_some() {
return Err("Multiple memory imports defined")
}
imported_mem_type = Some(memory_type);
continue;
}
_ => continue,
};
let Type::Function(ref func_ty) = types
@@ -447,6 +456,54 @@ mod tests {
"#,
Err("Maximum number of pages should not exceed the configured maximum.")
);
prepare_test!(field_name_not_memory,
r#"
(module
(import "env" "forgetit" (memory 1 1))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("Memory import must have the field name 'memory'")
);
prepare_test!(multiple_memory_imports,
r#"
(module
(import "env" "memory" (memory 1 1))
(import "env" "memory" (memory 1 1))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("Multiple memory imports defined")
);
prepare_test!(table_import,
r#"
(module
(import "env" "table" (table 1 anyfunc))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("Cannot import tables")
);
prepare_test!(global_import,
r#"
(module
(global $g (import "env" "global") (mut i32))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("Cannot import globals")
);
}
mod imports {
@@ -582,5 +639,16 @@ mod tests {
"#,
Err("entry point has wrong signature")
);
prepare_test!(unknown_exports,
r#"
(module
(func (export "call"))
(func (export "deploy"))
(func (export "whatevs"))
)
"#,
Err("unknown export: expecting only deploy and call functions")
);
}
}