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]

Reply via email to