This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit a84627aca9e1080c40b12ccef4e1ff1be67329c6 Author: Ramiro Polla <[email protected]> AuthorDate: Fri Sep 12 17:15:41 2025 +0200 Commit: Ramiro Polla <[email protected]> CommitDate: Mon Jan 5 13:14:15 2026 +0000 avcodec/mjpegdec: add mjpeg_parse_len() helper And check for length field in a consistent manner. --- libavcodec/mjpegdec.c | 79 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 2485591aab..903a139f49 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -101,12 +101,12 @@ static int init_default_huffman_tables(MJpegDecodeContext *s) static void parse_avid(MJpegDecodeContext *s, uint8_t *buf, int len) { s->buggy_avid = 1; - if (len > 14 && buf[12] == 1) /* 1 - NTSC */ + if (len > 12 && buf[12] == 1) /* 1 - NTSC */ s->interlace_polarity = 1; - if (len > 14 && buf[12] == 2) /* 2 - PAL */ + if (len > 12 && buf[12] == 2) /* 2 - PAL */ s->interlace_polarity = 0; if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 14 ? buf[12] : -1); + av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 12 ? buf[12] : -1); } static void init_idct(AVCodecContext *avctx) @@ -190,17 +190,25 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) } +static int mjpeg_parse_len(MJpegDecodeContext *s, int *plen, const char *name) +{ + int len = get_bits(&s->gb, 16); + if (len < 2 || get_bits_left(&s->gb) < (8 * len - 16)) { + av_log(s->avctx, AV_LOG_ERROR, "%s: invalid len %d\n", name, len); + return AVERROR_INVALIDDATA; + } + *plen = len - 2; + return 0; +} + /* quantize tables */ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) { int len, index, i; - len = get_bits(&s->gb, 16) - 2; - - if (8*len > get_bits_left(&s->gb)) { - av_log(s->avctx, AV_LOG_ERROR, "dqt: len %d is too large\n", len); - return AVERROR_INVALIDDATA; - } + int ret = mjpeg_parse_len(s, &len, "dqt"); + if (ret < 0) + return ret; while (len >= 65) { int pr = get_bits(&s->gb, 4); @@ -243,12 +251,9 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) uint8_t val_table[256]; int ret = 0; - len = get_bits(&s->gb, 16) - 2; - - if (8*len > get_bits_left(&s->gb)) { - av_log(s->avctx, AV_LOG_ERROR, "dht: len %d is too large\n", len); - return AVERROR_INVALIDDATA; - } + ret = mjpeg_parse_len(s, &len, "dht"); + if (ret < 0) + return ret; while (len > 0) { if (len < 17) @@ -308,7 +313,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) memset(s->upscale_h, 0, sizeof(s->upscale_h)); memset(s->upscale_v, 0, sizeof(s->upscale_v)); - len = get_bits(&s->gb, 16); + ret = mjpeg_parse_len(s, &len, "sof"); + if (ret < 0) + return ret; + if (len < 6) + return AVERROR_INVALIDDATA; bits = get_bits(&s->gb, 8); if (bits > 16 || bits < 1) { @@ -365,7 +374,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) "bits/component or 16-bit gray"); return AVERROR_PATCHWELCOME; } - if (len != 8 + 3 * nb_components) { + len -= 6; + if (len != 3 * nb_components) { av_log(s->avctx, AV_LOG_ERROR, "decode_sof0: error, len(%d) mismatch %d components\n", len, nb_components); return AVERROR_INVALIDDATA; } @@ -1683,8 +1693,11 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, return AVERROR_INVALIDDATA; } - /* XXX: verify len field validity */ - len = get_bits(&s->gb, 16); + ret = mjpeg_parse_len(s, &len, "sos"); + if (ret < 0) + return ret; + if (len < 1) + return AVERROR_INVALIDDATA; nb_components = get_bits(&s->gb, 8); if (nb_components == 0 || nb_components > MAX_COMPONENTS) { avpriv_report_missing_feature(s->avctx, @@ -1692,8 +1705,8 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, nb_components); return AVERROR_PATCHWELCOME; } - if (len != 6 + 2 * nb_components) { - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len); + if (len != 4 + 2 * nb_components) { + av_log(s->avctx, AV_LOG_ERROR, "decode_sos: len(%d) mismatch %d components\n", len, nb_components); return AVERROR_INVALIDDATA; } for (i = 0; i < nb_components; i++) { @@ -1850,10 +1863,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) { int len, id, i; - len = get_bits(&s->gb, 16); - if (len < 2) + int ret = mjpeg_parse_len(s, &len, "app"); + if (ret < 0) return AVERROR_INVALIDDATA; - len -= 2; if (len < 4) { if (s->avctx->err_recognition & AV_EF_EXPLODE) @@ -1862,9 +1874,6 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) goto out; } - if (8 * len > get_bits_left(&s->gb)) - return AVERROR_INVALIDDATA; - id = get_bits_long(&s->gb, 32); len -= 4; @@ -2155,16 +2164,21 @@ out: static int mjpeg_decode_com(MJpegDecodeContext *s) { - int len = get_bits(&s->gb, 16); - if (len >= 2 && 8 * len - 16 <= get_bits_left(&s->gb)) { + int len; + int ret = mjpeg_parse_len(s, &len, "com"); + if (ret < 0) + return ret; + if (!len) + return 0; + int i; - char *cbuf = av_malloc(len - 1); + char *cbuf = av_malloc(len + 1); if (!cbuf) return AVERROR(ENOMEM); - for (i = 0; i < len - 2; i++) + for (i = 0; i < len; i++) cbuf[i] = get_bits(&s->gb, 8); - if (i > 0 && cbuf[i - 1] == '\n') + if (cbuf[i - 1] == '\n') cbuf[i - 1] = 0; else cbuf[i] = 0; @@ -2186,7 +2200,6 @@ static int mjpeg_decode_com(MJpegDecodeContext *s) } av_free(cbuf); - } return 0; } _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
