@@ -83,7 +83,7 @@ fn test_process_create_ok() {
8383 & [ ( config, config_account) ] ,
8484 & [
8585 Check :: success ( ) ,
86- Check :: compute_units ( 581 ) ,
86+ Check :: compute_units ( 584 ) ,
8787 Check :: account ( & config)
8888 . data (
8989 & bincode:: serialize ( & ( ConfigKeys { keys : vec ! [ ] } , MyConfig :: default ( ) ) )
@@ -111,7 +111,7 @@ fn test_process_store_ok() {
111111 & [ ( config, config_account) ] ,
112112 & [
113113 Check :: success ( ) ,
114- Check :: compute_units ( 581 ) ,
114+ Check :: compute_units ( 584 ) ,
115115 Check :: account ( & config)
116116 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , my_config) ) . unwrap ( ) )
117117 . build ( ) ,
@@ -186,7 +186,7 @@ fn test_process_store_with_additional_signers() {
186186 ] ,
187187 & [
188188 Check :: success ( ) ,
189- Check :: compute_units ( 3_228 ) ,
189+ Check :: compute_units ( 3_253 ) ,
190190 Check :: account ( & config)
191191 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , my_config) ) . unwrap ( ) )
192192 . build ( ) ,
@@ -285,7 +285,7 @@ fn test_config_updates() {
285285 ( signer0, AccountSharedData :: default ( ) ) ,
286286 ( signer1, AccountSharedData :: default ( ) ) ,
287287 ] ,
288- & [ Check :: success ( ) , Check :: compute_units ( 3_228 ) ] ,
288+ & [ Check :: success ( ) , Check :: compute_units ( 3_253 ) ] ,
289289 ) ;
290290
291291 // Use this for next invoke.
@@ -303,7 +303,7 @@ fn test_config_updates() {
303303 ] ,
304304 & [
305305 Check :: success ( ) ,
306- Check :: compute_units ( 3_229 ) ,
306+ Check :: compute_units ( 3_254 ) ,
307307 Check :: account ( & config)
308308 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , new_config) ) . unwrap ( ) )
309309 . build ( ) ,
@@ -399,7 +399,7 @@ fn test_config_update_contains_duplicates_fails() {
399399 ( signer0, AccountSharedData :: default ( ) ) ,
400400 ( signer1, AccountSharedData :: default ( ) ) ,
401401 ] ,
402- & [ Check :: success ( ) , Check :: compute_units ( 3_228 ) ] ,
402+ & [ Check :: success ( ) , Check :: compute_units ( 3_253 ) ] ,
403403 ) ;
404404
405405 // Attempt update with duplicate signer inputs.
@@ -443,7 +443,7 @@ fn test_config_updates_requiring_config() {
443443 ] ,
444444 & [
445445 Check :: success ( ) ,
446- Check :: compute_units ( 3_324 ) ,
446+ Check :: compute_units ( 3_352 ) ,
447447 Check :: account ( & config)
448448 . data ( & bincode:: serialize ( & ( ConfigKeys { keys : keys. clone ( ) } , my_config) ) . unwrap ( ) )
449449 . build ( ) ,
@@ -464,7 +464,7 @@ fn test_config_updates_requiring_config() {
464464 ] ,
465465 & [
466466 Check :: success ( ) ,
467- Check :: compute_units ( 3_324 ) ,
467+ Check :: compute_units ( 3_352 ) ,
468468 Check :: account ( & config)
469469 . data ( & bincode:: serialize ( & ( ConfigKeys { keys } , new_config) ) . unwrap ( ) )
470470 . build ( ) ,
@@ -558,7 +558,7 @@ fn test_maximum_keys_input() {
558558 let result = mollusk. process_and_validate_instruction (
559559 & instruction,
560560 & [ ( config, config_account) ] ,
561- & [ Check :: success ( ) , Check :: compute_units ( 25_020 ) ] ,
561+ & [ Check :: success ( ) , Check :: compute_units ( 25_247 ) ] ,
562562 ) ;
563563
564564 // Use this for next invoke.
@@ -571,7 +571,7 @@ fn test_maximum_keys_input() {
571571 let result = mollusk. process_and_validate_instruction (
572572 & instruction,
573573 & [ ( config, updated_config_account) ] ,
574- & [ Check :: success ( ) , Check :: compute_units ( 25_020 ) ] ,
574+ & [ Check :: success ( ) , Check :: compute_units ( 25_247 ) ] ,
575575 ) ;
576576
577577 // Use this for next invoke.
@@ -587,3 +587,65 @@ fn test_maximum_keys_input() {
587587 & [ Check :: err ( ProgramError :: InvalidInstructionData ) ] ,
588588 ) ;
589589}
590+
591+ #[ test]
592+ fn test_safe_deserialize ( ) {
593+ let mollusk = setup ( ) ;
594+
595+ // Accounts don't matter for this test.
596+
597+ // First try to spoof the program with just `ShortU16` length values.
598+ let build_instruction =
599+ |data : & [ u8 ] | Instruction :: new_with_bytes ( solana_config_program:: id ( ) , data, vec ! [ ] ) ;
600+
601+ mollusk. process_and_validate_instruction (
602+ // Empty buffer. Not a valid `ShortU16`.
603+ & build_instruction ( & [ ] ) ,
604+ & [ ] ,
605+ & [ Check :: err ( ProgramError :: InvalidInstructionData ) ] ,
606+ ) ;
607+
608+ mollusk. process_and_validate_instruction (
609+ // `ShortU16` value of 38. One byte too large.
610+ & build_instruction ( & [ 0x26 ] ) ,
611+ & [ ] ,
612+ & [ Check :: err ( ProgramError :: InvalidInstructionData ) ] ,
613+ ) ;
614+
615+ mollusk. process_and_validate_instruction (
616+ // `ShortU16` value of 37. OK for vector size, but no keys following.
617+ & build_instruction ( & [ 0x25 ] ) ,
618+ & [ ] ,
619+ & [ Check :: err ( ProgramError :: InvalidInstructionData ) ] ,
620+ ) ;
621+
622+ // Now try with some actual `ConfigKeys` inputs.
623+ let mut keys = Vec :: new ( ) ;
624+ let serialized_config_keys = |keys : & [ ( Pubkey , bool ) ] | {
625+ let config_keys = ConfigKeys {
626+ keys : keys. to_vec ( ) ,
627+ } ;
628+ bincode:: serialize ( & config_keys) . unwrap ( )
629+ } ;
630+
631+ // First build out to an acceptable size of 37.
632+ ( 0 ..37 ) . for_each ( |i| keys. push ( ( Pubkey :: new_unique ( ) , i % 2 == 0 ) ) ) ;
633+
634+ mollusk. process_and_validate_instruction (
635+ // `ShortU16` value of 37. OK.
636+ & build_instruction ( & serialized_config_keys ( & keys) ) ,
637+ & [ ] ,
638+ // Falls through to account keys failure.
639+ & [ Check :: err ( ProgramError :: NotEnoughAccountKeys ) ] ,
640+ ) ;
641+
642+ // Add one more key, pushing the size to 38.
643+ keys. push ( ( Pubkey :: new_unique ( ) , true ) ) ;
644+
645+ mollusk. process_and_validate_instruction (
646+ // `ShortU16` value of 38. Err.
647+ & build_instruction ( & serialized_config_keys ( & keys) ) ,
648+ & [ ] ,
649+ & [ Check :: err ( ProgramError :: InvalidInstructionData ) ] ,
650+ ) ;
651+ }
0 commit comments