aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Izen <leo.izen@gmail.com>2025-02-03 22:22:24 -0500
committerLeo Izen <leo.izen@gmail.com>2025-02-09 19:06:42 -0500
commit3fca5877d0341578eb4cb23ba74b71c8637f81a0 (patch)
treed0037d0a4066dcab34aab016d3d30930f9a9ffb1
parent43be8d07281caca2e88bfd8ee2333633e1fb1a13 (diff)
downloadffmpeg-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.c18
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;