[vlc-commits] xa: handle header read error, fix struct size
Rémi Denis-Courmont
git at videolan.org
Sat Feb 25 13:11:22 CET 2017
vlc | branch: master | Rémi Denis-Courmont <remi at 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;
More information about the vlc-commits
mailing list