MediaArea / MediaInfoLib

Convenient unified display of the most relevant technical and tag data for video and audio files.
https://mediaarea.net/MediaInfo
BSD 2-Clause "Simplified" License
638 stars 177 forks source link

Avoid crash in mxf assets on unsupported audio #2096

Closed aipsvrr closed 3 months ago

JeromeMartinez commented 4 months ago

Could you share a file demonstrating this issue?

aipsvrr commented 4 months ago

Hi @JeromeMartinez , I need some time to get an asset (will try update later on if you would still want to have that). But for now, I'd like to add some details :) Here is a crash stack: `Program terminated with signal 11, Segmentation fault.

0 0x00007daf6a1e579f in MediaInfoLib::File_ChannelSplitting::Read_Buffer_Continue() () from /lib64/libmediainfo.so.0

1 0x00007daf6a08fb2e in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() () from /lib64/libmediainfo.so.0

2 0x00007daf6a090468 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) () from /lib64/libmediainfo.so.0

3 0x00007daf6a091f44 in MediaInfoLib::FileAnalyze::Open_Buffer_Continue(MediaInfoLib::FileAnalyze, unsigned char const, unsigned long, bool, double) () from /lib64/libmediainfo.so.0

4 0x00007daf6a56c827 in MediaInfoLib::File_Mxf::Data_Parse() () from /lib64/libmediainfo.so.0

5 0x00007daf6a08b1e7 in MediaInfoLib::File__Analyze::Data_Manage() () from /lib64/libmediainfo.so.0

6 0x00007daf6a08fa58 in MediaInfoLib::File__Analyze::Buffer_Parse() () from /lib64/libmediainfo.so.0

7 0x00007daf6a08fbf8 in MediaInfoLib::File__Analyze::Open_Buffer_Continue_Loop() () from /lib64/libmediainfo.so.0

8 0x00007daf6a090468 in MediaInfoLib::File__Analyze::Open_Buffer_Continue(unsigned char const*, unsigned long) () from /lib64/libmediainfo.so.0

9 0x00007daf6a141193 in MediaInfoLib::MediaInfo_Internal::Open_Buffer_Continue(unsigned char const*, unsigned long) () from /lib64/libmediainfo.so.0

10 0x00007daf6a5ceb41 in MediaInfoLib::Reader_File::Format_Test_PerParser_Continue(MediaInfoLib::MediaInfo_Internal*) () from /lib64/libmediainfo.so.0

11 0x00007daf6a5cd7a2 in MediaInfoLib::Reader_File::Format_Test_PerParser(MediaInfoLib::MediaInfo_Internal*, std::basic_string<wchar_t, std::char_traits, std::allocator > const&) () from /lib64/libmediainfo.so.0

12 0x00007daf6a5cdf68 in MediaInfoLib::Reader_File::Format_Test(MediaInfoLib::MediaInfo_Internal*, std::basic_string<wchar_t, std::char_traits, std::allocator >) ()

from /lib64/libmediainfo.so.0

13 0x00007daf6a1530b2 in MediaInfoLib::MediaInfo_Internal::Entry() () from /lib64/libmediainfo.so.0

14 0x00007daf6a14fa4c in MediaInfoLib::MediaInfo_Internal::Open(std::basic_string<wchar_t, std::char_traits, std::allocator > const&) () from /lib64/libmediainfo.so.0

15 0x00007daf6a157f28 in MediaInfoLib::MediaInfoList_Internal::Entry() () from /lib64/libmediainfo.so.0

16 0x00007daf6a15a8fa in MediaInfoLib::MediaInfoList_Internal::Open(std::basic_string<wchar_t, std::char_traits, std::allocator > const&, MediaInfoLib::fileoptions_t) ()

from /lib64/libmediainfo.so.0

17 0x0000000000402d26 in main ()`

The reason of that SEGFAULT is that Common is NULL. That happened because Common was not initialized in File_ChannelSplitting::Read_Buffer_Init() method due to wrong BitDepth that was calculated as 1 (BitDepth=3*8/16) because of improper BlockAlign value (BlockAlign=3 instead of 48) in WaveAudioEssenceDescriptor while ChannelsCount is 16 and QuantizationBits are 24. Well, I'm pretty sure that BlockAlign value was wrong in my test asset (I see that similar problems were already observed and Descriptor was fixed before for PCM parser). But mediainfo crash even on "non-well formed" file is not something that we expect :(

Descriptor's (BlockAlign) Fix was not working in my case because BlockAlign was fixed after Parser->BitDepth was already calculated to 1 for ChannelSplitting parser. Btw, I tried to apply this fix earlier in code and it works then.

By summarizing all above, two things were spotted: 1) Mediainfo can mitigate influence of potentially incorrect BlockAlign descriptor for its analysis but it depends on descriptor's sequence (if ChooseParser_Pcm would be called before ChooseParser_ChannelSplitting then no problems would be observed) 2) ChannelSplitting Parser can stay uninitialized if audio is not supported but still can be called and so segfault is possible in this case (no check on null pointer is performing in Read_Buffer_Continue())

Hope you will find my description useful. Thanks!

aipsvrr commented 3 months ago

Hi @JeromeMartinez , Returning back to you with approx. 8-seconds long asset's fragment (splitted by 3 parts: part_1, part_2, part_3. Please check that md5sum of resulting file is: c15b109561ef9110ca4b4ed1b1c89937) demonstrating this issue. Thanks!

JeromeMartinez commented 3 months ago

But mediainfo crash even on "non-well formed" file is not something that we expect :(

We agree :)

Btw, I tried to apply this fix earlier in code and it works then.

I definitely need to refactor this code and avoid to rely much on BlockAlign, because the current code will not catch Dolby E in a file with wrong BlockAlign.

In the meantime, I take this "hot fix", thank you.