Commit 0f89d936b3 for ffmpeg

commit 0f89d936b39e1cb438a874ecfccffe253be6b63b
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Fri Nov 6 02:09:33 2026 +0100

    avcodec/jpeg2000_parser: look only for EOC in the data of a tile-part with Psot 0

    Fixes: 9ulyCCXNUqlt

    Found during triage of the security report kgusFCuY3WYo

    Merged frames Replicated through UnModified FFmpeg with ffprobe

    Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

diff --git a/libavcodec/jpeg2000_parser.c b/libavcodec/jpeg2000_parser.c
index edf47934d5..8a3aac9ef5 100644
--- a/libavcodec/jpeg2000_parser.c
+++ b/libavcodec/jpeg2000_parser.c
@@ -45,6 +45,7 @@ typedef struct JPEG2000ParserContext {
     uint8_t skipped_codestream;
     uint8_t read_tp;
     uint8_t in_codestream;
+    uint8_t skip_to_eoc;
 } JPEG2000ParserContext;

 static inline void reset_context(JPEG2000ParserContext *m)
@@ -60,6 +61,7 @@ static inline void reset_context(JPEG2000ParserContext *m)
     m->skip_bytes = 0;
     m->read_tp = 0;
     m->in_codestream = 0;
+    m->skip_to_eoc = 0;
 }

 /* Returns 1 if marker has any data which can be skipped
@@ -128,6 +130,12 @@ static int find_frame_end(JPEG2000ParserContext *m, const uint8_t *buf, int buf_
             m->read_tp--;
             continue;
         }
+        if (m->skip_to_eoc) {
+            if ((state64 & 0xFFFF) == 0xFF91)
+                m->skip_bytes = 5;
+            if ((state64 & 0xFFFF) != 0xFFD9)
+                continue;
+        }
         if (m->fheader_read) {
             if (m->fheader_read == 1) {
                 if (state64 == 0x6A5020200D0A870A) { // JP2 signature box value.
@@ -162,9 +170,12 @@ static int find_frame_end(JPEG2000ParserContext *m, const uint8_t *buf, int buf_
                 return i + 1; // End of frame detected, return frame size.
             }
             m->in_codestream = 0;
+            m->skip_to_eoc = 0;
         } else if (m->in_codestream) {
             if ((state64 & 0xFFFF) == 0xFF90) { // Are we in tile part header?
                 m->read_tp = 8;
+            } else if ((state64 & 0xFFFF) == 0xFF93) {
+                m->skip_to_eoc = 1;
             } else if (info_marker((state64 & 0xFFFF0000)>>16) && pc->frame_start_found && (state64 & 0xFFFF)) {
                 // Calculate number of bytes to skip to get to end of the next marker.
                 m->skip_bytes = (state64 & 0xFFFF)-1;