@@ -376,7 +376,7 @@ def parse_box_header(ps: Parser):
376376 start = ps .pos
377377 length = ps .int (4 )
378378 btype = ps .fourcc ()
379- assert btype .isprintable (), f'invalid type { repr (btype )} '
379+ assert btype .isprintable () or btype == ' \x00 \x00 \x00 \x00 ' , f'invalid type { repr (btype )} '
380380
381381 last_box , large_size = False , False
382382 if length == 0 :
@@ -395,7 +395,7 @@ def parse_box_header(ps: Parser):
395395def parse_boxes (ps : Parser , contents_fn : Optional [Callable [[str , Parser ], T ]]= None ) -> List [T ]:
396396 result = []
397397 with ps .in_list ():
398- while not ps .ended :
398+ while ps .remaining > 4 : # accept TerminatorBox but specifically avoid reading null trailers here
399399 with ps .in_list_item ():
400400 result .append (parse_box (ps , contents_fn or parse_contents ))
401401 return result
@@ -415,13 +415,15 @@ def parse_box(ps: Parser, contents_fn: Callable[[str, Parser], T]) -> T:
415415 if large_size :
416416 offset_text = ' (large size)' + offset_text
417417 type_label = btype
418- if len (btype ) != 4 : # it's a UUID
418+ if btype == '\x00 \x00 \x00 \x00 ' :
419+ type_label = '00 00 00 00'
420+ elif len (btype ) != 4 : # it's a UUID
419421 type_label = f'UUID { btype } '
420422 ps .print (ansi_bold (f'[{ type_label } ]' ) + name_text + offset_text + length_text , header = True )
421423 with ps .subparser (length ) as data , data .handle_errors ():
422424 return contents_fn (btype , data )
423425
424- nesting_boxes = { 'moov' , 'trak' , 'mdia' , 'minf' , 'dinf' , 'stbl' , 'mvex' , 'moof' , 'traf' , 'mfra' , 'meco' , 'edts' , 'udta' , 'sinf' , 'schi' , 'gmhd' , 'cmov' }
426+ nesting_boxes = { 'moov' , 'trak' , 'mdia' , 'minf' , 'dinf' , 'stbl' , 'mvex' , 'moof' , 'traf' , 'mfra' , 'meco' , 'edts' , 'udta' , 'sinf' , 'schi' , 'gmhd' , 'cmov' , 'wave' }
425427# metadata?
426428nesting_boxes |= { 'aART' , 'trkn' , 'covr' , '----' }
427429
0 commit comments