diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # lzlib
 
+## 1.0.7.1
+
+  * Bump C sources to lzlib 1.12
+
 ## 1.0.7.0
 
   * Add `Bounded` instance to `CompressionLevel`
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Vanessa McHale (c) 2019-2020
+Copyright Vanessa McHale (c) 2019-2021
 
 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
diff --git a/bench/Bench.hs b/bench/Bench.hs
--- a/bench/Bench.hs
+++ b/bench/Bench.hs
@@ -1,6 +1,7 @@
 module Main (main) where
 
 import           Codec.Lzip
+import           Control.Applicative  ((<$>))
 import           Criterion.Main
 import qualified Data.ByteString.Lazy as BSL
 import           System.FilePath      ((</>))
@@ -14,7 +15,7 @@
 pack :: FilePath -> IO ()
 pack fp' = withSystemTempDirectory "lzlib" $
     \fp -> BSL.writeFile (fp </> "dump.tar.lz") =<<
-        (compressFile fp')
+        compressFile fp'
 
 main :: IO ()
 main =
diff --git a/cbits/cbuffer.c b/cbits/cbuffer.c
--- a/cbits/cbuffer.c
+++ b/cbits/cbuffer.c
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 struct Circular_buffer
diff --git a/cbits/decoder.c b/cbits/decoder.c
--- a/cbits/decoder.c
+++ b/cbits/decoder.c
@@ -1,27 +1,27 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 static int LZd_try_verify_trailer( struct LZ_decoder * const d )
   {
   Lzip_trailer trailer;
-  if( Rd_available_bytes( d->rdec ) < Lt_size && !d->rdec->at_stream_end )
-    return 0;
+  if( Rd_available_bytes( d->rdec ) < Lt_size )
+    { if( !d->rdec->at_stream_end ) return 0; else return 2; }
   d->verify_trailer_pending = false;
   d->member_finished = true;
 
@@ -40,10 +40,10 @@
   {
   struct Range_decoder * const rdec = d->rdec;
   State * const state = &d->state;
-  /* unsigned old_mpos = d->rdec->member_position; */
+  /* unsigned old_mpos = rdec->member_position; */
 
   if( d->member_finished ) return 0;
-  if( !Rd_try_reload( rdec, false ) )
+  if( !Rd_try_reload( rdec ) )
     { if( !rdec->at_stream_end ) return 0; else return 2; }
   if( d->verify_trailer_pending ) return LZd_try_verify_trailer( d );
 
@@ -51,7 +51,7 @@
     {
     int len;
     const int pos_state = LZd_data_position( d ) & pos_state_mask;
-    /* const unsigned mpos = d->rdec->member_position;
+    /* const unsigned mpos = rdec->member_position;
     if( mpos - old_mpos > rd_min_available_bytes ) return 5;
     old_mpos = mpos; */
     if( !Rd_enough_available_bytes( rdec ) )	/* check unexpected EOF */
@@ -123,6 +123,9 @@
           if( distance == 0xFFFFFFFFU )		/* marker found */
             {
             Rd_normalize( rdec );
+            /* const unsigned mpos = rdec->member_position;
+            if( mpos - old_mpos > rd_min_available_bytes ) return 5;
+            old_mpos = mpos; */
             if( len == min_match_len )		/* End Of Stream marker */
               {
               d->verify_trailer_pending = true;
@@ -130,7 +133,8 @@
               }
             if( len == min_match_len + 1 )	/* Sync Flush marker */
               {
-              if( Rd_try_reload( rdec, true ) ) { /*old_mpos += 5;*/ continue; }
+              rdec->reload_pending = true;
+              if( Rd_try_reload( rdec ) ) continue;
               else { if( !rdec->at_stream_end ) return 0; else break; }
               }
             return 4;
diff --git a/cbits/decoder.h b/cbits/decoder.h
--- a/cbits/decoder.h
+++ b/cbits/decoder.h
@@ -1,23 +1,23 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
-enum { rd_min_available_bytes = 8 };
+enum { rd_min_available_bytes = 10 };
 
 struct Range_decoder
   {
@@ -133,9 +133,8 @@
   return true;
   }
 
-static bool Rd_try_reload( struct Range_decoder * const rdec, const bool force )
+static bool Rd_try_reload( struct Range_decoder * const rdec )
   {
-  if( force ) rdec->reload_pending = true;
   if( rdec->reload_pending && Rd_available_bytes( rdec ) >= 5 )
     {
     int i;
@@ -168,7 +167,7 @@
 /*    symbol <<= 1; */
 /*    if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */
     bit = ( rdec->code >= rdec->range );
-    symbol = ( symbol << 1 ) + bit;
+    symbol <<= 1; symbol += bit;
     rdec->code -= rdec->range & ( 0U - bit );
     }
   return symbol;
@@ -182,15 +181,15 @@
   bound = ( rdec->range >> bit_model_total_bits ) * *probability;
   if( rdec->code < bound )
     {
-    rdec->range = bound;
     *probability += (bit_model_total - *probability) >> bit_model_move_bits;
+    rdec->range = bound;
     return 0;
     }
   else
     {
-    rdec->range -= bound;
-    rdec->code -= bound;
     *probability -= *probability >> bit_model_move_bits;
+    rdec->code -= bound;
+    rdec->range -= bound;
     return 1;
     }
   }
@@ -198,8 +197,7 @@
 static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec,
                                         Bit_model bm[] )
   {
-  unsigned symbol = 1;
-  symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
+  unsigned symbol = 2 | Rd_decode_bit( rdec, &bm[1] );
   symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
   symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
   return symbol & 7;
@@ -208,8 +206,7 @@
 static inline unsigned Rd_decode_tree6( struct Range_decoder * const rdec,
                                         Bit_model bm[] )
   {
-  unsigned symbol = 1;
-  symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
+  unsigned symbol = 2 | Rd_decode_bit( rdec, &bm[1] );
   symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
   symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
   symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
@@ -238,7 +235,7 @@
   for( i = 0; i < num_bits; ++i )
     {
     const unsigned bit = Rd_decode_bit( rdec, &bm[model] );
-    model = ( model << 1 ) + bit;
+    model <<= 1; model += bit;
     symbol |= ( bit << i );
     }
   return symbol;
@@ -248,12 +245,9 @@
 Rd_decode_tree_reversed4( struct Range_decoder * const rdec, Bit_model bm[] )
   {
   unsigned symbol = Rd_decode_bit( rdec, &bm[1] );
-  unsigned model = 2 + symbol;
-  unsigned bit = Rd_decode_bit( rdec, &bm[model] );
-  model = ( model << 1 ) + bit; symbol |= ( bit << 1 );
-  bit = Rd_decode_bit( rdec, &bm[model] );
-  model = ( model << 1 ) + bit; symbol |= ( bit << 2 );
-  symbol |= ( Rd_decode_bit( rdec, &bm[model] ) << 3 );
+  symbol += Rd_decode_bit( rdec, &bm[2+symbol] ) << 1;
+  symbol += Rd_decode_bit( rdec, &bm[4+symbol] ) << 2;
+  symbol += Rd_decode_bit( rdec, &bm[8+symbol] ) << 3;
   return symbol;
   }
 
@@ -266,7 +260,7 @@
     {
     const unsigned match_bit = ( match_byte <<= 1 ) & mask;
     const unsigned bit = Rd_decode_bit( rdec, &bm[symbol+match_bit+mask] );
-    symbol = ( symbol << 1 ) + bit;
+    symbol <<= 1; symbol += bit;
     if( symbol > 0xFF ) return symbol & 0xFF;
     mask &= ~(match_bit ^ (bit << 8));	/* if( match_bit != bit ) mask = 0; */
     }
diff --git a/cbits/encoder.c b/cbits/encoder.c
--- a/cbits/encoder.c
+++ b/cbits/encoder.c
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs )
@@ -23,7 +23,7 @@
   int32_t * ptr1 = ptr0 + 1;
   int32_t * newptr;
   int len = 0, len0 = 0, len1 = 0;
-  int maxlen = 0;
+  int maxlen = 3;			/* only used if pairs != 0 */
   int num_pairs = 0;
   const int pos1 = e->eb.mb.pos + 1;
   const int min_pos = ( e->eb.mb.pos > e->eb.mb.dictionary_size ) ?
@@ -49,8 +49,8 @@
 
   if( pairs )
     {
-    int np2 = e->eb.mb.prev_positions[key2];
-    int np3 = e->eb.mb.prev_positions[key3];
+    const int np2 = e->eb.mb.prev_positions[key2];
+    const int np3 = e->eb.mb.prev_positions[key3];
     if( np2 > min_pos && e->eb.mb.buffer[np2-1] == data[0] )
       {
       pairs[0].dis = e->eb.mb.pos - np2;
@@ -60,19 +60,17 @@
     if( np2 != np3 && np3 > min_pos && e->eb.mb.buffer[np3-1] == data[0] )
       {
       maxlen = 3;
-      np2 = np3;
-      pairs[num_pairs].dis = e->eb.mb.pos - np2;
-      ++num_pairs;
+      pairs[num_pairs++].dis = e->eb.mb.pos - np3;
       }
     if( num_pairs > 0 )
       {
-      const int delta = pos1 - np2;
+      const int delta = pairs[num_pairs-1].dis + 1;
       while( maxlen < len_limit && data[maxlen-delta] == data[maxlen] )
         ++maxlen;
       pairs[num_pairs-1].len = maxlen;
+      if( maxlen < 3 ) maxlen = 3;
       if( maxlen >= len_limit ) pairs = 0;	/* done. now just skip */
       }
-    if( maxlen < 3 ) maxlen = 3;
     }
 
   e->eb.mb.prev_positions[key2] = pos1;
diff --git a/cbits/encoder.h b/cbits/encoder.h
--- a/cbits/encoder.h
+++ b/cbits/encoder.h
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 struct Len_prices
diff --git a/cbits/encoder_base.c b/cbits/encoder_base.c
--- a/cbits/encoder_base.c
+++ b/cbits/encoder_base.c
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 static bool Mb_normalize_pos( struct Matchfinder_base * const mb )
@@ -58,7 +58,7 @@
   mb->stream_pos = 0;
   mb->num_prev_positions23 = num_prev_positions23;
   mb->at_stream_end = false;
-  mb->flushing = false;
+  mb->sync_flush_pending = false;
 
   mb->buffer_size = max( 65536, buffer_size_limit );
   mb->buffer = (uint8_t *)malloc( mb->buffer_size );
@@ -69,7 +69,7 @@
   size = 1 << max( 16, real_bits( mb->dictionary_size - 1 ) - 2 );
   if( mb->dictionary_size > 1 << 26 )		/* 64 MiB */
     size >>= 1;
-  mb->key4_mask = size - 1;
+  mb->key4_mask = size - 1;		/* increases with dictionary size */
   size += num_prev_positions23;
   mb->num_prev_positions = size;
 
@@ -118,7 +118,7 @@
   mb->pos = 0;
   mb->cyclic_pos = 0;
   mb->at_stream_end = false;
-  mb->flushing = false;
+  mb->sync_flush_pending = false;
   mb->dictionary_size = mb->saved_dictionary_size;
   Mb_adjust_array( mb );
   mb->pos_limit = mb->buffer_size - mb->after_size;
@@ -126,7 +126,7 @@
   }
 
 
-     /* End Of Stream mark => (dis == 0xFFFFFFFFU, len == min_match_len) */
+/* End Of Stream marker => (dis == 0xFFFFFFFFU, len == min_match_len) */
 static void LZeb_try_full_flush( struct LZ_encoder_base * const eb )
   {
   int i;
@@ -149,33 +149,36 @@
   }
 
 
-     /* Sync Flush mark => (dis == 0xFFFFFFFFU, len == min_match_len + 1) */
-static bool LZeb_sync_flush( struct LZ_encoder_base * const eb )
+/* Sync Flush marker => (dis == 0xFFFFFFFFU, len == min_match_len + 1) */
+static void LZeb_try_sync_flush( struct LZ_encoder_base * const eb )
   {
-  int i;
   const int pos_state = Mb_data_position( &eb->mb ) & pos_state_mask;
   const State state = eb->state;
+  const unsigned min_size = eb->renc.ff_count + max_marker_size;
   if( eb->member_finished ||
-      Cb_free_bytes( &eb->renc.cb ) < (2 * max_marker_size) + eb->renc.ff_count )
-    return false;
-  for( i = 0; i < 2; ++i )	/* 2 consecutive markers guarantee decoding */
-    {
+      Cb_free_bytes( &eb->renc.cb ) < min_size + max_marker_size ) return;
+  eb->mb.sync_flush_pending = false;
+  const unsigned long long old_mpos = Re_member_position( &eb->renc );
+  do {		/* size of markers must be >= rd_min_available_bytes + 5 */
     Re_encode_bit( &eb->renc, &eb->bm_match[state][pos_state], 1 );
     Re_encode_bit( &eb->renc, &eb->bm_rep[state], 0 );
     LZeb_encode_pair( eb, 0xFFFFFFFFU, min_match_len + 1, pos_state );
     Re_flush( &eb->renc );
     }
-  return true;
+  while( Re_member_position( &eb->renc ) - old_mpos < min_size );
   }
 
 
 static void LZeb_reset( struct LZ_encoder_base * const eb,
                         const unsigned long long member_size )
   {
+  const unsigned long long min_member_size = min_dictionary_size;
+  const unsigned long long max_member_size = 0x0008000000000000ULL; /* 2 PiB */
   int i;
   Mb_reset( &eb->mb );
   eb->member_size_limit =
-    min( member_size, 0x0008000000000000ULL ) - Lt_size - max_marker_size;
+    min( max( min_member_size, member_size ), max_member_size ) -
+    Lt_size - max_marker_size;
   eb->crc = 0xFFFFFFFFU;
   Bm_array_init( eb->bm_literal[0], (1 << literal_context_bits) * 0x300 );
   Bm_array_init( eb->bm_match[0], states * pos_states );
diff --git a/cbits/encoder_base.h b/cbits/encoder_base.h
--- a/cbits/encoder_base.h
+++ b/cbits/encoder_base.h
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 enum { price_shift_bits = 6,
@@ -197,7 +197,7 @@
     const bool bit = symbol & 1;
     symbol >>= 1;
     price += price_bit( bm[model], bit );
-    model = ( model << 1 ) | bit;
+    model <<= 1; model |= bit;
     }
   return price;
   }
@@ -240,7 +240,7 @@
   int pos_array_size;
   int saved_dictionary_size;	/* dictionary_size restored by Mb_reset */
   bool at_stream_end;		/* stream_pos shows real end of file */
-  bool flushing;
+  bool sync_flush_pending;
   };
 
 static bool Mb_normalize_pos( struct Matchfinder_base * const mb );
@@ -265,19 +265,20 @@
   { return mb->partial_data_pos + mb->pos; }
 
 static inline void Mb_finish( struct Matchfinder_base * const mb )
-  { mb->at_stream_end = true; mb->flushing = false; }
+  { mb->at_stream_end = true; mb->sync_flush_pending = false; }
 
 static inline bool Mb_data_finished( const struct Matchfinder_base * const mb )
-  { return mb->at_stream_end && !mb->flushing && mb->pos >= mb->stream_pos; }
+  { return mb->at_stream_end && mb->pos >= mb->stream_pos; }
 
 static inline bool Mb_flushing_or_end( const struct Matchfinder_base * const mb )
-  { return mb->at_stream_end || mb->flushing; }
+  { return mb->at_stream_end || mb->sync_flush_pending; }
 
 static inline int Mb_free_bytes( const struct Matchfinder_base * const mb )
   { if( Mb_flushing_or_end( mb ) ) return 0;
     return mb->buffer_size - mb->stream_pos; }
 
-static inline bool Mb_enough_available_bytes( const struct Matchfinder_base * const mb )
+static inline bool
+Mb_enough_available_bytes( const struct Matchfinder_base * const mb )
   { return ( mb->pos + mb->after_size <= mb->stream_pos ||
              ( Mb_flushing_or_end( mb ) && mb->pos < mb->stream_pos ) ); }
 
@@ -426,28 +427,30 @@
 static inline void Re_encode_tree3( struct Range_encoder * const renc,
                                     Bit_model bm[], const int symbol )
   {
-  int model = 1;
+  int model;
   bool bit = ( symbol >> 2 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[1], bit );
+  model = 2 | bit;
   bit = ( symbol >> 1 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
   Re_encode_bit( renc, &bm[model], symbol & 1 );
   }
 
 static inline void Re_encode_tree6( struct Range_encoder * const renc,
                                     Bit_model bm[], const unsigned symbol )
   {
-  int model = 1;
+  int model;
   bool bit = ( symbol >> 5 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[1], bit );
+  model = 2 | bit;
   bit = ( symbol >> 4 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
   bit = ( symbol >> 3 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
   bit = ( symbol >> 2 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
   bit = ( symbol >> 1 ) & 1;
-  Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
+  Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
   Re_encode_bit( renc, &bm[model], symbol & 1 );
   }
 
@@ -460,7 +463,7 @@
     {
     const bool bit = ( symbol >> i ) & 1;
     Re_encode_bit( renc, &bm[model], bit );
-    model = ( model << 1 ) | bit;
+    model <<= 1; model |= bit;
     }
   }
 
@@ -474,7 +477,7 @@
     const bool bit = symbol & 1;
     symbol >>= 1;
     Re_encode_bit( renc, &bm[model], bit );
-    model = ( model << 1 ) | bit;
+    model <<= 1; model |= bit;
     }
   }
 
@@ -561,7 +564,7 @@
   }
 
 static inline bool LZeb_member_finished( const struct LZ_encoder_base * const eb )
-  { return ( eb->member_finished && !Cb_used_bytes( &eb->renc.cb ) ); }
+  { return ( eb->member_finished && Cb_empty( &eb->renc.cb ) ); }
 
 static inline void LZeb_free( struct LZ_encoder_base * const eb )
   { Re_free( &eb->renc ); Mb_free( &eb->mb ); }
diff --git a/cbits/fast_encoder.c b/cbits/fast_encoder.c
--- a/cbits/fast_encoder.c
+++ b/cbits/fast_encoder.c
@@ -1,23 +1,23 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
-int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance )
+static int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance )
   {
   enum { len_limit = 16 };
   const uint8_t * const data = Mb_ptr_to_current_pos( &fe->eb.mb );
@@ -59,7 +59,7 @@
   }
 
 
-bool FLZe_encode_member( struct FLZ_encoder * const fe )
+static bool FLZe_encode_member( struct FLZ_encoder * const fe )
   {
   int rep = 0, i;
   State * const state = &fe->eb.state;
@@ -86,7 +86,7 @@
   while( !Mb_data_finished( &fe->eb.mb ) &&
          Re_member_position( &fe->eb.renc ) < fe->eb.member_size_limit )
     {
-    int match_distance;
+    int match_distance = 0;		/* avoid warning from gcc 6.1.0 */
     int main_len, pos_state;
     int len = 0;
     if( !Mb_enough_available_bytes( &fe->eb.mb ) ||
diff --git a/cbits/fast_encoder.h b/cbits/fast_encoder.h
--- a/cbits/fast_encoder.h
+++ b/cbits/fast_encoder.h
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 struct FLZ_encoder
@@ -31,21 +31,19 @@
     fe->key4 = ( fe->key4 << 4 ) ^ fe->eb.mb.buffer[i];
   }
 
-int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance );
-
 static inline bool FLZe_update_and_move( struct FLZ_encoder * const fe, int n )
   {
+  struct Matchfinder_base * const mb = &fe->eb.mb;
   while( --n >= 0 )
     {
-    if( Mb_available_bytes( &fe->eb.mb ) >= 4 )
+    if( Mb_available_bytes( mb ) >= 4 )
       {
-      fe->key4 = ( ( fe->key4 << 4 ) ^ fe->eb.mb.buffer[fe->eb.mb.pos+3] ) &
-                 fe->eb.mb.key4_mask;
-      fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = fe->eb.mb.prev_positions[fe->key4];
-      fe->eb.mb.prev_positions[fe->key4] = fe->eb.mb.pos + 1;
+      fe->key4 = ( ( fe->key4 << 4 ) ^ mb->buffer[mb->pos+3] ) & mb->key4_mask;
+      mb->pos_array[mb->cyclic_pos] = mb->prev_positions[fe->key4];
+      mb->prev_positions[fe->key4] = mb->pos + 1;
       }
-    else fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = 0;
-    if( !Mb_move_pos( &fe->eb.mb ) ) return false;
+    else mb->pos_array[mb->cyclic_pos] = 0;
+    if( !Mb_move_pos( mb ) ) return false;
     }
   return true;
   }
diff --git a/cbits/lzip.h b/cbits/lzip.h
--- a/cbits/lzip.h
+++ b/cbits/lzip.h
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 #ifndef max
@@ -83,7 +83,7 @@
   { return min( len - min_match_len, len_states - 1 ); }
 
 static inline int get_lit_state( const uint8_t prev_byte )
-  { return ( prev_byte >> ( 8 - literal_context_bits ) ); }
+  { return prev_byte >> ( 8 - literal_context_bits ); }
 
 
 enum { bit_model_move_bits = 5,
@@ -197,7 +197,7 @@
 
 typedef uint8_t Lzip_header[6];		/* 0-3 magic bytes */
 					/*   4 version */
-					/*   5 coded_dict_size */
+					/*   5 coded dictionary size */
 enum { Lh_size = 6 };
 
 static inline void Lh_set_magic( Lzip_header data )
@@ -255,9 +255,8 @@
 
 static inline bool Lh_verify( const Lzip_header data )
   {
-  if( Lh_verify_magic( data ) && Lh_verify_version( data ) )
-    return isvalid_ds( Lh_get_dictionary_size( data ) );
-  return false;
+  return Lh_verify_magic( data ) && Lh_verify_version( data ) &&
+         isvalid_ds( Lh_get_dictionary_size( data ) );
   }
 
 
diff --git a/cbits/lzlib.c b/cbits/lzlib.c
--- a/cbits/lzlib.c
+++ b/cbits/lzlib.c
@@ -1,20 +1,20 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 #include <stdbool.h>
@@ -105,10 +105,11 @@
   }
 
 
-/*------------------------- Misc Functions -------------------------*/
+/* ------------------------- Misc Functions ------------------------- */
 
-const char * LZ_version( void ) { return LZ_version_string; }
+int LZ_api_version( void ) { return LZ_API_VERSION; }
 
+const char * LZ_version( void ) { return LZ_version_string; }
 
 const char * LZ_strerror( const enum LZ_Errno lz_errno )
   {
@@ -135,7 +136,7 @@
 int LZ_max_match_len_limit( void ) { return max_match_len; }
 
 
-/*---------------------- Compression Functions ----------------------*/
+/* --------------------- Compression Functions --------------------- */
 
 struct LZ_Encoder * LZ_compress_open( const int dictionary_size,
                                       const int match_len_limit,
@@ -226,8 +227,8 @@
 int LZ_compress_sync_flush( struct LZ_Encoder * const e )
   {
   if( !verify_encoder( e ) || e->fatal ) return -1;
-  if( !Mb_flushing_or_end( &e->lz_encoder_base->mb ) )
-    e->lz_encoder_base->mb.flushing = true;
+  if( !e->lz_encoder_base->mb.at_stream_end )
+    e->lz_encoder_base->mb.sync_flush_pending = true;
   return 0;
   }
 
@@ -235,24 +236,22 @@
 int LZ_compress_read( struct LZ_Encoder * const e,
                       uint8_t * const buffer, const int size )
   {
-  int out_size = 0;
   if( !verify_encoder( e ) || e->fatal ) return -1;
   if( size < 0 ) return 0;
-  do {
+
+  { struct LZ_encoder_base * const eb = e->lz_encoder_base;
+  int out_size = Re_read_data( &eb->renc, buffer, size );
+  /* minimize number of calls to encode_member */
+  if( out_size < size || size == 0 )
+    {
     if( ( e->flz_encoder && !FLZe_encode_member( e->flz_encoder ) ) ||
         ( e->lz_encoder && !LZe_encode_member( e->lz_encoder ) ) )
       { e->lz_errno = LZ_library_error; e->fatal = true; return -1; }
-    if( e->lz_encoder_base->mb.flushing &&
-        Mb_available_bytes( &e->lz_encoder_base->mb ) <= 0 &&
-        LZeb_sync_flush( e->lz_encoder_base ) )
-      e->lz_encoder_base->mb.flushing = false;
-    out_size += Re_read_data( &e->lz_encoder_base->renc,
-                              buffer + out_size, size - out_size );
+    if( eb->mb.sync_flush_pending && Mb_available_bytes( &eb->mb ) <= 0 )
+      LZeb_try_sync_flush( eb );
+    out_size += Re_read_data( &eb->renc, buffer + out_size, size - out_size );
     }
-  while( e->lz_encoder_base->mb.flushing && out_size < size &&
-         Mb_enough_available_bytes( &e->lz_encoder_base->mb ) &&
-         Re_enough_free_bytes( &e->lz_encoder_base->renc ) );
-  return out_size;
+  return out_size; }
   }
 
 
@@ -321,7 +320,7 @@
   }
 
 
-/*--------------------- Decompression Functions ---------------------*/
+/* -------------------- Decompression Functions -------------------- */
 
 struct LZ_Decoder * LZ_decompress_open( void )
   {
@@ -401,10 +400,11 @@
   {
   int result;
   if( !verify_decoder( d ) ) return -1;
+  if( size < 0 ) return 0;
   if( d->fatal )	/* don't return error until pending bytes are read */
     { if( d->lz_decoder && !Cb_empty( &d->lz_decoder->cb ) ) goto get_data;
       return -1; }
-  if( d->seeking || size < 0 ) return 0;
+  if( d->seeking ) return 0;
 
   if( d->lz_decoder && LZd_member_finished( d->lz_decoder ) )
     {
diff --git a/cbits/lzlib.h b/cbits/lzlib.h
--- a/cbits/lzlib.h
+++ b/cbits/lzlib.h
@@ -1,35 +1,39 @@
-/*  Lzlib - Compression library for the lzip format
-    Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+   Copyright (C) 2009-2021 Antonio Diaz Diaz.
 
-    This library is free software. Redistribution and use in source and
-    binary forms, with or without modification, are permitted provided
-    that the following conditions are met:
+   This library is free software. Redistribution and use in source and
+   binary forms, with or without modification, are permitted provided
+   that the following conditions are met:
 
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
+   1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions, and the following disclaimer.
 
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions, and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define LZ_API_VERSION 1
+/* LZ_API_VERSION was first defined in lzlib 1.8 to 1.
+   Since lzlib 1.12, LZ_API_VERSION is defined as (major * 1000 + minor). */
 
-static const char * const LZ_version_string = "1.11";
+#define LZ_API_VERSION 1012
 
+static const char * const LZ_version_string = "1.12";
+
 enum LZ_Errno { LZ_ok = 0,         LZ_bad_argument, LZ_mem_error,
                 LZ_sequence_error, LZ_header_error, LZ_unexpected_eof,
                 LZ_data_error,     LZ_library_error };
 
 
+int LZ_api_version( void );				/* new in 1.12 */
 const char * LZ_version( void );
 const char * LZ_strerror( const enum LZ_Errno lz_errno );
 
@@ -41,7 +45,7 @@
 int LZ_max_match_len_limit( void );
 
 
-/*---------------------- Compression Functions ----------------------*/
+/* --------------------- Compression Functions --------------------- */
 
 struct LZ_Encoder;
 
@@ -71,7 +75,7 @@
 unsigned long long LZ_compress_total_out_size( struct LZ_Encoder * const encoder );
 
 
-/*--------------------- Decompression Functions ---------------------*/
+/* -------------------- Decompression Functions -------------------- */
 
 struct LZ_Decoder;
 
diff --git a/lzlib.cabal b/lzlib.cabal
--- a/lzlib.cabal
+++ b/lzlib.cabal
@@ -1,9 +1,9 @@
 cabal-version:      1.18
 name:               lzlib
-version:            1.0.7.0
+version:            1.0.7.1
 license:            BSD3
 license-file:       LICENSE
-copyright:          Copyright: (c) 2019-2020 Vanessa McHale
+copyright:          Copyright: (c) 2019-2021 Vanessa McHale
 maintainer:         vamchale@gmail.com
 author:             Vanessa McHale
 synopsis:           lzlib bindings
@@ -74,7 +74,7 @@
     main-is:          Spec.hs
     hs-source-dirs:   test
     default-language: Haskell2010
-    ghc-options:      -threaded -rtsopts -with-rtsopts=-N -Wall
+    ghc-options:      -threaded -rtsopts "-with-rtsopts=-N -K1K" -Wall
     build-depends:
         base -any,
         lzlib -any,
@@ -99,10 +99,7 @@
     main-is:          Bench.hs
     hs-source-dirs:   bench
     default-language: Haskell2010
-    ghc-options:
-        -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates
-        -Wredundant-constraints
-
+    ghc-options:      -Wall
     build-depends:
         base -any,
         lzlib -any,
@@ -110,6 +107,11 @@
         bytestring -any,
         temporary -any,
         filepath -any
+
+    if impl(ghc >=8.0)
+        ghc-options:
+            -Wincomplete-uni-patterns -Wincomplete-record-updates
+            -Wredundant-constraints
 
     if impl(ghc >=8.4)
         ghc-options: -Wmissing-export-lists
diff --git a/src/Codec/Lzip.hs b/src/Codec/Lzip.hs
--- a/src/Codec/Lzip.hs
+++ b/src/Codec/Lzip.hs
@@ -265,6 +265,8 @@
 
             withForeignPtr buf $ \b -> do
                 bytesActual <- lZCompressRead encoder b (fromIntegral sz)
+                when (maxSz == 0 && bytesActual == 0) $
+                    error "Internal error in lzlib-hs: no progress made; maybe delta is too high?"
                 res <- lZCompressFinished encoder
                 bsActual <- BS.packCStringLen (castPtr b, fromIntegral bytesActual)
                 if res == 1
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -14,10 +14,10 @@
 import           Test.Hspec
 
 forceHead :: BSL.ByteString -> IO ()
-forceHead bsl = BS.length (head $ BSL.toChunks bsl) `seq` (pure ())
+forceHead bsl = BS.length (head $ BSL.toChunks bsl) `seq` pure ()
 
 forceBSL :: BSL.ByteString -> IO ()
-forceBSL bsl = BS.length (last $ BSL.toChunks bsl) `seq` (pure ())
+forceBSL bsl = BS.length (last $ BSL.toChunks bsl) `seq` pure ()
 
 decompressMultithreaded :: FilePath -> IO ()
 decompressMultithreaded fp = do
@@ -55,7 +55,7 @@
 main :: IO ()
 main = do
     ex' <- filterM doesFileExist ["gmp-6.1.2.tar.lz", "lzlib-1.10.tar.lz"]
-    ex <- filterM doesFileExist ["gmp-6.1.2.tar", "lzlib-1.10.tar"]
+    ex <- filterM doesFileExist ["cbits/encoder.c", "gmp-6.1.2.tar", "lzlib-1.10.tar"]
     hspec $ do
         describe "roundtrip" $
             traverse_ compressFile ex
