[vlc-commits] [Git][videolan/vlc][master] 12 commits: demux: aiff: avoid using a potentially negative read amount
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Aug 14 11:48:04 UTC 2026
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
334161d1 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: avoid using a potentially negative read amount
i_ssnd_end comes from values (i_ssnd_offset, i_ssnd_size) read in the file.
- - - - -
81e5c904 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: avoid returning a potentially negative position
i_ssnd_start comes from values (i_ssnd_offset) read in the file.
- - - - -
f19090a3 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: check the number of channels is supported
We only support 32 channels and write the value in a uint8_t.
- - - - -
d04cc3e4 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: do not parse the data again for logging
- - - - -
20d8c746 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: reject files without a SSND chunk
The i_ssnd_start ends up being negative and the size is 0.
It was already handled by the minimum pos of 12.
- - - - -
aedc79bd by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: remove always false test
i_ssnd_pos is either -1 (SSND chunk not found) or it has a positive value from vlc_stream_Tell().
Given the position in the file is read after have already read 12 bytes at the beginning of
the file (skip aiff header), the position can never be smaller than 12.
- - - - -
1cc8e47a by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: use uint32_t for i_ssnd_size
Its only source is i_data_size which is a uint32_t.
- - - - -
39e27c38 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: read some vlc_stream_Tell() values as uint64_t
- - - - -
03b48a50 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: make i_ssnd_fsize unsigned
It's the multiplication of an 8-bit unsigned value and a 16-bit unsigned value.
- - - - -
83c26379 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: make i_ssnd_offset a uint32_t
It's read as an unsigned 32-bit value.
- - - - -
78fcda15 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: use more local variables in Open()
- - - - -
6a485a24 by Steve Lhomme at 2026-08-14T11:21:35+00:00
demux: aiff: make i_ssnd_pos unsigned
It's either -1 (unset) or comes from vlc_stream_Tell() which gives a uint64_t.
As a consequence i_ssnd_start and i_ssnd_end and also unsigned.
- - - - -
1 changed file:
- modules/demux/aiff.c
Changes:
=====================================
modules/demux/aiff.c
=====================================
@@ -34,6 +34,7 @@
#include <vlc_aout.h>
#include <vlc_meta.h>
#include <limits.h>
+#include <stdint.h>
#include "mp4/coreaudio.h"
@@ -62,19 +63,14 @@ vlc_module_end ()
typedef struct
{
- es_format_t fmt;
es_out_id_t *es;
-
- int64_t i_ssnd_pos;
- int64_t i_ssnd_size;
- int i_ssnd_offset;
- int i_ssnd_blocksize;
+ unsigned int i_rate;
/* real data start */
- int64_t i_ssnd_start;
- int64_t i_ssnd_end;
+ uint64_t i_ssnd_start;
+ uint64_t i_ssnd_end;
- int i_ssnd_fsize;
+ unsigned i_ssnd_fsize;
vlc_tick_t i_time;
@@ -191,11 +187,15 @@ static int Open( vlc_object_t *p_this )
p_demux->p_sys = p_sys;
p_sys->i_time = 0;
- p_sys->i_ssnd_pos = -1;
p_sys->i_chans_to_reorder = 0;
- es_format_Init( &p_sys->fmt, AUDIO_ES, VLC_FOURCC( 't', 'w', 'o', 's' ) );
+
+ es_format_t fmt;
+ es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 't', 'w', 'o', 's' ) );
const uint32_t *pi_channels_in = NULL;
+ uint64_t i_ssnd_pos = UINT64_C(-1);
+ uint32_t i_ssnd_size = 0;
+ uint32_t i_ssnd_offset = 0;
for( ;; )
{
@@ -213,26 +213,32 @@ static int Open( vlc_object_t *p_this )
if( vlc_stream_Peek( p_demux->s, &p_peek, 18+8 ) < 18+8 )
goto error;
- p_sys->fmt.audio.i_channels = GetWBE( &p_peek[8] );
- p_sys->fmt.audio.i_bitspersample = GetWBE( &p_peek[14] );
- p_sys->fmt.audio.i_rate = GetF80BE( &p_peek[16] );
+ uint16_t channels = GetWBE( &p_peek[8] );
+ if (channels > 32)
+ {
+ msg_Err( p_demux, "Unsupported number of channels %" PRIu16, channels );
+ goto error;
+ }
+ fmt.audio.i_channels = channels;
+ fmt.audio.i_bitspersample = GetWBE( &p_peek[14] );
+ fmt.audio.i_rate = p_sys->i_rate = GetF80BE( &p_peek[16] );
- msg_Dbg( p_demux, "COMM: channels=%d samples_frames=%d bits=%d rate=%d",
- GetWBE( &p_peek[8] ), GetDWBE( &p_peek[10] ), GetWBE( &p_peek[14] ),
- GetF80BE( &p_peek[16] ) );
+ msg_Dbg( p_demux, "COMM: channels=%" PRIu16 " samples_frames=%d bits=%u rate=%u",
+ channels, GetDWBE( &p_peek[10] ), fmt.audio.i_bitspersample,
+ fmt.audio.i_rate );
}
else if( !memcmp( p_peek, "SSND", 4 ) )
{
if( vlc_stream_Peek( p_demux->s, &p_peek, 8+8 ) < 8+8 )
goto error;
- p_sys->i_ssnd_pos = vlc_stream_Tell( p_demux->s );
- p_sys->i_ssnd_size = i_data_size;
- p_sys->i_ssnd_offset = GetDWBE( &p_peek[8] );
- p_sys->i_ssnd_blocksize = GetDWBE( &p_peek[12] );
+ i_ssnd_pos = vlc_stream_Tell( p_demux->s );
+ i_ssnd_size = i_data_size;
+ i_ssnd_offset = GetDWBE( &p_peek[8] );
+ uint32_t i_ssnd_blocksize = GetDWBE( &p_peek[12] );
- msg_Dbg( p_demux, "SSND: (offset=%d blocksize=%d)",
- p_sys->i_ssnd_offset, p_sys->i_ssnd_blocksize );
+ msg_Dbg( p_demux, "SSND: (offset=%" PRIu32 " blocksize=%" PRIu32 ")",
+ i_ssnd_offset, i_ssnd_blocksize );
}
else if( !memcmp( p_peek, "CHAN", 4 ) && i_chunk_size > 8 + 12 )
{
@@ -247,8 +253,8 @@ static int Open( vlc_object_t *p_this )
/* TODO: handle CoreAudio_layout_s.p_descriptions */
if ( CoreAudio_Layout_to_vlc( &layout,
- &p_sys->fmt.audio.i_physical_channels,
- &p_sys->fmt.audio.i_channels,
+ &fmt.audio.i_physical_channels,
+ &fmt.audio.i_channels,
&pi_channels_in ) != VLC_SUCCESS )
msg_Warn( p_demux, "discarding chan mapping" );
}
@@ -276,32 +282,38 @@ static int Open( vlc_object_t *p_this )
}
}
+ if ( i_ssnd_pos == UINT64_C(-1) )
+ {
+ msg_Err( p_demux, "Missing SSND chunk" );
+ goto error;
+ }
+
if( pi_channels_in != NULL )
{
p_sys->i_chans_to_reorder =
aout_CheckChannelReorder( pi_channels_in, NULL,
- p_sys->fmt.audio.i_physical_channels,
+ fmt.audio.i_physical_channels,
p_sys->pi_chan_table ) > 0;
p_sys->audio_fourcc =
- vlc_fourcc_GetCodecAudio( p_sys->fmt.i_codec,
- p_sys->fmt.audio.i_bitspersample );
+ vlc_fourcc_GetCodecAudio( fmt.i_codec,
+ fmt.audio.i_bitspersample );
if( p_sys->audio_fourcc == 0 )
p_sys->i_chans_to_reorder = 0;
}
- p_sys->i_ssnd_start = p_sys->i_ssnd_pos + 16 + p_sys->i_ssnd_offset;
- p_sys->i_ssnd_end = p_sys->i_ssnd_start + p_sys->i_ssnd_size;
+ p_sys->i_ssnd_start = i_ssnd_pos + 16 + i_ssnd_offset;
+ p_sys->i_ssnd_end = p_sys->i_ssnd_start + i_ssnd_size;
- p_sys->i_ssnd_fsize = p_sys->fmt.audio.i_channels *
- ((p_sys->fmt.audio.i_bitspersample + 7) / 8);
+ p_sys->i_ssnd_fsize = fmt.audio.i_channels *
+ ((fmt.audio.i_bitspersample + 7) / 8);
- if( p_sys->i_ssnd_fsize <= 0 || p_sys->fmt.audio.i_rate == 0 || p_sys->i_ssnd_pos < 12 )
+ if( p_sys->i_ssnd_fsize == 0 || p_sys->i_rate == 0 )
{
msg_Err( p_demux, "invalid audio parameters" );
goto error;
}
- if( p_sys->i_ssnd_size <= 0 )
+ if( i_ssnd_size == 0 )
{
/* unknown */
p_sys->i_ssnd_end = 0;
@@ -315,8 +327,8 @@ static int Open( vlc_object_t *p_this )
}
/* */
- p_sys->fmt.i_id = 0;
- p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
+ fmt.i_id = 0;
+ p_sys->es = es_out_Add( p_demux->out, &fmt );
if( unlikely(p_sys->es == NULL) )
goto error;
@@ -336,12 +348,12 @@ error:
static int Demux( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
- int64_t i_tell = vlc_stream_Tell( p_demux->s );
+ uint64_t i_tell = vlc_stream_Tell( p_demux->s );
block_t *p_block;
- int i_read;
+ size_t i_read;
- if( p_sys->i_ssnd_end > 0 && i_tell >= p_sys->i_ssnd_end )
+ if( p_sys->i_ssnd_end != 0 && i_tell >= p_sys->i_ssnd_end )
{
/* EOF */
return VLC_DEMUXER_EOF;
@@ -351,8 +363,8 @@ static int Demux( demux_t *p_demux )
es_out_SetPCR( p_demux->out, VLC_TICK_0 + p_sys->i_time);
/* we will read 100ms at once */
- i_read = p_sys->i_ssnd_fsize * ( p_sys->fmt.audio.i_rate / 10 );
- if( p_sys->i_ssnd_end > 0 && p_sys->i_ssnd_end - i_tell < i_read )
+ i_read = p_sys->i_ssnd_fsize * ( p_sys->i_rate / 10 );
+ if( p_sys->i_ssnd_end != 0 && p_sys->i_ssnd_end > i_tell && p_sys->i_ssnd_end - i_tell < i_read )
{
i_read = p_sys->i_ssnd_end - i_tell;
}
@@ -366,7 +378,7 @@ static int Demux( demux_t *p_demux )
p_sys->i_time += vlc_tick_from_samples(p_block->i_buffer,
p_sys->i_ssnd_fsize) /
- p_sys->fmt.audio.i_rate;
+ p_sys->i_rate;
if( p_sys->i_chans_to_reorder )
aout_ChannelReorder( p_block->p_buffer, p_block->i_buffer,
@@ -404,13 +416,13 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_GET_POSITION:
{
- int64_t i_start = p_sys->i_ssnd_start;
- int64_t i_end = p_sys->i_ssnd_end > 0 ? p_sys->i_ssnd_end : stream_Size( p_demux->s );
- int64_t i_tell = vlc_stream_Tell( p_demux->s );
+ uint64_t i_start = p_sys->i_ssnd_start;
+ uint64_t i_end = p_sys->i_ssnd_end != 0 ? p_sys->i_ssnd_end : stream_Size( p_demux->s );
+ uint64_t i_tell = vlc_stream_Tell( p_demux->s );
pf = va_arg( args, double * );
- if( i_start < i_end )
+ if( i_start < i_end && i_start <= i_tell )
{
*pf = (double)(i_tell - i_start)/(double)(i_end - i_start);
return VLC_SUCCESS;
@@ -420,21 +432,21 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_SET_POSITION:
{
- int64_t i_start = p_sys->i_ssnd_start;
- int64_t i_end = p_sys->i_ssnd_end > 0 ? p_sys->i_ssnd_end : stream_Size( p_demux->s );
+ uint64_t i_start = p_sys->i_ssnd_start;
+ uint64_t i_end = p_sys->i_ssnd_end != 0 ? p_sys->i_ssnd_end : stream_Size( p_demux->s );
f = va_arg( args, double );
if( i_start < i_end )
{
- int i_frame = (f * ( i_end - i_start )) / p_sys->i_ssnd_fsize;
- int64_t i_new = i_start + i_frame * p_sys->i_ssnd_fsize;
+ unsigned i_frame = (f * ( i_end - i_start )) / p_sys->i_ssnd_fsize;
+ uint64_t i_new = i_start + i_frame * p_sys->i_ssnd_fsize;
if( vlc_stream_Seek( p_demux->s, i_new ) )
{
return VLC_EGENERIC;
}
- p_sys->i_time = vlc_tick_from_samples( i_frame, p_sys->fmt.audio.i_rate );
+ p_sys->i_time = vlc_tick_from_samples( i_frame, p_sys->i_rate );
return VLC_SUCCESS;
}
return VLC_EGENERIC;
@@ -446,12 +458,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_GET_LENGTH:
{
- int64_t i_end = p_sys->i_ssnd_end > 0 ? p_sys->i_ssnd_end : stream_Size( p_demux->s );
+ uint64_t i_end = p_sys->i_ssnd_end != 0 ? p_sys->i_ssnd_end : stream_Size( p_demux->s );
if( p_sys->i_ssnd_start < i_end )
{
*va_arg( args, vlc_tick_t * ) =
- vlc_tick_from_samples( i_end - p_sys->i_ssnd_start, p_sys->i_ssnd_fsize) / p_sys->fmt.audio.i_rate;
+ vlc_tick_from_samples( i_end - p_sys->i_ssnd_start, p_sys->i_ssnd_fsize) / p_sys->i_rate;
return VLC_SUCCESS;
}
return VLC_EGENERIC;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fbf2e13f58a8e75bc987c502041f3772d896bd6a...6a485a2425e335eefd1648d75ef13356afb2ab7b
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fbf2e13f58a8e75bc987c502041f3772d896bd6a...6a485a2425e335eefd1648d75ef13356afb2ab7b
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the vlc-commits
mailing list