[vlc-commits] [Git][videolan/vlc][master] 9 commits: meta_engine: i3dtag: early on ID3 size values
Steve Lhomme (@robUx4)
gitlab at videolan.org
Wed Apr 29 03:52:34 UTC 2026
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
acc9fa38 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: i3dtag: early on ID3 size values
i_peek = 10 is OK to read the size.
- - - - -
8f8ac233 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: fix indentation
No functional changes.
- - - - -
bd4d5b07 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: pass the buffer size to ID3TAG_IsTag()
- - - - -
de5014df by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: simplify test
- - - - -
89448363 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: use a different variable for the rolling p_frame buffer size
- - - - -
e74b7d13 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: undo the i_framesize shift by 10
Apply it where i_framesize is evaluated (no functional changes).
- - - - -
756d1b50 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: check frame size against remaining frame length
This avoids a potential addition overflow. We know frame_length is a least 10.
Fixes #29803
- - - - -
b134ec88 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: simplify tag length check before calling callback
- - - - -
149b9b79 by Steve Lhomme at 2026-04-29T03:31:25+00:00
meta_engine: id3tag: return size of ID3 tag data even if they are bogus
We should skip the data, not keep trying to parse them by the caller.
- - - - -
3 changed files:
- modules/demux/adaptive/StreamFormat.cpp
- modules/demux/hls/HLSStreams.cpp
- modules/meta_engine/ID3Tag.h
Changes:
=====================================
modules/demux/adaptive/StreamFormat.cpp
=====================================
@@ -147,7 +147,7 @@ StreamFormat::StreamFormat(const void *data_, size_t sz)
}
/* Skipped ID3 if any */
- while(sz > 10 && ID3TAG_IsTag(data, false))
+ while(ID3TAG_IsTag(data, sz, false))
{
size_t tagsize = ID3TAG_Parse(data, sz, ID3Callback, this);
if(tagsize >= sz || tagsize == 0)
=====================================
modules/demux/hls/HLSStreams.cpp
=====================================
@@ -112,7 +112,7 @@ block_t * HLSStream::checkBlock(block_t *p_block, bool b_first)
{
if(b_first && p_block)
{
- while(p_block->i_buffer >= 10 && ID3TAG_IsTag(p_block->p_buffer, false))
+ while(ID3TAG_IsTag(p_block->p_buffer, p_block->i_buffer, false))
{
size_t i_size = ID3TAG_Parse( p_block->p_buffer, p_block->i_buffer,
ID3TAG_Parse_Handler, static_cast<void *>(this) );
=====================================
modules/meta_engine/ID3Tag.h
=====================================
@@ -20,6 +20,8 @@
#ifndef ID3TAG_H
#define ID3TAG_H
+#include <limits.h>
+
static uint32_t ID3TAG_ReadSize( const uint8_t *p_buffer, bool b_syncsafe )
{
if( !b_syncsafe )
@@ -30,9 +32,9 @@ static uint32_t ID3TAG_ReadSize( const uint8_t *p_buffer, bool b_syncsafe )
(( (uint32_t)p_buffer[0] & 0x7F ) << 21);
}
-static bool ID3TAG_IsTag( const uint8_t *p_buffer, bool b_footer )
+static bool ID3TAG_IsTag( const uint8_t *p_buffer, size_t buffer_len, bool b_footer )
{
- return( memcmp(p_buffer, (b_footer) ? "3DI" : "ID3", 3) == 0 &&
+ return( buffer_len >= 10 && memcmp(p_buffer, (b_footer) ? "3DI" : "ID3", 3) == 0 &&
p_buffer[3] < 0xFF &&
p_buffer[4] < 0xFF &&
((GetDWBE(&p_buffer[6]) & 0x80808080) == 0) );
@@ -41,59 +43,62 @@ static bool ID3TAG_IsTag( const uint8_t *p_buffer, bool b_footer )
static size_t ID3TAG_Parse( const uint8_t *p_peek, size_t i_peek,
int (*pf_callback)(uint32_t, const uint8_t *, size_t, void *), void *p_priv )
{
- size_t i_total_size = 0;
- uint32_t i_ID3size = 0;
- if( i_peek > 10 && ID3TAG_IsTag( p_peek, false ) )
- {
- const uint8_t i_ID3major = p_peek[3];
- const uint8_t i_ID3flags = p_peek[5];
- i_ID3size = ID3TAG_ReadSize( &p_peek[6], true );
- if( i_ID3size > i_peek - 10 )
- return 0;
- i_total_size = i_ID3size + 10;
+ if( !ID3TAG_IsTag( p_peek, i_peek, false ) )
+ return 0; /* not an ID3 tag */
- const uint8_t *p_frame = &p_peek[10];
+ const uint32_t i_ID3size = ID3TAG_ReadSize( &p_peek[6], true );
+ if( i_ID3size > i_peek - 10 )
+ return 0; /* not enough peek */
+#if UINT32_MAX >= SIZE_MAX
+ if( i_ID3size > SIZE_MAX - 10 )
+ return 0; /* total size overflow */
+#endif
- if( i_ID3major >= 3 && i_ID3major <= 4 && (i_ID3flags & 0x40) ) /* ext header */
- {
- if( i_ID3size < 6 ) /* can't be less than 6 */
- return 0;
- uint32_t i_exthdr = ID3TAG_ReadSize( p_frame, true );
- if( i_ID3major == 3 )
- {
- /* 6 or 10 bytes not including size storage */
- if( i_exthdr != 6 && i_exthdr != 10 )
- return 0;
- i_exthdr += 4;
- }
- if( i_ID3size < i_exthdr )
- return 0;
- p_frame += i_exthdr;
- i_ID3size -= i_exthdr;
- }
+ size_t i_total_size = i_ID3size + 10;
+ /* Count footer if any */
+ if( i_peek > i_total_size &&
+ ID3TAG_IsTag( &p_peek[i_total_size], i_peek - i_total_size, true ) )
+ {
+ i_total_size += 10;
+ }
- /* Tags */
- while( i_ID3size > 10 )
+ const uint8_t i_ID3major = p_peek[3];
+ const uint8_t i_ID3flags = p_peek[5];
+ const uint8_t *p_frame = &p_peek[10];
+ size_t frame_length = i_ID3size;
+
+ if( (i_ID3major == 3 || i_ID3major == 4) && (i_ID3flags & 0x40) ) /* ext header */
+ {
+ if( frame_length < 6 ) /* can't be less than 6 */
+ return 0;
+ uint32_t i_exthdr = ID3TAG_ReadSize( p_frame, true );
+ if( i_ID3major == 3 )
{
- uint32_t i_tagname = VLC_FOURCC( p_frame[0], p_frame[1], p_frame[2], p_frame[3] );
- uint32_t i_framesize = ID3TAG_ReadSize( &p_frame[4], i_ID3major != 3 ) + 10;
- if( i_framesize > i_ID3size )
+ /* 6 or 10 bytes not including size storage */
+ if( i_exthdr != 6 && i_exthdr != 10 )
return 0;
-
- if( i_framesize > 10 &&
- pf_callback( i_tagname, &p_frame[10], i_framesize - 10, p_priv ) != VLC_SUCCESS )
- break;
-
- p_frame += i_framesize;
- i_ID3size -= i_framesize;
+ i_exthdr += 4;
}
+ if( frame_length < i_exthdr )
+ return 0;
+ p_frame += i_exthdr;
+ frame_length -= i_exthdr;
}
- /* Count footer if any */
- if( i_total_size && i_peek - i_total_size >= 10 &&
- ID3TAG_IsTag( &p_peek[i_total_size], true ) )
+ /* Tags */
+ while( frame_length > 10 )
{
- i_total_size += 10;
+ uint32_t i_tagname = VLC_FOURCC( p_frame[0], p_frame[1], p_frame[2], p_frame[3] );
+ uint32_t i_framesize = ID3TAG_ReadSize( &p_frame[4], i_ID3major != 3 );
+ if( i_framesize > frame_length - 10 )
+ break; /* not enough peek */
+
+ if( i_framesize != 0 &&
+ pf_callback( i_tagname, &p_frame[10], i_framesize, p_priv ) != VLC_SUCCESS )
+ break;
+
+ p_frame += i_framesize + 10;
+ frame_length -= i_framesize + 10;
}
return i_total_size;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/471e6c6c5840ad1f26d041c8e26dcfeffaa07f11...149b9b79cb04bd5a042a52ba86ea7e508da1c07d
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/471e6c6c5840ad1f26d041c8e26dcfeffaa07f11...149b9b79cb04bd5a042a52ba86ea7e508da1c07d
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list