beardypig/pymp4

Large size not handled

Opened this issue · 1 comments

ptpt commented

According to the spec:

size: is an integer that specifies the number of bytes in this box, including all its fields and contained
boxes; if size is 1 then the actual size is in the field largesize; if size is 0, then this box is the last
one in the file, and its contents extend to the end of the file (normally only used for a Media Data Box)

I don't see pymp4 handles the largesize.

ptpt commented

Just verified that it crashed on a 4-GB mp4 file:

mp4dump ~/Downloads/LARGE_VIDEO.mp4
Container:
    offset = 0
    type = b'ftyp' (total 4)
    major_brand = b'isom' (total 4)
    minor_version = 512
    compatible_brands = ListContainer:
        b'isom'
        b'iso2'
        b'avc1'
        b'mp41'
    end = 32
Traceback (most recent call last):
  File "/python3.7/site-packages/construct/core.py", line 1670, in _parse
    return self.subcon._parse(stream, context, path)
  File "/python3.7/site-packages/construct/core.py", line 313, in _parse
    return self._decode(self.subcon._parse(stream, context, path), context)
  File "/python3.7/site-packages/construct/core.py", line 313, in _parse
    return self._decode(self.subcon._parse(stream, context, path), context)
  File "/python3.7/site-packages/construct/core.py", line 397, in _parse
    return _read_stream(stream, length)
  File "/python3.7/site-packages/construct/core.py", line 71, in _read_stream
    data = stream.read(length)
  File "/python3.7/site-packages/construct/lib/bitstream.py", line 156, in read
    data = self.substream.read(count)
ValueError: read length must be non-negative or -1

The mdat box size is 4316956137 which exceeding max uint32 (4294967295). It's therefore stored in the size64 field that follows the box type.

See the spec:

1, which means that the actual size is given in the extended size field, an optional 64-bit field that follows the type field.
This accommodates media data atoms that contain more than 2^32 bytes.