@@ -2,11 +2,8 @@ use std::fmt;
22use std:: io:: { Cursor , Read } ;
33use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
44
5- use aes:: {
6- cipher:: BlockEncrypt ,
7- Aes128 , Block ,
8- } ;
9- use anyhow:: Result ;
5+ use aes:: { Aes128 , Block , cipher:: BlockEncrypt } ;
6+ use anyhow:: { Context , Result } ;
107use cmac:: { Cmac , Mac } ;
118use log:: warn;
129
@@ -276,7 +273,10 @@ pub struct UplinkPayload {
276273impl UplinkPayload {
277274 pub fn from_slice ( b : & [ u8 ] ) -> Result < UplinkPayload > {
278275 if b. len ( ) < 9 {
279- return Err ( anyhow ! ( "At least 9 bytes are expected" ) ) ;
276+ return Err ( anyhow ! (
277+ "This is not a mesh uplink packet. At least 9 bytes of payload are expected, got: {}. " ,
278+ b. len( )
279+ ) ) ;
280280 }
281281
282282 let mut md = [ 0 ; 5 ] ;
@@ -376,7 +376,7 @@ pub struct DownlinkPayload {
376376impl DownlinkPayload {
377377 pub fn from_slice ( b : & [ u8 ] ) -> Result < Self > {
378378 if b. len ( ) < 10 {
379- return Err ( anyhow ! ( "At least 10 bytes are expected" ) ) ;
379+ return Err ( anyhow ! ( "At least 10 bytes are expected, got: {}" , b . len ( ) ) ) ;
380380 }
381381
382382 let mut md = [ 0 ; 6 ] ;
@@ -463,18 +463,24 @@ pub struct EventPayload {
463463
464464impl EventPayload {
465465 pub fn from_slice ( b : & [ u8 ] ) -> Result < EventPayload > {
466+ if b. len ( ) < 8 {
467+ return Err ( anyhow ! (
468+ "This is not a mesh event packet. At least 8 bytes of payload are expected, got: {}" ,
469+ b. len( )
470+ ) ) ;
471+ }
466472 let b_len = b. len ( ) as u64 ;
467473 let mut cur = Cursor :: new ( b) ;
468474 let mut ts_b: [ u8 ; 4 ] = [ 0 ; 4 ] ;
469475
470- cur. read_exact ( & mut ts_b) ?;
476+ cur. read_exact ( & mut ts_b) . context ( "Read timestamp" ) ?;
471477 let timestamp = u32:: from_be_bytes ( ts_b) ;
472478 let timestamp = UNIX_EPOCH
473479 . checked_add ( Duration :: from_secs ( timestamp. into ( ) ) )
474480 . ok_or_else ( || anyhow ! ( "Invalid timestamp" ) ) ?;
475481
476482 let mut relay_id: [ u8 ; 4 ] = [ 0 ; 4 ] ;
477- cur. read_exact ( & mut relay_id) ?;
483+ cur. read_exact ( & mut relay_id) . context ( "Read relay_id" ) ?;
478484
479485 let mut events = Vec :: new ( ) ;
480486
@@ -591,10 +597,10 @@ pub enum Event {
591597impl Event {
592598 pub fn decode ( cur : & mut Cursor < & [ u8 ] > ) -> Result < Self > {
593599 let mut tag_length: [ u8 ; 2 ] = [ 0 ; 2 ] ;
594- cur. read_exact ( & mut tag_length) ?;
600+ cur. read_exact ( & mut tag_length) . context ( "Read tag_length" ) ?;
595601
596602 let mut value = vec ! [ 0 ; tag_length[ 1 ] as usize ] ;
597- cur. read_exact ( & mut value) ?;
603+ cur. read_exact ( & mut value) . context ( "Read value" ) ?;
598604
599605 Ok ( match tag_length[ 0 ] {
600606 0x00 => Event :: Heartbeat ( HeartbeatPayload :: from_slice ( & value) ?) ,
@@ -714,18 +720,24 @@ pub struct CommandPayload {
714720
715721impl CommandPayload {
716722 pub fn from_slice ( b : & [ u8 ] ) -> Result < CommandPayload > {
723+ if b. len ( ) < 8 {
724+ return Err ( anyhow ! (
725+ "This is not a mesh command packet : at least 8 bytes of payload are expected, got: {}" ,
726+ b. len( )
727+ ) ) ;
728+ }
717729 let b_len = b. len ( ) as u64 ;
718730 let mut cur = Cursor :: new ( b) ;
719731 let mut ts_b: [ u8 ; 4 ] = [ 0 ; 4 ] ;
720732
721- cur. read_exact ( & mut ts_b) ?;
733+ cur. read_exact ( & mut ts_b) . context ( "Read timestamp" ) ?;
722734 let timestamp = u32:: from_be_bytes ( ts_b) ;
723735 let timestamp = UNIX_EPOCH
724736 . checked_add ( Duration :: from_secs ( timestamp. into ( ) ) )
725737 . ok_or_else ( || anyhow ! ( "Invalid timestamp" ) ) ?;
726738
727739 let mut relay_id: [ u8 ; 4 ] = [ 0 ; 4 ] ;
728- cur. read_exact ( & mut relay_id) ?;
740+ cur. read_exact ( & mut relay_id) . context ( "Read relay_id" ) ?;
729741
730742 let mut commands = Vec :: new ( ) ;
731743
@@ -841,10 +853,10 @@ pub enum Command {
841853impl Command {
842854 pub fn decode ( cur : & mut Cursor < & [ u8 ] > ) -> Result < Self > {
843855 let mut tag_length: [ u8 ; 2 ] = [ 0 ; 2 ] ;
844- cur. read_exact ( & mut tag_length) ?;
856+ cur. read_exact ( & mut tag_length) . context ( "Read tag_length" ) ?;
845857
846858 let mut value = vec ! [ 0 ; tag_length[ 1 ] as usize ] ;
847- cur. read_exact ( & mut value) ?;
859+ cur. read_exact ( & mut value) . context ( "Read value" ) ?;
848860
849861 Ok ( Command :: Proprietary ( ( tag_length[ 0 ] , value) ) )
850862 }
@@ -1406,7 +1418,9 @@ mod test {
14061418 } ;
14071419 let b = dn_pl. to_vec ( ) . unwrap ( ) ;
14081420 assert_eq ! (
1409- vec![ 0x40 , 0x03 , 0x84 , 0x76 , 0x28 , 0xff , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , ] ,
1421+ vec![
1422+ 0x40 , 0x03 , 0x84 , 0x76 , 0x28 , 0xff , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 ,
1423+ ] ,
14101424 b
14111425 ) ;
14121426 }
@@ -1468,7 +1482,9 @@ mod test {
14681482 } ;
14691483 let b = event_pl. to_vec ( ) . unwrap ( ) ;
14701484 assert_eq ! (
1471- vec![ 59 , 154 , 202 , 0 , 1 , 2 , 3 , 4 , 0 , 12 , 5 , 6 , 7 , 8 , 120 , 52 , 9 , 10 , 11 , 12 , 120 , 52 ] ,
1485+ vec![
1486+ 59 , 154 , 202 , 0 , 1 , 2 , 3 , 4 , 0 , 12 , 5 , 6 , 7 , 8 , 120 , 52 , 9 , 10 , 11 , 12 , 120 , 52
1487+ ] ,
14721488 b
14731489 ) ;
14741490 }
@@ -1735,4 +1751,29 @@ mod test {
17351751 assert_eq ! ( tst. expected_bytes, b) ;
17361752 }
17371753 }
1754+
1755+ #[ test]
1756+ fn test_mesh_packet_from_slice_too_short ( ) {
1757+ // PayloadType::Event, but only 1 byte of payload (MHDR(1) + EventPayload(1) + MIC(4) = 6 bytes)
1758+ // EventPayload needs at least 8 bytes (4 for timestamp, 4 for relay_id)
1759+ let b = vec ! [
1760+ MHDR {
1761+ payload_type: PayloadType :: Event ,
1762+ hop_count: 1 ,
1763+ }
1764+ . to_byte( )
1765+ . unwrap( ) ,
1766+ 0x00 , // 1 byte of payload (not enough for EventPayload)
1767+ 0x00 ,
1768+ 0x00 ,
1769+ 0x00 ,
1770+ 0x00 , // MIC
1771+ ] ;
1772+ let res = MeshPacket :: from_slice ( & b) ;
1773+ assert ! ( res. is_err( ) ) ;
1774+ assert_eq ! (
1775+ res. unwrap_err( ) . to_string( ) ,
1776+ "This is not a mesh event packet. At least 8 bytes of payload are expected, got: 1"
1777+ ) ;
1778+ }
17381779}
0 commit comments