forked from minhngoc25a/freetype2
[bzip2] Reset bzip stream on any error.
According to the bzip documentation it is undefined what will happen if `BZ2_bzDecompress` is called on a `bz_stream` it has previously returned an error against. If `BZ2_bzDecompress` returns anything other than `BZ_OK` the only valid next action is `BZ2_bzDecompressEnd`. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43564 * src/bzip2/ftbzip2.c (FT_BZip2FileRec_): Add `reset` to track the need to reset the stream. (ft_bzip2_file_init): Initialize `reset` to 0. (ft_bzip2_file_reset): Set `reset` to 0 after resetting. (ft_bzip2_file_fill_output): Set `reset` to 1 when `BZ2_bzDecompress` returns anything other than `BZ_OK`.
This commit is contained in:
parent
b647dbdeb8
commit
6ee8951956
|
@ -102,10 +102,11 @@
|
|||
|
||||
FT_Byte input[FT_BZIP2_BUFFER_SIZE]; /* input read buffer */
|
||||
|
||||
FT_Byte buffer[FT_BZIP2_BUFFER_SIZE]; /* output buffer */
|
||||
FT_ULong pos; /* position in output */
|
||||
FT_Byte buffer[FT_BZIP2_BUFFER_SIZE]; /* output buffer */
|
||||
FT_ULong pos; /* position in output */
|
||||
FT_Byte* cursor;
|
||||
FT_Byte* limit;
|
||||
FT_Bool reset; /* reset before next read */
|
||||
|
||||
} FT_BZip2FileRec, *FT_BZip2File;
|
||||
|
||||
|
@ -153,6 +154,7 @@
|
|||
zip->limit = zip->buffer + FT_BZIP2_BUFFER_SIZE;
|
||||
zip->cursor = zip->limit;
|
||||
zip->pos = 0;
|
||||
zip->reset = 0;
|
||||
|
||||
/* check .bz2 header */
|
||||
{
|
||||
|
@ -228,6 +230,7 @@
|
|||
zip->limit = zip->buffer + FT_BZIP2_BUFFER_SIZE;
|
||||
zip->cursor = zip->limit;
|
||||
zip->pos = 0;
|
||||
zip->reset = 0;
|
||||
|
||||
BZ2_bzDecompressInit( bzstream, 0, 0 );
|
||||
}
|
||||
|
@ -302,18 +305,23 @@
|
|||
|
||||
err = BZ2_bzDecompress( bzstream );
|
||||
|
||||
if ( err == BZ_STREAM_END )
|
||||
if ( err != BZ_OK )
|
||||
{
|
||||
zip->limit = (FT_Byte*)bzstream->next_out;
|
||||
if ( zip->limit == zip->cursor )
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
break;
|
||||
}
|
||||
else if ( err != BZ_OK )
|
||||
{
|
||||
zip->limit = zip->cursor;
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
break;
|
||||
zip->reset = 1;
|
||||
|
||||
if ( err == BZ_STREAM_END )
|
||||
{
|
||||
zip->limit = (FT_Byte*)bzstream->next_out;
|
||||
if ( zip->limit == zip->cursor )
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
zip->limit = zip->cursor;
|
||||
error = FT_THROW( Invalid_Stream_Operation );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,9 +371,9 @@
|
|||
FT_Error error;
|
||||
|
||||
|
||||
/* Reset inflate stream if we're seeking backwards. */
|
||||
/* Yes, that is not too efficient, but it saves memory :-) */
|
||||
if ( pos < zip->pos )
|
||||
/* Reset inflate stream if seeking backwards or bzip reported an error. */
|
||||
/* Yes, that is not too efficient, but it saves memory :-) */
|
||||
if ( pos < zip->pos || zip->reset )
|
||||
{
|
||||
error = ft_bzip2_file_reset( zip );
|
||||
if ( error )
|
||||
|
|
Loading…
Reference in New Issue