diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index fd0bf339a7..d664325a29 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1330,6 +1330,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size - 2)) { av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; err = AAC_AC3_PARSE_ERROR_CRC; } } diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index d4f103bd60..782a1b8b80 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1545,6 +1545,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, if (ctx->cur_frame_length != sconf->frame_length && ctx->crc_org != ctx->crc) { av_log(avctx, AV_LOG_ERROR, "CRC error.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 84bfccb5ac..ad45d97ddc 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2332,6 +2332,13 @@ typedef struct AVCodecContext { * - decoding: Set by user. */ int err_recognition; + +/** + * Verify checksums embedded in the bitstream (could be of either encoded or + * decoded data, depending on the codec) and print an error message on mismatch. + * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the + * decoder returning an error. + */ #define AV_EF_CRCCHECK (1<<0) #define AV_EF_BITSTREAM (1<<1) #define AV_EF_BUFFER (1<<2) diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 8b3966112c..0d2dcbbdb2 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -693,7 +693,8 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if (avctx->err_recognition & AV_EF_CRCCHECK) { if (ff_tak_check_crc(pkt->data, hsize)) { av_log(avctx, AV_LOG_ERROR, "CRC error\n"); - return AVERROR_INVALIDDATA; + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } @@ -867,7 +868,8 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if (ff_tak_check_crc(pkt->data + hsize, get_bits_count(gb) / 8 - hsize)) { av_log(avctx, AV_LOG_ERROR, "CRC error\n"); - return AVERROR_INVALIDDATA; + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 53c8acaa6e..4d2e2a00be 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -275,7 +275,8 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) avctx->extradata_size - 26 < total_frames * 4) av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n"); else if (avctx->err_recognition & AV_EF_CRCCHECK) { - if (tta_check_crc(s, avctx->extradata + 22, total_frames * 4)) + int ret = tta_check_crc(s, avctx->extradata + 22, total_frames * 4); + if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) return AVERROR_INVALIDDATA; } skip_bits_long(&s->gb, 32 * total_frames); @@ -316,7 +317,8 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, int32_t *p; if (avctx->err_recognition & AV_EF_CRCCHECK) { - if (buf_size < 4 || tta_check_crc(s, buf, buf_size - 4)) + if (buf_size < 4 || + (tta_check_crc(s, buf, buf_size - 4) && avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index bdc2a81d44..cbc5b04d1a 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -699,9 +699,11 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, } while (!last && count < s->samples); wv_reset_saved_context(s); - if ((s->avctx->err_recognition & AV_EF_CRCCHECK) && - wv_check_crc(s, crc, crc_extra_bits)) - return AVERROR_INVALIDDATA; + if (s->avctx->err_recognition & AV_EF_CRCCHECK) { + int ret = wv_check_crc(s, crc, crc_extra_bits); + if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } return 0; }