97 lines
1.9 KiB
Python
97 lines
1.9 KiB
Python
import struct
|
|
import sys
|
|
|
|
stream = sys.stdin.buffer
|
|
offset = 0
|
|
box_index = 0
|
|
|
|
def read_exact(length):
|
|
data = bytearray()
|
|
|
|
while len(data) < length:
|
|
chunk = stream.read(length - len(data))
|
|
|
|
if not chunk:
|
|
return None
|
|
|
|
data.extend(chunk)
|
|
|
|
return bytes(data)
|
|
|
|
def discard(length):
|
|
remaining = length
|
|
|
|
while remaining > 0:
|
|
chunk = stream.read(min(1024 * 1024, remaining))
|
|
|
|
if not chunk:
|
|
return False
|
|
|
|
remaining -= len(chunk)
|
|
|
|
return True
|
|
|
|
while True:
|
|
header = read_exact(8)
|
|
|
|
if header is None:
|
|
break
|
|
|
|
size32, box_type_bytes = struct.unpack(">I4s", header)
|
|
box_type = box_type_bytes.decode("ascii", errors="replace")
|
|
header_size = 8
|
|
|
|
if size32 == 1:
|
|
extended = read_exact(8)
|
|
|
|
if extended is None:
|
|
print(f"ERROR truncated extended size at offset={offset}")
|
|
break
|
|
|
|
box_size = struct.unpack(">Q", extended)[0]
|
|
header_size = 16
|
|
elif size32 == 0:
|
|
print(
|
|
f"{box_index:04d} "
|
|
f"offset={offset} "
|
|
f"type={box_type} "
|
|
f"size=to-eof"
|
|
)
|
|
break
|
|
else:
|
|
box_size = size32
|
|
|
|
if box_size < header_size:
|
|
print(
|
|
f"ERROR invalid box "
|
|
f"offset={offset} "
|
|
f"type={box_type} "
|
|
f"size={box_size}"
|
|
)
|
|
break
|
|
|
|
box_end = offset + box_size
|
|
|
|
print(
|
|
f"{box_index:04d} "
|
|
f"offset={offset} "
|
|
f"type={box_type} "
|
|
f"size={box_size} "
|
|
f"end={box_end}"
|
|
)
|
|
|
|
payload_size = box_size - header_size
|
|
|
|
if not discard(payload_size):
|
|
print(
|
|
f"ERROR truncated payload "
|
|
f"offset={offset} "
|
|
f"type={box_type} "
|
|
f"expectedPayload={payload_size}"
|
|
)
|
|
break
|
|
|
|
offset = box_end
|
|
box_index += 1
|
|
|
|
print(f"END parsedBytes={offset} boxes={box_index}")
|