1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use super::ModuleError;
use parity_wasm::elements::{deserialize_buffer, serialize, Module};
pub trait HasNamesSection {
fn has_names_section(&self) -> bool;
}
impl HasNamesSection for Module {
fn has_names_section(&self) -> bool {
let mut module = self
.clone()
.parse_names()
.expect("parsing the names section failed");
module.names_section().is_some()
}
}
pub trait SerializationHelpers {
fn from_slice(input: &[u8]) -> Module;
fn to_vec(self) -> Vec<u8>;
}
impl SerializationHelpers for Module {
fn from_slice(input: &[u8]) -> Self {
deserialize_buffer::<Module>(&input).expect("invalid Wasm bytecode")
}
fn to_vec(self) -> Vec<u8> {
serialize::<Module>(self).expect("invalid Wasm module")
}
}
impl From<parity_wasm::SerializationError> for ModuleError {
fn from(a: parity_wasm::SerializationError) -> Self {
use std::error::Error;
ModuleError::Custom(a.description().to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
use rustc_hex::FromHex;
#[test]
fn module_roundtrip() {
let input = FromHex::from_hex(
"0061736d01000000010401600000030201000405017001010105030100100619
037f01418080c0000b7f00418080c0000b7f00418080c0000b072503066d656d
6f727902000b5f5f686561705f6261736503010a5f5f646174615f656e640302
0a040102000b",
)
.unwrap();
let module = Module::from_slice(&input);
let output = module.to_vec();
assert_eq!(input, output);
}
#[test]
fn bytecode_has_names_section() {
let input = FromHex::from_hex(
"0061736d010000000104016000000303020000070801046d61696e00010a
0a020300010b040010000b0014046e616d65010d0200047465737401046d
61696e",
)
.unwrap();
let module = Module::from_slice(&input);
assert_eq!(module.has_names_section(), true);
}
#[test]
fn bytecode_has_no_names_section() {
let input = FromHex::from_hex(
"0061736d010000000104016000000303020000070801046d61696e00010a
0a020300010b040010000b",
)
.unwrap();
let module = Module::from_slice(&input);
assert_eq!(module.has_names_section(), false);
}
fn try_serialize(module: Module) -> Result<Vec<u8>, ModuleError> {
Ok(serialize::<Module>(module)?)
}
fn try_deserialize(input: &[u8]) -> Result<Module, ModuleError> {
Ok(deserialize_buffer::<Module>(&input)?)
}
#[test]
fn test_serialize_error() {
let module = parity_wasm::builder::module()
.export()
.field("invalid")
.internal()
.func(15)
.build()
.build();
assert_eq!(try_serialize(module).is_ok(), true);
assert_eq!(try_serialize(Module::default()).is_ok(), true)
}
#[test]
fn test_deserialize_error() {
assert_eq!(try_deserialize(&[0u8; 0]).is_ok(), false);
let input = FromHex::from_hex(
"0061736d01000000010401600000030201000405017001010105030100100619
037f01418080c0000b7f00418080c0000b7f00418080c0000b072503066d656d
6f727902000b5f5f686561705f6261736503010a5f5f646174615f656e640302
0a040102000b",
)
.unwrap();
assert_eq!(try_deserialize(&input).is_ok(), true)
}
}