Skip to content

Commit 3fca587

Browse files
committed
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 <[email protected]>
1 parent 43be8d0 commit 3fca587

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

libavcodec/pngdec.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,23 +1073,25 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s,
10731073
{
10741074
int bits = 0;
10751075
int channels;
1076+
int remainder = bytestream2_get_bytes_left(gb);
10761077

10771078
if (!(s->hdr_state & PNG_IHDR)) {
10781079
av_log(avctx, AV_LOG_ERROR, "sBIT before IHDR\n");
10791080
return AVERROR_INVALIDDATA;
10801081
}
10811082

10821083
if (s->pic_state & PNG_IDAT) {
1083-
av_log(avctx, AV_LOG_ERROR, "sBIT after IDAT\n");
1084-
return AVERROR_INVALIDDATA;
1084+
av_log(avctx, AV_LOG_WARNING, "Ignoring illegal sBIT chunk after IDAT\n");
1085+
return 0;
10851086
}
10861087

10871088
channels = s->color_type & PNG_COLOR_MASK_PALETTE ? 3 : ff_png_get_nb_channels(s->color_type);
10881089

1089-
if (bytestream2_get_bytes_left(gb) != channels) {
1090-
av_log(avctx, AV_LOG_ERROR, "Invalid sBIT size: %d, expected: %d\n",
1091-
bytestream2_get_bytes_left(gb), channels);
1092-
return AVERROR_INVALIDDATA;
1090+
if (remainder != channels) {
1091+
av_log(avctx, AV_LOG_WARNING, "Invalid sBIT size: %d, expected: %d\n", remainder, channels);
1092+
/* not enough space left in chunk to read info */
1093+
if (remainder < channels)
1094+
return 0;
10931095
}
10941096

10951097
for (int i = 0; i < channels; i++) {
@@ -1098,8 +1100,8 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s,
10981100
}
10991101

11001102
if (bits <= 0 || bits > (s->color_type & PNG_COLOR_MASK_PALETTE ? 8 : s->bit_depth)) {
1101-
av_log(avctx, AV_LOG_ERROR, "Invalid significant bits: %d\n", bits);
1102-
return AVERROR_INVALIDDATA;
1103+
av_log(avctx, AV_LOG_WARNING, "Invalid significant bits: %d\n", bits);
1104+
return 0;
11031105
}
11041106
s->significant_bits = bits;
11051107

0 commit comments

Comments
 (0)