[vlc-devel] [PATCH] asf: fix error handling in codec_list
RĂ©mi Denis-Courmont
remi at remlab.net
Sat Nov 11 14:45:23 CET 2017
Use a linked list rather than a large table, and actually handle errors
as errors.
---
modules/demux/asf/libasf.c | 125 ++++++++++++++++++++++-----------------------
modules/demux/asf/libasf.h | 7 +--
2 files changed, 66 insertions(+), 66 deletions(-)
diff --git a/modules/demux/asf/libasf.c b/modules/demux/asf/libasf.c
index edcfcde9df..b115ddb84f 100644
--- a/modules/demux/asf/libasf.c
+++ b/modules/demux/asf/libasf.c
@@ -629,6 +629,21 @@ static void ASF_FreeObject_stream_properties( asf_object_t *p_obj )
FREENULL( p_sp->p_error_correction_data );
}
+static void ASF_FreeObject_codec_list( asf_object_t *p_obj )
+{
+ asf_object_codec_list_t *p_cl = &p_obj->codec_list;
+
+ for( asf_codec_entry_t *codec = p_cl->codecs, *next;
+ codec != NULL;
+ codec = next )
+ {
+ next = codec->p_next;
+ free( codec->psz_name );
+ free( codec->psz_description );
+ free( codec->p_information );
+ free( codec );
+ }
+}
static int ASF_ReadObject_codec_list( stream_t *s, asf_object_t *p_obj )
{
@@ -636,92 +651,76 @@ static int ASF_ReadObject_codec_list( stream_t *s, asf_object_t *p_obj )
ssize_t i_peek;
const uint8_t *p_peek, *p_data;
- uint32_t i_codec;
-
if( ( i_peek = vlc_stream_Peek( s, &p_peek, p_cl->i_object_size ) ) < 44 )
return VLC_EGENERIC;
ASF_GetGUID( &p_cl->i_reserved, p_peek + ASF_OBJECT_COMMON_SIZE );
- p_cl->i_codec_entries_count = GetDWLE( p_peek + 40 );
+ uint32_t count = GetDWLE( p_peek + 40 );
+#ifdef ASF_DEBUG
+ msg_Dbg( s, "read \"codec list object\" reserved_guid:" GUID_FMT
+ " codec_entries_count:%d", GUID_PRINT( p_cl->i_reserved ),
+ count );
+#endif
p_data = p_peek + 44;
- if( p_cl->i_codec_entries_count > 0 )
+ asf_codec_entry_t **pp = &p_cl->codecs;
+
+ for( uint32_t i = 0; i < count; i++ )
{
- p_cl->codec = calloc( p_cl->i_codec_entries_count,
- sizeof( asf_codec_entry_t ) );
- if( !p_cl->codec )
- return VLC_ENOMEM;
+ asf_codec_entry_t *p_codec = malloc( sizeof( *p_codec ) );
- for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )
+ if( unlikely(p_codec == NULL) || !ASF_HAVE( 2+2+2 ) )
{
- asf_codec_entry_t *p_codec = &p_cl->codec[i_codec];
-
- if( !ASF_HAVE( 2+2+2 ) )
- break;
+ free( p_codec );
+ *pp = NULL;
+ goto error;
+ }
- /* */
- p_codec->i_type = ASF_READ2();
+ /* */
+ p_codec->i_type = ASF_READ2();
- /* XXX the length here are the number of *unicode* characters and
- * not of bytes like nearly every elsewhere */
+ /* XXX the length here are the number of *unicode* characters and
+ * not of bytes like nearly every elsewhere */
- /* codec name */
- p_codec->psz_name = ASF_READS( 2*ASF_READ2() );
+ /* codec name */
+ p_codec->psz_name = ASF_READS( 2*ASF_READ2() );
- /* description */
- p_codec->psz_description = ASF_READS( 2*ASF_READ2() );
+ /* description */
+ p_codec->psz_description = ASF_READS( 2*ASF_READ2() );
- /* opaque information */
- p_codec->i_information_length = ASF_READ2();
- if( p_codec->i_information_length > 0 && ASF_HAVE( p_codec->i_information_length ) )
- {
- p_codec->p_information = malloc( p_codec->i_information_length );
- if( p_codec->p_information )
- memcpy( p_codec->p_information, p_data, p_codec->i_information_length );
- else
- p_codec->i_information_length = 0;
- p_data += p_codec->i_information_length;
- }
+ /* opaque information */
+ p_codec->i_information_length = ASF_READ2();
+ if( ASF_HAVE( p_codec->i_information_length ) )
+ {
+ p_codec->p_information = malloc( p_codec->i_information_length );
+ if( unlikely(p_codec->p_information == NULL
+ && p_codec->i_information_length > 0) )
+ goto error;
+
+ memcpy( p_codec->p_information, p_data,
+ p_codec->i_information_length );
+ p_data += p_codec->i_information_length;
}
- p_cl->i_codec_entries_count = i_codec;
- }
#ifdef ASF_DEBUG
- msg_Dbg( s, "read \"codec list object\" reserved_guid:" GUID_FMT
- " codec_entries_count:%d",
- GUID_PRINT( p_cl->i_reserved ), p_cl->i_codec_entries_count );
-
- for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )
- {
- const asf_codec_entry_t *p_codec = &p_cl->codec[i_codec];
-
msg_Dbg( s, " - codec[%"PRIu32"] %s name:\"%s\" "
- "description:\"%s\" information_length:%u",
- i_codec, ( p_codec->i_type == ASF_CODEC_TYPE_VIDEO ) ?
- "video" : ( ( p_codec->i_type == ASF_CODEC_TYPE_AUDIO ) ?
- "audio" : "unknown" ),
- p_codec->psz_name, p_codec->psz_description,
- p_codec->i_information_length );
- }
+ "description:\"%s\" information_length:%u", i,
+ ( p_codec->i_type == ASF_CODEC_TYPE_VIDEO ) ? "video"
+ : ( ( p_codec->i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio"
+ : "unknown" ), p_codec->psz_name,
+ p_codec->psz_description, p_codec->i_information_length );
#endif
+ *pp = p_codec;
+ pp = &p_codec->p_next;
+ }
+ *pp = NULL;
return VLC_SUCCESS;
-}
-
-static void ASF_FreeObject_codec_list( asf_object_t *p_obj )
-{
- asf_object_codec_list_t *p_cl = &p_obj->codec_list;
-
- for( uint32_t i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )
- {
- asf_codec_entry_t *p_codec = &p_cl->codec[i_codec];
- FREENULL( p_codec->psz_name );
- FREENULL( p_codec->psz_description );
- FREENULL( p_codec->p_information );
- }
- FREENULL( p_cl->codec );
+error:
+ ASF_FreeObject_codec_list( p_obj );
+ return VLC_EGENERIC;
}
static inline char *get_wstring( const uint8_t *p_data, size_t i_size )
diff --git a/modules/demux/asf/libasf.h b/modules/demux/asf/libasf.h
index b6079eb5da..c483b5f28b 100644
--- a/modules/demux/asf/libasf.h
+++ b/modules/demux/asf/libasf.h
@@ -189,7 +189,7 @@ typedef struct
#define ASF_CODEC_TYPE_AUDIO 0x0002
#define ASF_CODEC_TYPE_UNKNOWN 0xffff
-typedef struct
+typedef struct asf_codec_entry
{
uint16_t i_type;
char *psz_name;
@@ -197,14 +197,15 @@ typedef struct
uint16_t i_information_length;
uint8_t *p_information;
+
+ struct asf_codec_entry *p_next;
} asf_codec_entry_t;
typedef struct
{
ASF_OBJECT_COMMON
guid_t i_reserved;
- uint32_t i_codec_entries_count;
- asf_codec_entry_t *codec;
+ asf_codec_entry_t *codecs;
} asf_object_codec_list_t;
--
2.15.0
More information about the vlc-devel
mailing list