diff options
author | Leo Izen <leo.izen@gmail.com> | 2025-02-03 22:22:24 -0500 |
---|---|---|
committer | Leo Izen <leo.izen@gmail.com> | 2025-02-09 19:06:42 -0500 |
commit | 3fca5877d0341578eb4cb23ba74b71c8637f81a0 (patch) | |
tree | d0037d0a4066dcab34aab016d3d30930f9a9ffb1 | |
parent | 43be8d07281caca2e88bfd8ee2333633e1fb1a13 (diff) | |
download | ffmpeg-3fca5877d0341578eb4cb23ba74b71c8637f81a0.tar.gz |
avcodec/pngdec: avoid hard failure on illegal sBIT chunks
If a malformed chunk like sBIT appears but otherwise the stream
is still parseable, we should print a warning and skip it rather
than failing with an error.
Signed-off-by: Leo Izen <leo.izen@gmail.com>
-rw-r--r-- | libavcodec/pngdec.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index f8cb61775e..b9c997ab0e 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -1073,6 +1073,7 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, { int bits = 0; int channels; + int remainder = bytestream2_get_bytes_left(gb); if (!(s->hdr_state & PNG_IHDR)) { av_log(avctx, AV_LOG_ERROR, "sBIT before IHDR\n"); @@ -1080,16 +1081,17 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, } if (s->pic_state & PNG_IDAT) { - av_log(avctx, AV_LOG_ERROR, "sBIT after IDAT\n"); - return AVERROR_INVALIDDATA; + av_log(avctx, AV_LOG_WARNING, "Ignoring illegal sBIT chunk after IDAT\n"); + return 0; } channels = s->color_type & PNG_COLOR_MASK_PALETTE ? 3 : ff_png_get_nb_channels(s->color_type); - if (bytestream2_get_bytes_left(gb) != channels) { - av_log(avctx, AV_LOG_ERROR, "Invalid sBIT size: %d, expected: %d\n", - bytestream2_get_bytes_left(gb), channels); - return AVERROR_INVALIDDATA; + if (remainder != channels) { + av_log(avctx, AV_LOG_WARNING, "Invalid sBIT size: %d, expected: %d\n", remainder, channels); + /* not enough space left in chunk to read info */ + if (remainder < channels) + return 0; } for (int i = 0; i < channels; i++) { @@ -1098,8 +1100,8 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, } if (bits <= 0 || bits > (s->color_type & PNG_COLOR_MASK_PALETTE ? 8 : s->bit_depth)) { - av_log(avctx, AV_LOG_ERROR, "Invalid significant bits: %d\n", bits); - return AVERROR_INVALIDDATA; + av_log(avctx, AV_LOG_WARNING, "Invalid significant bits: %d\n", bits); + return 0; } s->significant_bits = bits; |