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.
Unified · Split
| @@ -1073,6 +1073,7 @@ static int decode_sbit_chunk(AVCodecContext *avctx, PNGDecContext *s, · 1072 unmodified lines | ||
| 1073 | 1073 | { |
| 1074 | 1074 | int bits = 0; |
| 1075 | 1075 | int channels; |
| 1076 | + int remainder = bytestream2_get_bytes_left(gb); | |
| 1076 | 1077 | |
| 1077 | 1078 | if (!(s->hdr_state & PNG_IHDR)) { |
| 1078 | 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 | 1083 | 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; | |
| 1085 | 1086 | } |
| 1086 | 1087 | |
| 1087 | 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 | − 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; | |
| 1093 | 1095 | } |
| 1094 | 1096 | |
| 1095 | 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 | 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); | |
| 1102 | − return AVERROR_INVALIDDATA; | |
| 1103 | + av_log(avctx, AV_LOG_WARNING, "Invalid significant bits: %d\n", bits); | |
| 1104 | + return 0; | |
| 1103 | 1105 | } |
| 1104 | 1106 | s->significant_bits = bits; |
| 1105 | 1107 | |