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
From bea5f87977789ca69b3601c3388b6ca575d976cb Mon Sep 17 00:00:00 2001 From: Shaun Simpson <shauns2...@gmail.com> Date: Wed, 21 Jul 2021 14:15:45 +0100 Subject: [PATCH 2/2] libavcodec/jpeg2000_parser: Fix skipping of JP2 info markers by correctly reading marker size. Signed-off-by: Shaun Simpson <shauns2...@gmail.com> --- libavcodec/jpeg2000_parser.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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; + } + } } } -- 2.30.2
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".