avcodec/jpeg2000dec: implement cdef remapping during pixel format matching
authorMichael Niedermayer <michael@niedermayer.cc>
Tue, 5 Aug 2025 21:42:23 +0000 (23:42 +0200)
committerMichael Niedermayer <michael@niedermayer.cc>
Wed, 13 Aug 2025 22:20:30 +0000 (00:20 +0200)
Fixes: out of array access
Fixes: poc.jp2

Found-by: Andy Nguyen <theflow@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 01a292c7e36545ddeb3c7f79cd02e2611cd37d73)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavcodec/jpeg2000dec.c

index 9586e2011c455841886e9fc5bd15faa8b215be90..a34bbc833ae65a80dd1257c87d126bbc7b094bac 100644 (file)
@@ -357,6 +357,14 @@ static int get_siz(Jpeg2000DecoderContext *s)
     }
     // after here we no longer have to consider negative cdef
 
+    int cdef_used = 0;
+    for (i = 0; i < s->ncomponents; i++)
+        cdef_used |= 1<<s->cdef[i];
+
+    // Check that the channels we have are what we expect for the number of components
+    if (cdef_used != ((int[]){0,2,3,14,15})[s->ncomponents])
+        return AVERROR_INVALIDDATA;
+
     for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i
         uint8_t x    = bytestream2_get_byteu(&s->g);
         s->cbps[i]   = (x & 0x7f) + 1;
@@ -369,7 +377,9 @@ static int get_siz(Jpeg2000DecoderContext *s)
             av_log(s->avctx, AV_LOG_ERROR, "Invalid sample separation %d/%d\n", s->cdx[i], s->cdy[i]);
             return AVERROR_INVALIDDATA;
         }
-        log2_chroma_wh |= s->cdy[i] >> 1 << i * 4 | s->cdx[i] >> 1 << i * 4 + 2;
+        int i_remapped = s->cdef[i] ? s->cdef[i]-1 : (s->ncomponents-1);
+
+        log2_chroma_wh |= s->cdy[i] >> 1 << i_remapped * 4 | s->cdx[i] >> 1 << i_remapped * 4 + 2;
     }
 
     s->numXtiles = ff_jpeg2000_ceildiv(s->width  - s->tile_offset_x, s->tile_width);