Commit 55d4d471 authored by Denis Charmet's avatar Denis Charmet

Add try/catch when reading elements with libmatroska.

(cherry picked from commit 59c9e8309d5b435a2d85c2c9eaae979ba56ccdd9)

Conflicts:
	modules/demux/mkv/matroska_segment.cpp
parent 94afe341
...@@ -462,16 +462,24 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS ...@@ -462,16 +462,24 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS
EbmlElement *p_l0, *p_l1, *p_l2; EbmlElement *p_l0, *p_l1, *p_l2;
bool b_keep_stream = false, b_keep_segment = false; bool b_keep_stream = false, b_keep_segment = false;
// verify the EBML Header /* verify the EBML Header... it shouldn't be bigger than 1kB */
p_l0 = p_estream->FindNextID(EBML_INFO(EbmlHead), UINT64_MAX); p_l0 = p_estream->FindNextID(EBML_INFO(EbmlHead), 1024);
if (p_l0 == NULL) if (p_l0 == NULL)
{ {
msg_Err( p_demux, "No EBML header found" ); msg_Err( p_demux, "No EBML header found" );
return NULL; return NULL;
} }
// verify we can read this Segment, we only support Matroska version 1 for now /* verify we can read this Segment */
p_l0->Read(*p_estream, EBML_CLASS_CONTEXT(EbmlHead), i_upper_lvl, p_l0, true); try
{
p_l0->Read(*p_estream, EBML_CLASS_CONTEXT(EbmlHead), i_upper_lvl, p_l0, true);
}
catch(...)
{
msg_Err(p_demux, "EBML Header Read failed");
return NULL;
}
EDocType doc_type = GetChild<EDocType>(*static_cast<EbmlHead*>(p_l0)); EDocType doc_type = GetChild<EDocType>(*static_cast<EbmlHead*>(p_l0));
if (std::string(doc_type) != "matroska" && std::string(doc_type) != "webm" ) if (std::string(doc_type) != "matroska" && std::string(doc_type) != "webm" )
...@@ -517,8 +525,15 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS ...@@ -517,8 +525,15 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS
// find the families of this segment // find the families of this segment
KaxInfo *p_info = static_cast<KaxInfo*>(p_l1); KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
b_keep_segment = b_initial; b_keep_segment = b_initial;
try
p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true); {
p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true);
}
catch (...)
{
msg_Err( p_demux, "KaxInfo found but corrupted");
break;
}
for( size_t i = 0; i < p_info->ListSize(); i++ ) for( size_t i = 0; i < p_info->ListSize(); i++ )
{ {
EbmlElement *l = (*p_info)[i]; EbmlElement *l = (*p_info)[i];
......
...@@ -120,6 +120,7 @@ matroska_segment_c::~matroska_segment_c() ...@@ -120,6 +120,7 @@ matroska_segment_c::~matroska_segment_c()
*****************************************************************************/ *****************************************************************************/
void matroska_segment_c::LoadCues( KaxCues *cues ) void matroska_segment_c::LoadCues( KaxCues *cues )
{ {
bool b_invalid_cue;
EbmlParser *ep; EbmlParser *ep;
EbmlElement *el; EbmlElement *el;
...@@ -134,6 +135,7 @@ void matroska_segment_c::LoadCues( KaxCues *cues ) ...@@ -134,6 +135,7 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
{ {
if( MKV_IS_ID( el, KaxCuePoint ) ) if( MKV_IS_ID( el, KaxCuePoint ) )
{ {
b_invalid_cue = false;
#define idx p_indexes[i_index] #define idx p_indexes[i_index]
idx.i_track = -1; idx.i_track = -1;
...@@ -148,42 +150,59 @@ void matroska_segment_c::LoadCues( KaxCues *cues ) ...@@ -148,42 +150,59 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
if( MKV_IS_ID( el, KaxCueTime ) ) if( MKV_IS_ID( el, KaxCueTime ) )
{ {
KaxCueTime &ctime = *(KaxCueTime*)el; KaxCueTime &ctime = *(KaxCueTime*)el;
try
ctime.ReadData( es.I_O() ); {
ctime.ReadData( es.I_O() );
}
catch(...)
{
msg_Err( &sys.demuxer, "Error while reading CueTime" );
b_invalid_cue = true;
break;
}
idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000; idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
} }
else if( MKV_IS_ID( el, KaxCueTrackPositions ) ) else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
{ {
ep->Down(); ep->Down();
while( ( el = ep->Get() ) != NULL ) try
{ {
if( MKV_IS_ID( el, KaxCueTrack ) ) while( ( el = ep->Get() ) != NULL )
{
KaxCueTrack &ctrack = *(KaxCueTrack*)el;
ctrack.ReadData( es.I_O() );
idx.i_track = uint16( ctrack );
}
else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
{
KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
ccpos.ReadData( es.I_O() );
idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
}
else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
{ {
KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el; if( MKV_IS_ID( el, KaxCueTrack ) )
{
cbnum.ReadData( es.I_O() ); KaxCueTrack &ctrack = *(KaxCueTrack*)el;
idx.i_block_number = uint32( cbnum );
} ctrack.ReadData( es.I_O() );
else idx.i_track = uint16( ctrack );
{ }
msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() ); else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
{
KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
ccpos.ReadData( es.I_O() );
idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
}
else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
{
KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
cbnum.ReadData( es.I_O() );
idx.i_block_number = uint32( cbnum );
}
else
{
msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
}
} }
} }
catch(...)
{
ep->Up();
msg_Err( &sys.demuxer, "Error while reading %s", typeid(*el).name() );
b_invalid_cue = true;
break;
}
ep->Up(); ep->Up();
} }
else else
...@@ -198,13 +217,15 @@ void matroska_segment_c::LoadCues( KaxCues *cues ) ...@@ -198,13 +217,15 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
" track=%d bnum=%d", idx.i_time, idx.i_position, " track=%d bnum=%d", idx.i_time, idx.i_position,
idx.i_track, idx.i_block_number ); idx.i_track, idx.i_block_number );
#endif #endif
if( likely( !b_invalid_cue ) )
i_index++;
if( i_index >= i_index_max )
{ {
i_index_max += 1024; i_index++;
p_indexes = (mkv_index_t*)xrealloc( p_indexes, if( i_index >= i_index_max )
sizeof( mkv_index_t ) * i_index_max ); {
i_index_max += 1024;
p_indexes = (mkv_index_t*)xrealloc( p_indexes,
sizeof( mkv_index_t ) * i_index_max );
}
} }
#undef idx #undef idx
} }
...@@ -254,21 +275,32 @@ void matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag ) ...@@ -254,21 +275,32 @@ void matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag )
sys.meta = vlc_meta_New(); sys.meta = vlc_meta_New();
msg_Dbg( &sys.demuxer, "| + Simple Tag "); msg_Dbg( &sys.demuxer, "| + Simple Tag ");
while( ( el = ep->Get() ) != NULL ) try
{ {
if( MKV_IS_ID( el, KaxTagName ) ) while( ( el = ep->Get() ) != NULL )
{
KaxTagName &key = *(KaxTagName*)el;
key.ReadData( es.I_O(), SCOPE_ALL_DATA );
k = strdup( UTFstring( key ).GetUTF8().c_str() );
}
if( MKV_IS_ID( el, KaxTagString ) )
{ {
KaxTagString &value = *(KaxTagString*)el; if( MKV_IS_ID( el, KaxTagName ) )
value.ReadData( es.I_O(), SCOPE_ALL_DATA ); {
v = strdup( UTFstring( value ).GetUTF8().c_str() ); KaxTagName &key = *(KaxTagName*)el;
key.ReadData( es.I_O(), SCOPE_ALL_DATA );
k = strdup( UTFstring( key ).GetUTF8().c_str() );
}
else if( MKV_IS_ID( el, KaxTagString ) )
{
KaxTagString &value = *(KaxTagString*)el;
value.ReadData( es.I_O(), SCOPE_ALL_DATA );
v = strdup( UTFstring( value ).GetUTF8().c_str() );
}
} }
} }
catch(...)
{
msg_Err( &sys.demuxer, "Error while reading Tag ");
free(k);
free(v);
delete ep;
return;
}
delete ep; delete ep;
if( !k || !v ) if( !k || !v )
...@@ -1502,109 +1534,117 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s ...@@ -1502,109 +1534,117 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
} }
/* do parsing */ /* do parsing */
switch ( i_level ) try
{ {
case 1: switch ( i_level )
if( MKV_IS_ID( el, KaxCluster ) )
{ {
cluster = (KaxCluster*)el; case 1:
i_cluster_pos = cluster->GetElementPosition(); if( MKV_IS_ID( el, KaxCluster ) )
{
cluster = (KaxCluster*)el;
i_cluster_pos = cluster->GetElementPosition();
// reset silent tracks // reset silent tracks
for (size_t i=0; i<tracks.size(); i++) for (size_t i=0; i<tracks.size(); i++)
{ {
tracks[i]->b_silent = false; tracks[i]->b_silent = false;
} }
ep->Down(); ep->Down();
} }
else if( MKV_IS_ID( el, KaxCues ) ) else if( MKV_IS_ID( el, KaxCues ) )
{ {
msg_Warn( &sys.demuxer, "find KaxCues FIXME" ); msg_Warn( &sys.demuxer, "find KaxCues FIXME" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
else else
{ {
msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() ); msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );
} }
break; break;
case 2: case 2:
if( MKV_IS_ID( el, KaxClusterTimecode ) ) if( MKV_IS_ID( el, KaxClusterTimecode ) )
{ {
KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el; KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
ctc.ReadData( es.I_O(), SCOPE_ALL_DATA ); ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );
cluster->InitTimecode( uint64( ctc ), i_timescale ); cluster->InitTimecode( uint64( ctc ), i_timescale );
/* add it to the index */
if( i_index == 0 ||
( i_index > 0 &&
p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
IndexAppendCluster( cluster );
}
else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
{
ep->Down();
}
else if( MKV_IS_ID( el, KaxBlockGroup ) )
{
i_block_pos = el->GetElementPosition();
ep->Down();
}
else if( MKV_IS_ID( el, KaxSimpleBlock ) )
{
pp_simpleblock = (KaxSimpleBlock*)el;
pp_simpleblock->ReadData( es.I_O() ); /* add it to the index */
pp_simpleblock->SetParent( *cluster ); if( i_index == 0 ||
} ( i_index > 0 &&
break; p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
case 3: IndexAppendCluster( cluster );
if( MKV_IS_ID( el, KaxBlock ) ) }
{ else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
pp_block = (KaxBlock*)el; {
ep->Down();
}
else if( MKV_IS_ID( el, KaxBlockGroup ) )
{
i_block_pos = el->GetElementPosition();
ep->Down();
}
else if( MKV_IS_ID( el, KaxSimpleBlock ) )
{
pp_simpleblock = (KaxSimpleBlock*)el;
pp_block->ReadData( es.I_O() ); pp_simpleblock->ReadData( es.I_O() );
pp_block->SetParent( *cluster ); pp_simpleblock->SetParent( *cluster );
}
break;
case 3:
if( MKV_IS_ID( el, KaxBlock ) )
{
pp_block = (KaxBlock*)el;
ep->Keep(); pp_block->ReadData( es.I_O() );
} pp_block->SetParent( *cluster );
else if( MKV_IS_ID( el, KaxBlockDuration ) )
{
KaxBlockDuration &dur = *(KaxBlockDuration*)el;
dur.ReadData( es.I_O() ); ep->Keep();
*pi_duration = uint64( dur ); }
} else if( MKV_IS_ID( el, KaxBlockDuration ) )
else if( MKV_IS_ID( el, KaxReferenceBlock ) ) {
{ KaxBlockDuration &dur = *(KaxBlockDuration*)el;
KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
ref.ReadData( es.I_O() ); dur.ReadData( es.I_O() );
*pi_duration = uint64( dur );
}
else if( MKV_IS_ID( el, KaxReferenceBlock ) )
{
KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
if( *pb_key_picture ) ref.ReadData( es.I_O() );
*pb_key_picture = false;
else if( int64( ref ) > 0 ) if( *pb_key_picture )
*pb_discardable_picture = true; *pb_key_picture = false;
} else if( int64( ref ) > 0 )
else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) ) *pb_discardable_picture = true;
{ }
KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el; else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
track_num.ReadData( es.I_O() );
// find the track
for (size_t i=0; i<tracks.size(); i++)
{
if ( tracks[i]->i_number == uint32(track_num))
{ {
tracks[i]->b_silent = true; KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;
break; track_num.ReadData( es.I_O() );
// find the track
for (size_t i=0; i<tracks.size(); i++)
{
if ( tracks[i]->i_number == uint32(track_num))
{
tracks[i]->b_silent = true;
break;
}
}
} }
} break;
default:
msg_Err( &sys.demuxer, "invalid level = %d", i_level );
return VLC_EGENERIC;
} }
break; }
default: catch(...)
msg_Err( &sys.demuxer, "invalid level = %d", i_level ); {
return VLC_EGENERIC; msg_Err( &sys.demuxer, "Error while reading %s... upping level", typeid(*el).name());
ep->Up();
} }
} }
} }
......
...@@ -66,26 +66,33 @@ void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead ) ...@@ -66,26 +66,33 @@ void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead )
msg_Dbg( &sys.demuxer, "| | + Seek" ); msg_Dbg( &sys.demuxer, "| | + Seek" );
#endif #endif
ep->Down(); ep->Down();
while( ( l = ep->Get() ) != NULL ) try
{ {
if( MKV_IS_ID( l, KaxSeekID ) ) while( ( l = ep->Get() ) != NULL )
{ {
KaxSeekID &sid = *(KaxSeekID*)l; if( MKV_IS_ID( l, KaxSeekID ) )
sid.ReadData( es.I_O() ); {
id = EbmlId( sid.GetBuffer(), sid.GetSize() ); KaxSeekID &sid = *(KaxSeekID*)l;
} sid.ReadData( es.I_O() );
else if( MKV_IS_ID( l, KaxSeekPosition ) ) id = EbmlId( sid.GetBuffer(), sid.GetSize() );
{ }
KaxSeekPosition &spos = *(KaxSeekPosition*)l; else if( MKV_IS_ID( l, KaxSeekPosition ) )
spos.ReadData( es.I_O() ); {
i_pos = (int64_t)segment->GetGlobalPosition( uint64( spos ) ); KaxSeekPosition &spos = *(KaxSeekPosition*)l;
} spos.ReadData( es.I_O() );
else i_pos = (int64_t)segment->GetGlobalPosition( uint64( spos ) );
{ }
/* Many mkvmerge files hit this case. It seems to be a broken SeekHead */ else
msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid(*l).name() ); {
/* Many mkvmerge files hit this case. It seems to be a broken SeekHead */
msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid(*l).name() );
}
} }
} }
catch(...)
{
msg_Err( &sys.demuxer,"Error while reading %s", typeid(*l).name() );
}
ep->Up(); ep->Up();
if( i_pos >= 0 ) if( i_pos >= 0 )
...@@ -668,7 +675,15 @@ void matroska_segment_c::ParseTracks( KaxTracks *tracks ) ...@@ -668,7 +675,15 @@ void matroska_segment_c::ParseTracks( KaxTracks *tracks )
int i_upper_level = 0; int i_upper_level = 0;
/* Master elements */ /* Master elements */
tracks->Read( es, EBML_CONTEXT(tracks), i_upper_level, el, true ); try
{
tracks->Read( es, EBML_CONTEXT(tracks), i_upper_level, el, true );
}
catch(...)
{
msg_Err( &sys.demuxer, "Couldn't read tracks" );
return;
}
for( size_t i = 0; i < tracks->ListSize(); i++ ) for( size_t i = 0; i < tracks->ListSize(); i++ )
{ {
...@@ -696,7 +711,15 @@ void matroska_segment_c::ParseInfo( KaxInfo *info ) ...@@ -696,7 +711,15 @@ void matroska_segment_c::ParseInfo( KaxInfo *info )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>(info); m = static_cast<EbmlMaster *>(info);
m->Read( es, EBML_CONTEXT(info), i_upper_level, el, true ); try
{
m->Read( es, EBML_CONTEXT(info), i_upper_level, el, true );
}
catch(...)
{
msg_Err( &sys.demuxer, "Couldn't read info" );
return;
}
for( size_t i = 0; i < m->ListSize(); i++ ) for( size_t i = 0; i < m->ListSize(); i++ )
{ {
...@@ -809,28 +832,35 @@ void matroska_segment_c::ParseInfo( KaxInfo *info ) ...@@ -809,28 +832,35 @@ void matroska_segment_c::ParseInfo( KaxInfo *info )
else if( MKV_IS_ID( l, KaxChapterTranslate ) ) else if( MKV_IS_ID( l, KaxChapterTranslate ) )
{ {
KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l ); KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l );
chapter_translation_c *p_translate = new chapter_translation_c(); try
p_trans->Read( es, EBML_CONTEXT(p_trans), i_upper_level, el, true );
for( size_t j = 0; j < p_trans->ListSize(); j++ )
{ {
EbmlElement *l = (*p_trans)[j]; p_trans->Read( es, EBML_CONTEXT(p_trans), i_upper_level, el, true );
chapter_translation_c *p_translate = new chapter_translation_c();
if( MKV_IS_ID( l, KaxChapterTranslateEditionUID ) ) for( size_t j = 0; j < p_trans->ListSize(); j++ )
{
p_translate->editions.push_back( uint64( *static_cast<KaxChapterTranslateEditionUID*>( l ) ) );
}
else if( MKV_IS_ID( l, KaxChapterTranslateCodec ) )
{
p_translate->codec_id = uint32( *static_cast<KaxChapterTranslateCodec*>( l ) );
}
else if( MKV_IS_ID( l, KaxChapterTranslateID ) )
{ {
p_translate->p_translated = new KaxChapterTranslateID( *static_cast<KaxChapterTranslateID*>( l ) ); EbmlElement *l = (*p_trans)[j];
if( MKV_IS_ID( l, KaxChapterTranslateEditionUID ) )
{
p_translate->editions.push_back( uint64( *static_cast<KaxChapterTranslateEditionUID*>( l ) ) );
}
else if( MKV_IS_ID( l, KaxChapterTranslateCodec ) )
{
p_translate->codec_id = uint32( *static_cast<KaxChapterTranslateCodec*>( l ) );
}
else if( MKV_IS_ID( l, KaxChapterTranslateID ) )
{
p_translate->p_translated = new KaxChapterTranslateID( *static_cast<KaxChapterTranslateID*>( l ) );
}
} }
}
translations.push_back( p_translate ); translations.push_back( p_translate );
}
catch(...)
{
msg_Err( &sys.demuxer, "Error while reading Chapter Tranlate");
}
} }
else else
{ {
...@@ -994,7 +1024,15 @@ void matroska_segment_c::ParseAttachments( KaxAttachments *attachments ) ...@@ -994,7 +1024,15 @@ void matroska_segment_c::ParseAttachments( KaxAttachments *attachments )
EbmlElement *el; EbmlElement *el;
int i_upper_level = 0; int i_upper_level = 0;
attachments->Read( es, EBML_CONTEXT(attachments), i_upper_level, el, true ); try
{
attachments->Read( es, EBML_CONTEXT(attachments), i_upper_level, el, true );
}
catch(...)
{
msg_Err( &sys.demuxer, "Error while reading attachments" );
return;
}
KaxAttached *attachedFile = FindChild<KaxAttached>( *attachments ); KaxAttached *attachedFile = FindChild<KaxAttached>( *attachments );
...@@ -1041,7 +1079,15 @@ void matroska_segment_c::ParseChapters( KaxChapters *chapters ) ...@@ -1041,7 +1079,15 @@ void matroska_segment_c::ParseChapters( KaxChapters *chapters )
int i_upper_level = 0; int i_upper_level = 0;
/* Master elements */ /* Master elements */
chapters->Read( es, EBML_CONTEXT(chapters), i_upper_level, el, true ); try
{
chapters->Read( es, EBML_CONTEXT(chapters), i_upper_level, el, true );
}
catch(...)
{
msg_Err( &sys.demuxer, "Error while reading chapters" );
return;
}
for( size_t i = 0; i < chapters->ListSize(); i++ ) for( size_t i = 0; i < chapters->ListSize(); i++ )
{ {
...@@ -1102,7 +1148,15 @@ void matroska_segment_c::ParseCluster( bool b_update_start_time ) ...@@ -1102,7 +1148,15 @@ void matroska_segment_c::ParseCluster( bool b_update_start_time )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>( cluster ); m = static_cast<EbmlMaster *>( cluster );
m->Read( es, EBML_CONTEXT(cluster), i_upper_level, el, true ); try
{
m->Read( es, EBML_CONTEXT(cluster), i_upper_level, el, true );
}
catch(...)
{
msg_Err( &sys.demuxer, "Error while reading cluster" );
return;
}
for( unsigned int i = 0; i < m->ListSize(); i++ ) for( unsigned int i = 0; i < m->ListSize(); i++ )
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment