diff mbox series

[FFmpeg-devel] Patch libavcodec/jpeg2000_parser: Fix skipping of JP2 info markers...

Message ID CAGKSLyzZKsT9SPhGFVDT_a0jzCZ26fm5OcSaqRqdaUaq7ojw0A@mail.gmail.com
State Accepted
Commit 16102cada5a7c6e0a2aa07b1d2ac24dabc2095d9
Headers show
Series [FFmpeg-devel] Patch libavcodec/jpeg2000_parser: Fix skipping of JP2 info markers... | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Shaun Simpson July 21, 2021, 3:48 p.m. UTC
libavcodec/jpeg2000_parser: Fix skipping of JP2 info markers by correctly
reading marker size.

This fixes playback of some JPEG2000 files that fail with a frame not found
error.

When reading the JP2 info markers, the parser can be triggered into
incorrectly calculating the number of bytes to skip of the next tag. This
is error is buffer data dependant.

This patch corrects this testing if the next marker is a info marker, and
correcting the number of skipped bytes if it is.

Please note that this is patch 2/2

PATCH 1/2 libavcodec/jpeg2000_parser: Fix parsing of tile-part  header, and
frames where the end of frame marker is at the end of the buffer

I apologise for splitting the patches this way.

Thank you,

Shaun Simpson
Subject: [PATCH 2/2] libavcodec/jpeg2000_parser: Fix skipping of JP2 info
 markers by correctly reading marker size.

Signed-off-by: Shaun Simpson <shauns2029@gmail.com>
---
 libavcodec/jpeg2000_parser.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/jpeg2000_parser.c b/libavcodec/jpeg2000_parser.c
index b332a067e5..e16ca2174c 100644
--- a/libavcodec/jpeg2000_parser.c
+++ b/libavcodec/jpeg2000_parser.c
@@ -81,7 +81,7 @@  static int find_frame_end(JPEG2000ParserContext *m, const uint8_t *buf, int buf_
 {
     ParseContext *pc= &m->pc;
     int i;
-    uint32_t state;
+    uint32_t state, next_state;
     uint64_t state64;
     state= pc->state;
     state64 = pc->state64;
@@ -142,7 +142,17 @@  static int find_frame_end(JPEG2000ParserContext *m, const uint8_t *buf, int buf_
         } else if (m->in_codestream && (state & 0xFFFF) == 0xFF90) { // Are we in tile part header?
             m->read_tp = 8;
         } else if (pc->frame_start_found && info_marker((state & 0xFFFF0000)>>16) && m->in_codestream) {
-            m->skip_bytes = (state & 0xFFFF) - 2;
+            // Calculate number of bytes to skip to get to end of the next marker.
+            m->skip_bytes = (state & 0xFFFF)-1;
+
+            // If the next marker is an info marker, skip to the end of of the marker length.
+            if (i + m->skip_bytes + 1 < buf_size) {
+                next_state = (buf[i + m->skip_bytes] << 8) | buf[i + m->skip_bytes + 1];
+                if (info_marker(next_state)) {
+                    // Skip an additional 2 bytes to get to the end of the marker length.
+                    m->skip_bytes += 2;
+                }
+            }
         }
     }