@@ -9,8 +9,11 @@ use block_buffer::{
99} ;
1010use hex_literal:: hex;
1111
12+ use core:: { array, panic:: AssertUnwindSafe } ;
13+ use std:: panic:: catch_unwind;
14+
1215#[ test]
13- fn test_eager_digest_pad ( ) {
16+ fn test_eager_digest ( ) {
1417 let mut buf = EagerBuffer :: < U4 > :: default ( ) ;
1518 let inputs = [
1619 & b"01234567" [ ..] ,
@@ -45,7 +48,7 @@ fn test_eager_digest_pad() {
4548}
4649
4750#[ test]
48- fn test_lazy_digest_pad ( ) {
51+ fn test_lazy_digest ( ) {
4952 let mut buf = LazyBuffer :: < U4 > :: default ( ) ;
5053 let inputs = [
5154 & b"01234567" [ ..] ,
@@ -78,6 +81,38 @@ fn test_lazy_digest_pad() {
7881 assert_eq ! ( buf. get_pos( ) , 0 ) ;
7982}
8083
84+ #[ test]
85+ fn digest_pad_combinations ( ) {
86+ let delim = 0x80 ;
87+ let data: [ u8 ; 7 ] = array:: from_fn ( |i| u8:: try_from ( i) . unwrap ( ) ) ;
88+ let suffix: [ u8 ; 7 ] = array:: from_fn ( |i| u8:: try_from ( i + 0x10 ) . unwrap ( ) ) ;
89+
90+ for data_len in 0 ..data. len ( ) {
91+ for suffix_len in 0 ..suffix. len ( ) {
92+ let data = & data[ ..data_len] ;
93+ let suffix = & suffix[ ..suffix_len] ;
94+ let mut buf = EagerBuffer :: < U8 > :: default ( ) ;
95+
96+ buf. digest_blocks ( data, |_| panic ! ( "should not be called" ) ) ;
97+
98+ let mut accum = Vec :: with_capacity ( 2 * buf. size ( ) ) ;
99+ buf. digest_pad ( delim, suffix, |block| accum. extend_from_slice ( block) ) ;
100+
101+ assert ! ( accum. len( ) <= 2 * buf. size( ) ) ;
102+ assert_eq ! ( buf. get_pos( ) , 0 ) ;
103+
104+ let ( res_data, rem) = accum. split_at ( data_len) ;
105+ let ( res_delim, rem) = rem. split_at ( 1 ) ;
106+ let ( res_zeros, res_suffix) = rem. split_at ( rem. len ( ) - suffix_len) ;
107+
108+ assert_eq ! ( res_data, data) ;
109+ assert_eq ! ( res_delim, & [ delim] ) ;
110+ assert ! ( res_zeros. iter( ) . all( |& b| b == 0 ) ) ;
111+ assert_eq ! ( res_suffix, suffix) ;
112+ }
113+ }
114+ }
115+
81116#[ test]
82117fn test_read ( ) {
83118 type Buf = ReadBuffer < U4 > ;
@@ -344,3 +379,57 @@ fn test_read_serialize() {
344379 let buf = Array ( [ 4 , 0 , 0 , 1 ] ) ;
345380 assert ! ( Buf :: deserialize( & buf) . is_err( ) ) ;
346381}
382+
383+ #[ test]
384+ fn eager_buffer_exception_safety ( ) {
385+ let mut buf = EagerBuffer :: < U4 > :: default ( ) ;
386+
387+ let res = catch_unwind ( AssertUnwindSafe ( || {
388+ buf. digest_blocks ( b"ab" , |_| { } ) ;
389+ buf. digest_blocks ( b"cd" , |_| panic ! ( "compression panic" ) ) ;
390+ } ) ) ;
391+
392+ assert ! ( res. is_err( ) ) ;
393+ let _ = buf. get_pos ( ) ;
394+
395+ let mut buf = EagerBuffer :: < U4 > :: default ( ) ;
396+
397+ let res = catch_unwind ( AssertUnwindSafe ( || {
398+ buf. digest_pad ( 0x80 , & [ 0xFF ; 2 ] , |_| panic ! ( "compression panic" ) ) ;
399+ } ) ) ;
400+
401+ assert ! ( res. is_err( ) ) ;
402+ let _ = buf. get_pos ( ) ;
403+ }
404+
405+ #[ test]
406+ fn read_buffer_exception_safety ( ) {
407+ let mut buf = ReadBuffer :: < U4 > :: default ( ) ;
408+
409+ let res = catch_unwind ( AssertUnwindSafe ( || {
410+ buf. write_block (
411+ 1 ,
412+ |block| {
413+ block[ 0 ] = 0xFF ;
414+ panic ! ( "block generation panic" ) ;
415+ } ,
416+ |_| { } ,
417+ ) ;
418+ } ) ) ;
419+
420+ assert ! ( res. is_err( ) ) ;
421+ let _ = buf. get_pos ( ) ;
422+
423+ let mut buf = ReadBuffer :: < U4 > :: default ( ) ;
424+
425+ let res = catch_unwind ( AssertUnwindSafe ( || {
426+ buf. write_block (
427+ 1 ,
428+ |block| block. 0 = [ 0xFF ; 4 ] ,
429+ |_| panic ! ( "data read panic" ) ,
430+ ) ;
431+ } ) ) ;
432+
433+ assert ! ( res. is_err( ) ) ;
434+ let _ = buf. get_pos ( ) ;
435+ }
0 commit comments