summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Wagner <bungeman@chromium.org>2022-01-12 15:12:53 -0500
committerWerner Lemberg <wl@gnu.org>2022-01-13 08:21:36 +0100
commit6ee89519561aa33c63abcb24ae63920742f81316 (patch)
treee6f3fb6cbde4f14bfa8a4e3ed384cef88a329aa6
parentb647dbdeb8d5389a7e05ca5284842b4b757ee723 (diff)
downloadfreetype2-6ee89519561aa33c63abcb24ae63920742f81316.tar.gz
[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`.
-rw-r--r--src/bzip2/ftbzip2.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/bzip2/ftbzip2.c b/src/bzip2/ftbzip2.c
index 1d08f5e18..6f34a8bb7 100644
--- a/src/bzip2/ftbzip2.c
+++ b/src/bzip2/ftbzip2.c
@@ -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 )