@@ -430,7 +430,7 @@ impl<R: AsyncStreamReader> ResponseDecoder<R> {
430430 let this = & mut self . 0 ;
431431 let data = this
432432 . encoded
433- . read_bytes ( size)
433+ . read_bytes_exact ( size)
434434 . await
435435 . map_err ( |e| DecodeError :: maybe_leaf_not_found ( e, start_chunk) ) ?;
436436 let leaf_hash = this. stack . pop ( ) . unwrap ( ) ;
@@ -482,7 +482,7 @@ where
482482 start_chunk, size, ..
483483 } => {
484484 let start = start_chunk. to_bytes ( ) ;
485- let bytes = data. read_at ( start, size) . await ?;
485+ let bytes = data. read_exact_at ( start, size) . await ?;
486486 encoded
487487 . write_bytes ( bytes)
488488 . await
@@ -556,6 +556,11 @@ where
556556 let expected = stack. pop ( ) . unwrap ( ) ;
557557 let start = start_chunk. to_bytes ( ) ;
558558 let bytes = data. read_at ( start, size) . await ?;
559+ if bytes. len ( ) != size as usize {
560+ return Err ( EncodeError :: Io (
561+ io:: ErrorKind :: UnexpectedEof . into ( ) ,
562+ ) ) ;
563+ }
559564 let ( actual, to_write) = if !ranges. is_all ( ) {
560565 // we need to encode just a part of the data
561566 //
@@ -669,7 +674,7 @@ async fn outboard_impl(
669674 start_chunk,
670675 ..
671676 } => {
672- let buf = data. read_bytes ( size) . await ?;
677+ let buf = data. read_bytes_exact ( size) . await ?;
673678 let hash = hash_subtree ( start_chunk. 0 , & buf, is_root) ;
674679 stack. push ( hash) ;
675680 }
@@ -722,7 +727,7 @@ async fn outboard_post_order_impl(
722727 start_chunk,
723728 ..
724729 } => {
725- let buf = data. read_bytes ( size) . await ?;
730+ let buf = data. read_bytes_exact ( size) . await ?;
726731 let hash = hash_subtree ( start_chunk. 0 , & buf, is_root) ;
727732 stack. push ( hash) ;
728733 }
@@ -803,6 +808,12 @@ mod validate {
803808 // special case for a tree that fits in one block / chunk group
804809 let mut data = data;
805810 let data = data. read_at ( 0 , tree. size ( ) . try_into ( ) . unwrap ( ) ) . await ?;
811+ if data. len ( ) != tree. size ( ) as usize {
812+ return Err ( io:: Error :: new (
813+ io:: ErrorKind :: UnexpectedEof ,
814+ "data is smaller than expected" ,
815+ ) ) ;
816+ }
806817 let actual = hash_subtree ( 0 , & data, true ) ;
807818 if actual == outboard. root ( ) {
808819 co. yield_ ( Ok ( ChunkNum ( 0 ) ..tree. chunks ( ) ) ) . await ;
@@ -831,7 +842,7 @@ mod validate {
831842 is_root : bool ,
832843 ) -> io:: Result < ( ) > {
833844 let len = ( range. end - range. start ) . try_into ( ) . unwrap ( ) ;
834- let data = self . data . read_at ( range. start , len) . await ?;
845+ let data = self . data . read_exact_at ( range. start , len) . await ?;
835846 // is_root is always false because the case of a single chunk group is handled before calling this function
836847 let actual = hash_subtree ( ChunkNum :: full_chunks ( range. start ) . 0 , & data, is_root) ;
837848 if & actual == hash {
0 commit comments