Commit faa5af57 authored by David Flynn's avatar David Flynn Committed by Laurent Aimar

demux/ogg: protect against invalid oggdirac stream

Signed-off-by: default avatarDavid Flynn <davidf@rd.bbc.co.uk>
Signed-off-by: default avatarLaurent Aimar <fenrir@videolan.org>
parent a60c74bf
...@@ -195,7 +195,7 @@ static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * ); ...@@ -195,7 +195,7 @@ static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * ); static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * ); static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * ); static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );
static void Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * ); static bool Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
/***************************************************************************** /*****************************************************************************
* Open: initializes ogg demux structures * Open: initializes ogg demux structures
...@@ -969,8 +969,14 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux ) ...@@ -969,8 +969,14 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
else if( oggpacket.bytes >= 5 && else if( oggpacket.bytes >= 5 &&
! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) )
{ {
Ogg_ReadDiracHeader( p_stream, &oggpacket ); if( Ogg_ReadDiracHeader( p_stream, &oggpacket ) )
msg_Dbg( p_demux, "found dirac header" ); msg_Dbg( p_demux, "found dirac header" );
else
{
msg_Warn( p_demux, "found dirac header isn't decodable" );
free( p_stream );
p_ogg->i_streams--;
}
} }
/* Check for Tarkin header */ /* Check for Tarkin header */
else if( oggpacket.bytes >= 7 && else if( oggpacket.bytes >= 7 &&
...@@ -1775,13 +1781,11 @@ static int dirac_bool( bs_t *p_bs ) ...@@ -1775,13 +1781,11 @@ static int dirac_bool( bs_t *p_bs )
return bs_read( p_bs, 1 ); return bs_read( p_bs, 1 );
} }
static void Ogg_ReadDiracHeader( logical_stream_t *p_stream, static bool Ogg_ReadDiracHeader( logical_stream_t *p_stream,
ogg_packet *p_oggpacket ) ogg_packet *p_oggpacket )
{ {
bs_t bs; bs_t bs;
p_stream->fmt.i_cat = VIDEO_ES;
p_stream->fmt.i_codec = VLC_FOURCC( 'd','r','a','c' );
p_stream->i_granule_shift = 22; /* not 32 */ p_stream->i_granule_shift = 22; /* not 32 */
/* Backing up stream headers is not required -- seqhdrs are repeated /* Backing up stream headers is not required -- seqhdrs are repeated
...@@ -1797,6 +1801,11 @@ static void Ogg_ReadDiracHeader( logical_stream_t *p_stream, ...@@ -1797,6 +1801,11 @@ static void Ogg_ReadDiracHeader( logical_stream_t *p_stream,
dirac_uint( &bs ); /* level */ dirac_uint( &bs ); /* level */
uint32_t u_video_format = dirac_uint( &bs ); /* index */ uint32_t u_video_format = dirac_uint( &bs ); /* index */
if( u_video_format > 20 )
{
/* don't know how to parse this ogg dirac stream */
return false;
}
if( dirac_bool( &bs ) ) if( dirac_bool( &bs ) )
{ {
...@@ -1828,17 +1837,16 @@ static void Ogg_ReadDiracHeader( logical_stream_t *p_stream, ...@@ -1828,17 +1837,16 @@ static void Ogg_ReadDiracHeader( logical_stream_t *p_stream,
}; };
static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate); static const size_t u_dirac_vidfmt_frate = sizeof(pu_dirac_vidfmt_frate)/sizeof(*pu_dirac_vidfmt_frate);
/* */
if( u_video_format >= u_dirac_vidfmt_frate )
u_video_format = 0;
uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n; uint32_t u_n = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_n;
uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d; uint32_t u_d = p_dirac_frate_tbl[pu_dirac_vidfmt_frate[u_video_format]].u_d;
if( dirac_bool( &bs ) ) if( dirac_bool( &bs ) )
{ {
uint32_t u_frame_rate_index = dirac_uint( &bs ); uint32_t u_frame_rate_index = dirac_uint( &bs );
if( u_frame_rate_index >= u_dirac_frate_tbl ) if( u_frame_rate_index >= u_dirac_frate_tbl )
u_frame_rate_index = 0; {
/* something is wrong with this stream */
return false;
}
u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n; u_n = p_dirac_frate_tbl[u_frame_rate_index].u_n;
u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d; u_d = p_dirac_frate_tbl[u_frame_rate_index].u_d;
if( u_frame_rate_index == 0 ) if( u_frame_rate_index == 0 )
...@@ -1848,4 +1856,10 @@ static void Ogg_ReadDiracHeader( logical_stream_t *p_stream, ...@@ -1848,4 +1856,10 @@ static void Ogg_ReadDiracHeader( logical_stream_t *p_stream,
} }
} }
p_stream->f_rate = (float) u_n / u_d; p_stream->f_rate = (float) u_n / u_d;
/* probably is an ogg dirac es */
p_stream->fmt.i_cat = VIDEO_ES;
p_stream->fmt.i_codec = VLC_FOURCC( 'd','r','a','c' );
return true;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment