@@ -137,6 +137,16 @@ impl GovernanceInstruction {
137137 _ => Err ( format ! ( "Unknown governance action type: {action_type}" , ) ) ,
138138 } ;
139139
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+
140150 Ok ( GovernanceInstruction {
141151 module,
142152 action : action?,
@@ -205,3 +215,37 @@ impl GovernanceInstruction {
205215 Ok ( buf)
206216 }
207217}
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