@@ -137,6 +137,16 @@ impl GovernanceInstruction {
137
137
_ => Err ( format ! ( "Unknown governance action type: {action_type}" , ) ) ,
138
138
} ;
139
139
140
+ // Check that we're at the end of the buffer (to ensure that this contract knows how to
141
+ // interpret every field in the governance message). The logic is a little janky
142
+ // but seems to be the simplest way to check that the reader is at EOF.
143
+ let mut next_byte = [ 0_u8 ; 1 ] ;
144
+ let read_result = bytes. read ( & mut next_byte) ;
145
+ match read_result {
146
+ Ok ( 0 ) => ( ) ,
147
+ _ => Err ( "Governance action had an unexpectedly long payload." . to_string ( ) ) ?,
148
+ }
149
+
140
150
Ok ( GovernanceInstruction {
141
151
module,
142
152
action : action?,
@@ -205,3 +215,37 @@ impl GovernanceInstruction {
205
215
Ok ( buf)
206
216
}
207
217
}
218
+
219
+ #[ cfg( test) ]
220
+ mod test {
221
+ use crate :: governance:: {
222
+ GovernanceAction ,
223
+ GovernanceInstruction ,
224
+ GovernanceModule ,
225
+ } ;
226
+
227
+ #[ test]
228
+ fn test_payload_wrong_size ( ) {
229
+ let instruction = GovernanceInstruction {
230
+ module : GovernanceModule :: Target ,
231
+ action : GovernanceAction :: SetFee {
232
+ val : 100 ,
233
+ expo : 200 ,
234
+ } ,
235
+ target_chain_id : 7 ,
236
+ } ;
237
+
238
+ let mut buf: Vec < u8 > = instruction. serialize ( ) . unwrap ( ) ;
239
+
240
+ let result = GovernanceInstruction :: deserialize ( buf. as_slice ( ) ) ;
241
+ assert ! ( result. is_ok( ) ) ;
242
+ assert_eq ! ( result. unwrap( ) , instruction) ;
243
+
244
+ buf. push ( 0 ) ;
245
+ let result = GovernanceInstruction :: deserialize ( buf. as_slice ( ) ) ;
246
+ assert ! ( result. is_err( ) ) ;
247
+
248
+ let result = GovernanceInstruction :: deserialize ( & buf[ 0 ..buf. len ( ) - 2 ] ) ;
249
+ assert ! ( result. is_err( ) ) ;
250
+ }
251
+ }
0 commit comments