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.
Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -1073,6 +1073,7 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, · 1072 unmodified lines | |||
| 1073 | { | 1073 | { |
| 1074 | int bits = 0; | 1074 | int bits = 0; |
| 1075 | int channels; | 1075 | int channels; |
| 1076 | int remainder = bytestream2_get_bytes_left(gb); | ||
| 1076 | 1077 | ||
| 1077 | if (!(s->hdr_state & PNG_IHDR)) { | 1078 | if (!(s->hdr_state & PNG_IHDR)) { |
| 1078 | av_log(avctx, AV_LOG_ERROR, "sBIT before IHDR\n"); | 1079 | av_log(avctx, AV_LOG_ERROR, "sBIT before IHDR\n"); |
| @@ -1080,16 +1081,17 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, · 1 unmodified line | |||
| 1080 | } | 1081 | } |
| 1081 | 1082 | ||
| 1082 | if (s->pic_state & PNG_IDAT) { | 1083 | if (s->pic_state & PNG_IDAT) { |
| 1083 | av_log(avctx, AV_LOG_ERROR, "sBIT after IDAT\n"); | 1084 | av_log(avctx, AV_LOG_WARNING, "Ignoring illegal sBIT chunk after IDAT\n"); |
| 1084 | return AVERROR_INVALIDDATA; | 1085 | return 0; |
| 1085 | } | 1086 | } |
| 1086 | 1087 | ||
| 1087 | channels = s->color_type & PNG_COLOR_MASK_PALETTE ? 3 : ff_png_get_nb_channels(s->color_type); | 1088 | channels = s->color_type & PNG_COLOR_MASK_PALETTE ? 3 : ff_png_get_nb_channels(s->color_type); |
| 1088 | 1089 | ||
| 1089 | if (bytestream2_get_bytes_left(gb) != channels) { | 1090 | if (remainder != channels) { |
| 1090 | av_log(avctx, AV_LOG_ERROR, "Invalid sBIT size: %d, expected: %d\n", | 1091 | av_log(avctx, AV_LOG_WARNING, "Invalid sBIT size: %d, expected: %d\n", remainder, channels); |
| 1091 | bytestream2_get_bytes_left(gb), channels); | 1092 | /* not enough space left in chunk to read info */ |
| 1092 | return AVERROR_INVALIDDATA; | 1093 | if (remainder < channels) |
| 1094 | return 0; | ||
| 1093 | } | 1095 | } |
| 1094 | 1096 | ||
| 1095 | for (int i = 0; i < channels; i++) { | 1097 | for (int i = 0; i < channels; i++) { |
| @@ -1098,8 +1100,8 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, · 2 unmodified lines | |||
| 1098 | } | 1100 | } |
| 1099 | 1101 | ||
| 1100 | if (bits <= 0 || bits > (s->color_type & PNG_COLOR_MASK_PALETTE ? 8 : s->bit_depth)) { | 1102 | 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); | 1103 | av_log(avctx, AV_LOG_WARNING, "Invalid significant bits: %d\n", bits); |
| 1102 | return AVERROR_INVALIDDATA; | 1104 | return 0; |
| 1103 | } | 1105 | } |
| 1104 | s->significant_bits = bits; | 1106 | s->significant_bits = bits; |
| 1105 | 1107 | ||