Browse Source

pngdec: add ability to check chunk CRC

By default now, if AV_EF_CRCCHECK or AV_EF_IGNORE_ERR are enabled the decoder
will skip the chunk and carry on with the next one. This should make the
decoder able to decode more corrupt files because the functions which decode
individual chunks will very likely error out if fed invalid data and stop the
decoding of the entire image.
tags/n4.3
Lynne 7 years ago
parent
commit
b8d9bc2e87
No known key found for this signature in database GPG Key ID: A2FEA5F03F034464
1 changed files with 17 additions and 0 deletions
  1. +17
    -0
      libavcodec/pngdec.c

+ 17
- 0
libavcodec/pngdec.c View File

@@ -23,6 +23,7 @@

#include "libavutil/avassert.h"
#include "libavutil/bprint.h"
#include "libavutil/crc.h"
#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/stereo3d.h"
@@ -1179,6 +1180,7 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
AVFrame *p, AVPacket *avpkt)
{
const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE);
AVDictionary **metadatap = NULL;
uint32_t tag, length;
int decode_next_dat = 0;
@@ -1213,6 +1215,21 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
ret = AVERROR_INVALIDDATA;
goto fail;
}
if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_IGNORE_ERR)) {
uint32_t crc_sig = AV_RB32(s->gb.buffer + length + 4);
uint32_t crc_cal = ~av_crc(crc_tab, UINT32_MAX, s->gb.buffer, length + 4);
if (crc_sig ^ crc_cal) {
av_log(avctx, AV_LOG_ERROR, "CRC mismatch in chunk");
if (avctx->err_recognition & AV_EF_EXPLODE) {
av_log(avctx, AV_LOG_ERROR, ", quitting\n");
ret = AVERROR_INVALIDDATA;
goto fail;
}
av_log(avctx, AV_LOG_ERROR, ", skipping\n");
bytestream2_skip(&s->gb, 4); /* tag */
goto skip_tag;
}
}
tag = bytestream2_get_le32(&s->gb);
if (avctx->debug & FF_DEBUG_STARTCODE)
av_log(avctx, AV_LOG_DEBUG, "png: tag=%s length=%u\n",


Loading…
Cancel
Save