vlc | branch: master | Rémi Denis-Courmont <r...@remlab.net> | Sat Feb 25 14:08:23 2017 +0200| [72d6528f121b985c0275fd341e1aa7b5e69c1f5d] | committer: Rémi Denis-Courmont
xa: handle header read error, fix struct size This fixes the vlc_stream_Read() compiler warning. As pointed out by Filip, some archs could pad the structure to a boundary larger than 8 bytes, defeating the sizeof() value. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=72d6528f121b985c0275fd341e1aa7b5e69c1f5d --- modules/demux/xa.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/modules/demux/xa.c b/modules/demux/xa.c index bdbd107..cc525cf 100644 --- a/modules/demux/xa.c +++ b/modules/demux/xa.c @@ -29,6 +29,7 @@ # include "config.h" #endif +#include <assert.h> #include <vlc_common.h> #include <vlc_plugin.h> #include <vlc_demux.h> @@ -79,6 +80,8 @@ typedef struct xa_header_t uint16_t wBitsPerSample; } xa_header_t; +static_assert(offsetof(xa_header_t, wBitsPerSample) == 22, "Bad padding"); + #define FRAME_LENGTH 28 /* samples per frame */ /***************************************************************************** @@ -87,46 +90,46 @@ typedef struct xa_header_t static int Open( vlc_object_t * p_this ) { demux_t *p_demux = (demux_t*)p_this; - demux_sys_t *p_sys; - xa_header_t p_xa; - const uint8_t *p_buf; + const uint8_t *peek; /* XA file heuristic */ - if( vlc_stream_Peek( p_demux->s, &p_buf, sizeof( p_xa ) ) - < (signed)sizeof( p_xa ) ) + if( vlc_stream_Peek( p_demux->s, &peek, 10 ) < 10 ) return VLC_EGENERIC; - - memcpy( &p_xa, p_buf, sizeof( p_xa ) ); - if( ( strncmp( p_xa.xa_id, "XAI", 4 ) - && strncmp( p_xa.xa_id, "XAJ", 4 ) ) - || ( GetWLE( &p_xa.wFormatTag ) != 0x0001) - || ( GetWLE( &p_xa.wBitsPerSample ) != 16) ) + if( memcmp( peek, "XAI", 4 ) && memcmp( peek, "XAJ", 4 ) ) + return VLC_EGENERIC; + if( GetWLE( peek + 8 ) != 1 ) /* format tag */ return VLC_EGENERIC; - p_sys = malloc( sizeof( demux_sys_t ) ); + demux_sys_t *p_sys = malloc( sizeof( demux_sys_t ) ); if( unlikely( p_sys == NULL ) ) return VLC_ENOMEM; - /* skip XA header -- cannot fail */ - vlc_stream_Read( p_demux->s, NULL, sizeof( p_xa ) ); + /* read XA header*/ + xa_header_t xa; + + if( vlc_stream_Read( p_demux->s, &xa, 24 ) < 24 ) + { + free( p_sys ); + return VLC_EGENERIC; + } es_format_t fmt; es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('X','A','J',0) ); msg_Dbg( p_demux, "assuming EA ADPCM audio codec" ); - fmt.audio.i_rate = GetDWLE( &p_xa.nSamplesPerSec ); - fmt.audio.i_bytes_per_frame = 15 * GetWLE( &p_xa.nChannels ); + fmt.audio.i_rate = GetDWLE( &xa.nSamplesPerSec ); + fmt.audio.i_bytes_per_frame = 15 * GetWLE( &xa.nChannels ); fmt.audio.i_frame_length = FRAME_LENGTH; - fmt.audio.i_channels = GetWLE ( &p_xa.nChannels ); + fmt.audio.i_channels = GetWLE ( &xa.nChannels ); fmt.audio.i_blockalign = fmt.audio.i_bytes_per_frame; - fmt.audio.i_bitspersample = 16; + fmt.audio.i_bitspersample = GetWLE( &xa.wBitsPerSample ); fmt.i_bitrate = (fmt.audio.i_rate * fmt.audio.i_bytes_per_frame * 8) / fmt.audio.i_frame_length; p_sys->i_data_offset = vlc_stream_Tell( p_demux->s ); /* FIXME: better computation */ - p_sys->i_data_size = p_xa.iSize * 15 / 56; + p_sys->i_data_size = xa.iSize * 15 / 56; /* How many frames per block (1:1 is too CPU intensive) */ p_sys->i_block_frames = fmt.audio.i_rate / (FRAME_LENGTH * 20) + 1; p_sys->i_frame_size = fmt.audio.i_bytes_per_frame; @@ -137,7 +140,8 @@ static int Open( vlc_object_t * p_this ) (char *)&fmt.i_codec, fmt.audio.i_channels, fmt.audio.i_rate, fmt.i_bitrate / 8192, fmt.audio.i_blockalign ); - if( fmt.audio.i_rate == 0 || fmt.audio.i_channels == 0 ) + if( fmt.audio.i_rate == 0 || fmt.audio.i_channels == 0 + || fmt.audio.i_bitspersample != 16 ) { free( p_sys ); return VLC_EGENERIC; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits