def _safe_inflate data
      zi = Zlib::Inflate.new
      pos = 0; r = ''
      begin
        # save some memory by not using String#[] when not necessary
        r << zi.inflate(pos==0 ? data : data[pos..-1])
        if zi.total_in < data.size
          @extradata << data[zi.total_in..-1]
          puts "[?] #{@extradata.last.size} bytes of extra data after zlib stream".red if @verbose >= 1
        end
        # decompress OK
      rescue Zlib::BufError
        # tried to decompress, but got EOF - need more data
        puts "[!] #{$!.inspect}".red if @verbose >= -1
        # collect any remaining data in decompress buffer
        r << zi.flush_next_out
      rescue Zlib::DataError
        puts "[!] #{$!.inspect}".red if @verbose >= -1
        #p [pos, zi.total_in, zi.total_out, data.size, r.size]
        r << zi.flush_next_out
        # XXX TODO try to skip error and continue
#        printf "[d] pos=%d/%d t_in=%d t_out=%d bytes_ok=%d\n".gray, pos, data.size,
#          zi.total_in, zi.total_out, r.size
#        if pos < zi.total_in
#          pos = zi.total_in
#        else
#          pos += 1
#        end
#        pos = 0
#        retry if pos < data.size
      rescue Zlib::NeedDict
        puts "[!] #{$!.inspect}".red if @verbose >= -1
        # collect any remaining data in decompress buffer
        r << zi.flush_next_out
      end

      r == "" ? nil : r
    ensure
      zi.close if zi && !zi.closed?
    end
def _safe_inflate data
      zi = Zlib::Inflate.new
      pos = 0; r = ''
      begin
        # save some memory by not using String#[] when not necessary
        r << zi.inflate(pos==0 ? data : data[pos..-1])
        if zi.total_in < data.size
          @extradata << data[zi.total_in..-1]
          puts "[?] #{@extradata.last.size} bytes of extra data after zlib stream".red if @verbose >= 1
        end
        # decompress OK
      rescue Zlib::BufError
        # tried to decompress, but got EOF - need more data
        puts "[!] #{$!.inspect}".red if @verbose >= -1
        # collect any remaining data in decompress buffer
        r << zi.flush_next_out
      rescue Zlib::DataError
        puts "[!] #{$!.inspect}".red if @verbose >= -1
        #p [pos, zi.total_in, zi.total_out, data.size, r.size]
        r << zi.flush_next_out
        # XXX TODO try to skip error and continue
#        printf "[d] pos=%d/%d t_in=%d t_out=%d bytes_ok=%d\n".gray, pos, data.size,
#          zi.total_in, zi.total_out, r.size
#        if pos < zi.total_in
#          pos = zi.total_in
#        else
#          pos += 1
#        end
#        pos = 0
#        retry if pos < data.size
      rescue Zlib::NeedDict
        puts "[!] #{$!.inspect}".red if @verbose >= -1
        # collect any remaining data in decompress buffer
        r << zi.flush_next_out
      end

      r == "" ? nil : r
    ensure
      zi.close if zi && !zi.closed?
    end
unpack zlib,
 on errors keep going and try to return maximum possible data