srml-contracts: Forbid declaration of float types in contracts (#3234)

* srml-contracts: Forbid remaining uses of float types.

* Bump node runtime impl version.
This commit is contained in:
Jim Posen
2019-07-30 07:41:09 +02:00
committed by Gavin Wood
parent 483ad60379
commit 4c0934b2a7
2 changed files with 91 additions and 2 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 123,
impl_version: 123,
impl_version: 124,
apis: RUNTIME_API_VERSIONS,
};
+90 -1
View File
@@ -22,7 +22,7 @@ use crate::wasm::env_def::ImportSatisfyCheck;
use crate::wasm::PrefabWasmModule;
use crate::Schedule;
use parity_wasm::elements::{self, Internal, External, MemoryType, Type};
use parity_wasm::elements::{self, Internal, External, MemoryType, Type, ValueType};
use pwasm_utils;
use pwasm_utils::rules;
use rstd::prelude::*;
@@ -93,6 +93,50 @@ impl<'a> ContractModule<'a> {
Ok(())
}
/// Ensures that no floating point types are in use.
fn ensure_no_floating_types(&self) -> Result<(), &'static str> {
if let Some(global_section) = self.module.global_section() {
for global in global_section.entries() {
match global.global_type().content_type() {
ValueType::F32 | ValueType::F64 =>
return Err("use of floating point type in globals is forbidden"),
_ => {}
}
}
}
if let Some(code_section) = self.module.code_section() {
for func_body in code_section.bodies() {
for local in func_body.locals() {
match local.value_type() {
ValueType::F32 | ValueType::F64 =>
return Err("use of floating point type in locals is forbidden"),
_ => {}
}
}
}
}
if let Some(type_section) = self.module.type_section() {
for wasm_type in type_section.types() {
match wasm_type {
Type::Function(func_type) => {
let return_type = func_type.return_type();
for value_type in func_type.params().iter().chain(return_type.iter()) {
match value_type {
ValueType::F32 | ValueType::F64 =>
return Err("use of floating point type in function types is forbidden"),
_ => {}
}
}
}
}
}
}
Ok(())
}
fn inject_gas_metering(self) -> Result<Self, &'static str> {
let gas_rules =
rules::Set::new(
@@ -291,6 +335,7 @@ pub fn prepare_contract<C: ImportSatisfyCheck>(
contract_module.scan_exports()?;
contract_module.ensure_no_internal_memory()?;
contract_module.ensure_table_size_limit(schedule.max_table_size)?;
contract_module.ensure_no_floating_types()?;
struct MemoryDefinition {
initial: u32,
@@ -740,5 +785,49 @@ mod tests {
"#,
Err("unknown export: expecting only deploy and call functions")
);
prepare_test!(global_float,
r#"
(module
(global $x f32 (f32.const 0))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("use of floating point type in globals is forbidden")
);
prepare_test!(local_float,
r#"
(module
(func $foo (local f32))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("use of floating point type in locals is forbidden")
);
prepare_test!(param_float,
r#"
(module
(func $foo (param f32))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("use of floating point type in function types is forbidden")
);
prepare_test!(result_float,
r#"
(module
(func $foo (result f32) (f32.const 0))
(func (export "call"))
(func (export "deploy"))
)
"#,
Err("use of floating point type in function types is forbidden")
);
}
}