FULL_FLUSH and SYNC_FLUSH flush modes are ignored

Bug #939658 reported by Steve Halstead
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
PylibLZMA
New
Undecided
Unassigned

Bug Description

Version = 0.5.3

The LZMA_FULL_FLUSH and LZMA_SYNC_FLUSH modes for LZMACompressor.flush() do nothing. Calling flush in either of these modes returns an empty string and leaves the compressed data in the object. The only mode that flushes anything is the LZMA_FINISH mode but this prevents any further compression with this object.

The following Python code demonstrates the issue.

>>> compressor = LZMACompressor()
>>> header = compressor.compress("Pre-flush text\n")
>>> preflush = header + compressor.flush(lzma.LZMA_FULL_FLUSH)
>>> compressor.compress("Post-flush text\n")
''
>>> postflush = header + compressor.flush(lzma.LZMA_FINISH)
>>> print lzma.decompress(preflush)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: unknown BUF error
>>> print lzma.decompress(postflush)
Pre-flush text
Post-flush text

If the flush works as expected, preflush should decompress to "Pre-flush text" and postflush should decompress to "Post-flush text".

Looking at the source code file liblzma_compressobj.c, it is apparent that on a FULL_FLUSH or SYNC_FLUSH there is no 'break' statement after the two case statements so the code falls through to the 'LZMA_RUN' case which ends in "goto error". This code is shown below.

    switch(flushmode){
  case(LZMA_SYNC_FLUSH):
  case(LZMA_FULL_FLUSH):
   if(self->filters[0].id == LZMA_FILTER_LZMA1) {
    PyErr_Format(LZMAError, "%d is not supported as flush mode for LZMA_Alone format", flushmode);
    goto error;
   }
  /* Flushing with LZMA_RUN is a no-op, so there's no point in
   * doing any work at all; just return an empty string.
   */
  case(LZMA_RUN):
   ret = PyString_FromStringAndSize(NULL, 0);
   goto error;
  case(LZMA_FINISH):
   break;
  default:
   PyErr_Format(LZMAError, "Invalid flush mode: %d", flushmode);
   goto error;
 }

Simply adding a 'break' after the FULL_FLUSH case will not by itself fix the problem because the first line after the switch statement sets the compressor as no longer running.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.