Code like this will cause segfault for some inputs with corrupted or invalid streams:
import av
container = av.open("input.m2ts", "r") # for certain input files
stream = container.streams[1] # select the corrupted stream
print(stream.type) # segfault here
This happens when the stream is corrupted so a general Stream rather than specific stream like VideoStream is created. So the type property invokes:
# av/stream.py
@cython.cclass
class Stream:
...
@property
def type(self):
"""
The type of the stream.
:type: Literal["audio", "video", "subtitle", "data", "attachment"]
"""
return lib.av_get_media_type_string(self.ptr.codecpar.codec_type)
The underlying av_get_media_type_string function may return NULL for unknown AVMediaType:
// FFmpeg/libavutil/utils.c
const char *av_get_media_type_string(enum AVMediaType media_type)
{
switch (media_type) {
case AVMEDIA_TYPE_VIDEO: return "video";
case AVMEDIA_TYPE_AUDIO: return "audio";
case AVMEDIA_TYPE_DATA: return "data";
case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
default: return NULL;
}
}
When NULL is returned, a segfault will be triggered since Cython converts the returned const char * to a Python string without checking for NULL.
Code like this will cause segfault for some inputs with corrupted or invalid streams:
This happens when the stream is corrupted so a general
Streamrather than specific stream likeVideoStreamis created. So thetypeproperty invokes:The underlying
av_get_media_type_stringfunction may returnNULLfor unknownAVMediaType:When
NULLis returned, a segfault will be triggered since Cython converts the returnedconst char *to a Python string without checking forNULL.