@@ -35,9 +35,7 @@ pub struct DeflateStream<'a> {
3535 pub ( crate ) total_out : crate :: c_api:: z_size ,
3636 pub ( crate ) msg : * const libc:: c_char ,
3737 pub ( crate ) state : & ' a mut State < ' a > ,
38- pub ( crate ) zalloc : crate :: c_api:: alloc_func ,
39- pub ( crate ) zfree : crate :: c_api:: free_func ,
40- pub ( crate ) opaque : crate :: c_api:: voidpf ,
38+ pub ( crate ) alloc : Allocator < ' a > ,
4139 pub ( crate ) data_type : libc:: c_int ,
4240 pub ( crate ) adler : crate :: c_api:: z_checksum ,
4341 pub ( crate ) reserved : crate :: c_api:: uLong ,
@@ -74,6 +72,11 @@ impl<'a> DeflateStream<'a> {
7472
7573 Some ( stream)
7674 }
75+
76+ fn as_z_stream_mut ( & mut self ) -> & mut z_stream {
77+ // safety: a valid &mut DeflateStream is also a valid &mut z_stream
78+ unsafe { & mut * ( self as * mut DeflateStream as * mut z_stream ) }
79+ }
7780}
7881
7982/// number of elements in hash table
@@ -258,11 +261,11 @@ pub fn init(stream: &mut z_stream, config: DeflateConfig) -> ReturnCode {
258261 if let Some ( mut sym_buf) = sym_buf {
259262 alloc. deallocate ( sym_buf. as_mut_ptr ( ) , sym_buf. capacity ( ) )
260263 }
261- if let Some ( mut pending) = pending {
264+ if let Some ( pending) = pending {
262265 pending. drop_in ( & alloc) ;
263266 }
264267 if let Some ( head) = head {
265- alloc. deallocate ( head. as_mut_ptr ( ) , HASH_SIZE )
268+ alloc. deallocate ( head. as_mut_ptr ( ) , 1 )
266269 }
267270 if let Some ( prev) = prev {
268271 alloc. deallocate ( prev. as_mut_ptr ( ) , prev. len ( ) )
@@ -434,12 +437,7 @@ pub fn copy<'a>(
434437 core:: ptr:: copy_nonoverlapping ( source, dest. as_mut_ptr ( ) , 1 ) ;
435438 }
436439
437- let alloc = Allocator {
438- zalloc : source. zalloc ,
439- zfree : source. zfree ,
440- opaque : source. opaque ,
441- _marker : PhantomData ,
442- } ;
440+ let alloc = & source. alloc ;
443441
444442 // allocated here to have the same order as zlib
445443 let Some ( state_allocation) = alloc. allocate :: < State > ( ) else {
@@ -448,13 +446,13 @@ pub fn copy<'a>(
448446
449447 let source_state = & source. state ;
450448
451- let window = source_state. window . clone_in ( & alloc) ;
449+ let window = source_state. window . clone_in ( alloc) ;
452450
453451 let prev = alloc. allocate_slice :: < u16 > ( source_state. w_size ) ;
454452 let head = alloc. allocate :: < [ u16 ; HASH_SIZE ] > ( ) ;
455453
456- let pending = source_state. pending . clone_in ( & alloc) ;
457- let sym_buf = source_state. sym_buf . clone_in ( & alloc) ;
454+ let pending = source_state. pending . clone_in ( alloc) ;
455+ let sym_buf = source_state. sym_buf . clone_in ( alloc) ;
458456
459457 // if any allocation failed, clean up allocations that did succeed
460458 let ( window, prev, head, pending, sym_buf) = match ( window, prev, head, pending, sym_buf) {
@@ -471,8 +469,8 @@ pub fn copy<'a>(
471469 if let Some ( mut sym_buf) = sym_buf {
472470 alloc. deallocate ( sym_buf. as_mut_ptr ( ) , sym_buf. capacity ( ) )
473471 }
474- if let Some ( mut pending) = pending {
475- pending. drop_in ( & alloc) ;
472+ if let Some ( pending) = pending {
473+ pending. drop_in ( alloc) ;
476474 }
477475 if let Some ( head) = head {
478476 alloc. deallocate ( head. as_mut_ptr ( ) , HASH_SIZE )
@@ -481,7 +479,7 @@ pub fn copy<'a>(
481479 alloc. deallocate ( prev. as_mut_ptr ( ) , prev. len ( ) )
482480 }
483481 if let Some ( mut window) = window {
484- window. drop_in ( & alloc) ;
482+ window. drop_in ( alloc) ;
485483 }
486484
487485 alloc. deallocate ( state_allocation. as_mut_ptr ( ) , 1 ) ;
@@ -558,37 +556,37 @@ pub fn copy<'a>(
558556 ReturnCode :: Ok
559557}
560558
561- pub fn end ( stream : & mut DeflateStream ) -> ReturnCode {
559+ /// # Returns
560+ ///
561+ /// - Err when deflate is not done. A common cause is insufficient output space
562+ /// - Ok otherwise
563+ pub fn end < ' a > ( stream : & ' a mut DeflateStream ) -> Result < & ' a mut z_stream , & ' a mut z_stream > {
562564 let status = stream. state . status ;
563565
564- let sym_buf = stream. state . sym_buf . as_mut_ptr ( ) ;
565- let pending = stream. state . pending . as_mut_ptr ( ) ;
566- let head = stream. state . head . as_mut_ptr ( ) ;
567- let prev = stream. state . prev . as_mut_ptr ( ) ;
568- let window = stream. state . window . as_mut_ptr ( ) ;
569- let state = stream. state as * mut State ;
566+ let alloc = stream. alloc ;
570567
571- let opaque = stream. opaque ;
572- let free = stream. zfree ;
568+ // deallocate in reverse order of allocations
569+ unsafe {
570+ // safety: we make sure that these fields are not used (by invalidating the state pointer)
571+ stream. state . sym_buf . drop_in ( & alloc) ;
572+ stream. state . pending . drop_in ( & alloc) ;
573+ alloc. deallocate ( stream. state . head , 1 ) ;
574+ alloc. deallocate ( stream. state . prev . as_mut_ptr ( ) , stream. state . prev . len ( ) ) ;
575+ stream. state . window . drop_in ( & alloc) ;
576+ }
573577
574- // safety: a valid &mut DeflateStream is also a valid & mut z_stream
575- let stream = unsafe { & mut * ( stream as * mut DeflateStream as * mut z_stream ) } ;
578+ let state = stream . state as * mut State ;
579+ let stream = stream. as_z_stream_mut ( ) ;
576580 stream. state = std:: ptr:: null_mut ( ) ;
577581
578- // deallocate in reverse order of allocations
582+ // safety: `state` is not used later
579583 unsafe {
580- free ( opaque, sym_buf. cast ( ) ) ;
581- free ( opaque, pending. cast ( ) ) ;
582- free ( opaque, head. cast ( ) ) ;
583- free ( opaque, prev. cast ( ) ) ;
584- free ( opaque, window. cast ( ) ) ;
585-
586- free ( opaque, state. cast ( ) ) ;
584+ alloc. deallocate ( state, 1 ) ;
587585 }
588586
589587 match status {
590- Status :: Busy => ReturnCode :: DataError ,
591- _ => ReturnCode :: Ok ,
588+ Status :: Busy => Err ( stream ) ,
589+ _ => Ok ( stream ) ,
592590 }
593591}
594592
@@ -2561,7 +2559,8 @@ pub fn compress<'a>(
25612559 } ;
25622560
25632561 if let Some ( stream) = unsafe { DeflateStream :: from_stream_mut ( & mut stream) } {
2564- end ( stream) ;
2562+ // error gets ignored here
2563+ let _ = end ( stream) ;
25652564 }
25662565
25672566 ( output_slice, ReturnCode :: Ok )
@@ -3041,7 +3040,7 @@ mod test {
30413040 assert_eq ! ( deflate( stream, Flush :: NoFlush ) , ReturnCode :: Ok ) ;
30423041
30433042 // but end is not
3044- assert_eq ! ( end( stream) , ReturnCode :: DataError ) ;
3043+ assert ! ( end( stream) . is_err ( ) ) ;
30453044 }
30463045
30473046 #[ test]
@@ -3512,7 +3511,7 @@ mod test {
35123511
35133512 let n = stream. total_out as usize ;
35143513
3515- assert_eq ! ( end( stream) , ReturnCode :: Ok ) ;
3514+ assert ! ( end( stream) . is_ok ( ) ) ;
35163515
35173516 let output_rs = & mut output[ ..n] ;
35183517
@@ -3567,7 +3566,7 @@ mod test {
35673566
35683567 let n = stream. total_out as usize ;
35693568
3570- assert_eq ! ( end( stream) , ReturnCode :: Ok ) ;
3569+ assert ! ( end( stream) . is_ok ( ) ) ;
35713570
35723571 let output_rs = & mut output[ ..n] ;
35733572
0 commit comments