[vlc-commits] demux: libavi: use parent for boundary check on chunk read
Francois Cartegnie
git at videolan.org
Tue Nov 21 18:32:56 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Nov 21 13:54:51 2017 +0100| [28e5cd0e0573acd9a7e05e2bc1119b8813728f42] | committer: Francois Cartegnie
demux: libavi: use parent for boundary check on chunk read
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=28e5cd0e0573acd9a7e05e2bc1119b8813728f42
---
modules/demux/avi/libavi.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/modules/demux/avi/libavi.c b/modules/demux/avi/libavi.c
index 38c938a5fc..ade9ac8af5 100644
--- a/modules/demux/avi/libavi.c
+++ b/modules/demux/avi/libavi.c
@@ -59,24 +59,38 @@ static uint64_t AVI_ChunkEnd( const avi_chunk_t *p_ck )
* Basics functions to manipulates chunks
*
****************************************************************************/
-static int AVI_ChunkReadCommon( stream_t *s, avi_chunk_t *p_chk )
+static int AVI_ChunkReadCommon( stream_t *s, avi_chunk_t *p_chk,
+ const avi_chunk_t *p_father )
{
const uint8_t *p_peek;
memset( p_chk, 0, sizeof( avi_chunk_t ) );
+ const uint64_t i_pos = vlc_stream_Tell( s );
if( vlc_stream_Peek( s, &p_peek, 8 ) < 8 )
+ {
+ if( stream_Size( s ) > 0 && (uint64_t) stream_Size( s ) > i_pos )
+ msg_Warn( s, "can't peek at %"PRIu64, i_pos );
+ else
+ msg_Dbg( s, "no more data at %"PRIu64, i_pos );
return VLC_EGENERIC;
+ }
p_chk->common.i_chunk_fourcc = GetFOURCC( p_peek );
p_chk->common.i_chunk_size = GetDWLE( p_peek + 4 );
- p_chk->common.i_chunk_pos = vlc_stream_Tell( s );
+ p_chk->common.i_chunk_pos = i_pos;
if( p_chk->common.i_chunk_size >= UINT64_MAX - 8 ||
p_chk->common.i_chunk_pos > UINT64_MAX - 8 ||
UINT64_MAX - p_chk->common.i_chunk_pos - 8 < __EVEN(p_chk->common.i_chunk_size) )
return VLC_EGENERIC;
+ if( p_father && AVI_ChunkEnd( p_chk ) > AVI_ChunkEnd( p_father ) )
+ {
+ msg_Warn( s, "chunk %4.4s does not fit into parent %ld",
+ (char*)&p_chk->common.i_chunk_fourcc, AVI_ChunkEnd( p_father ) );
+ return VLC_EGENERIC;
+ }
#ifdef AVI_DEBUG
msg_Dbg( (vlc_object_t*)s,
@@ -94,21 +108,13 @@ static int AVI_NextChunk( stream_t *s, avi_chunk_t *p_chk )
if( !p_chk )
{
- if( AVI_ChunkReadCommon( s, &chk ) )
+ if( AVI_ChunkReadCommon( s, &chk, p_chk->common.p_father ) )
{
return VLC_EGENERIC;
}
p_chk = &chk;
}
- if( p_chk->common.p_father )
- {
- if( AVI_ChunkEnd( p_chk->common.p_father ) < AVI_ChunkEnd( p_chk ) )
- {
- return VLC_EGENERIC;
- }
- }
-
bool b_seekable = false;
const uint64_t i_offset = AVI_ChunkEnd( p_chk );
if ( !vlc_stream_Control(s, STREAM_CAN_SEEK, &b_seekable) && b_seekable )
@@ -200,8 +206,8 @@ static int AVI_ChunkRead_list( stream_t *s, avi_chunk_t *p_container )
{
break;
}
- if( p_chk->common.p_father->common.i_chunk_size > 0 &&
- vlc_stream_Tell( s ) >= AVI_ChunkEnd( p_chk->common.p_father ) )
+ if( p_container->common.i_chunk_size > 0 &&
+ vlc_stream_Tell( s ) >= AVI_ChunkEnd( p_container ) )
{
break;
}
@@ -972,11 +978,8 @@ int AVI_ChunkRead( stream_t *s, avi_chunk_t *p_chk, avi_chunk_t *p_father )
return VLC_EGENERIC;
}
- if( AVI_ChunkReadCommon( s, p_chk ) )
- {
- msg_Warn( (vlc_object_t*)s, "cannot read one chunk" );
+ if( AVI_ChunkReadCommon( s, p_chk, p_father ) )
return VLC_EGENERIC;
- }
if( p_chk->common.i_chunk_fourcc == VLC_FOURCC( 0, 0, 0, 0 ) )
{
More information about the vlc-commits
mailing list