[vlc-commits] demux: libmp4: always check meta atom header
Francois Cartegnie
git at videolan.org
Mon Sep 5 10:36:30 CEST 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Sep 5 09:42:58 2016 +0200| [7f70e1cd7e6b1a7223c45f30d5e1d4b5fe6ee6b8] | committer: Francois Cartegnie
demux: libmp4: always check meta atom header
As in qtff && iso specs, should always be w/header.
Some incorrect meta atoms have none.
Simplifies both cases.
refs MP4-Tags-Sample.mp4, 6_Channel_ID.mov
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7f70e1cd7e6b1a7223c45f30d5e1d4b5fe6ee6b8
---
modules/demux/mp4/libmp4.c | 47 +++++++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 17 deletions(-)
diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 807680e..ad8fdfe 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -3558,40 +3558,53 @@ static int MP4_ReadBox_colr( stream_t *p_stream, MP4_Box_t *p_box )
static int MP4_ReadBox_meta( stream_t *p_stream, MP4_Box_t *p_box )
{
- uint8_t meta_data[8];
- int i_actually_read;
+ const uint8_t *p_peek;
const size_t i_headersize = mp4_box_headersize( p_box );
- if( p_box->i_size < 8 || p_box->i_size - i_headersize < 4 )
+ if( p_box->i_size < 16 || p_box->i_size - i_headersize < 8 )
+ return 0;
+
+ /* skip over box header */
+ if( vlc_stream_Read( p_stream, NULL, i_headersize ) < (ssize_t) i_headersize )
return 0;
- // skip over box header
- i_actually_read = vlc_stream_Read( p_stream, meta_data, i_headersize );
- if( i_actually_read < i_headersize )
+ /* meta content starts with a 4 byte version/flags value (should be 0) */
+ if( vlc_stream_Peek( p_stream, &p_peek, 8 ) < 8 )
return 0;
- if ( p_box->p_father && p_box->p_father->i_type == ATOM_udta ) /* itunes udta/meta */
+ if( !memcmp( p_peek, "\0\0\0", 4 ) ) /* correct header case */
{
- /* meta content starts with a 4 byte version/flags value (should be 0) */
- i_actually_read = vlc_stream_Read( p_stream, meta_data, 4 );
- if( i_actually_read < 4 || memcmp( meta_data, "\0\0\0", 4 ) )
+ if( vlc_stream_Read( p_stream, NULL, 4 ) < 4 )
return 0;
}
+ else if( memcmp( &p_peek[4], "hdlr", 4 ) ) /* Broken, headerless ones */
+ {
+ return 0;
+ }
+ /* load child atoms up to the handler (which should be next anyway) */
const uint32_t stoplist[] = { ATOM_hdlr, 0 };
if ( !MP4_ReadBoxContainerChildren( p_stream, p_box, stoplist ) )
return 0;
/* Mandatory */
const MP4_Box_t *p_hdlr = MP4_BoxGet( p_box, "hdlr" );
- if ( !p_hdlr || !BOXDATA(p_hdlr) ||
- ( BOXDATA(p_hdlr)->i_handler_type != HANDLER_mdta &&
- BOXDATA(p_hdlr)->i_handler_type != HANDLER_mdir ) ||
- BOXDATA(p_hdlr)->i_version != 0 )
- return 0;
+ if ( p_hdlr && BOXDATA(p_hdlr) && BOXDATA(p_hdlr)->i_version == 0 )
+ {
+ p_box->i_handler = BOXDATA(p_hdlr)->i_handler_type;
+ switch( p_box->i_handler )
+ {
+ case HANDLER_mdta:
+ case HANDLER_mdir:
+ /* then it behaves like a container */
+ return MP4_ReadBoxContainerChildren( p_stream, p_box, NULL );
+ default:
+ /* skip parsing, will be seen as empty container */
+ break;
+ }
+ }
- /* then it behaves like a container */
- return MP4_ReadBoxContainerChildren( p_stream, p_box, NULL );
+ return 1;
}
static int MP4_ReadBox_iods( stream_t *p_stream, MP4_Box_t *p_box )
More information about the vlc-commits
mailing list