Ejemplo n.º 1
0
 def createFields(self):
     addr = self.absolute_address
     len = self.stream.searchBytesLength(':', False, addr,
                                         addr + (MAX_STRING_LENGTH + 1) * 8)
     if len is None:
         raise ParserError("Torrent: unable to find string separator (':')")
     if not len:
         raise ParserError("Torrent: error: no string length!")
     val = String(self, "length", len, "String length")
     yield val
     try:
         len = int(val.value)
     except ValueError:
         len = -1
     if len < 0:
         raise ParserError(
             "Invalid string length (%s)" %
             makePrintable(val.value, "ASCII", to_unicode=True))
     yield String(self, "separator", 1, "String length/value separator")
     if not len:
         self.info("Empty string: len=%i" % len)
         return
     if len < 512:
         yield String(self,
                      "value",
                      len,
                      "String value",
                      charset="ISO-8859-1")
     else:
         # Probably raw data
         yield RawBytes(self, "value", len, "Raw data")
Ejemplo n.º 2
0
 def createFields(self):
     yield String(self, "magic", 4)
     yield String(self, "version", 4, strip='\0')
     yield textHandler(UInt32(self, "checksum"), hexadecimal)
     yield RawBytes(self, "signature", 20, description="SHA1 sum over all subsequent data")
     yield filesizeHandler(UInt32(self, "filesize"))
     yield UInt32(self, "size", description="Header size")
     self._size = self['size'].value * 8
     yield textHandler(UInt32(self, "endian"), hexadecimal)
     yield UInt32(self, "link_count")
     yield UInt32(self, "link_offset")
     yield UInt32(self, "map_offset", description="offset to map footer")
     yield UInt32(self, "string_count", description="number of entries in string table")
     yield UInt32(self, "string_offset", description="offset to string table")
     yield UInt32(self, "type_desc_count", description="number of entries in type descriptor table")
     yield UInt32(self, "type_desc_offset", description="offset to type descriptor table")
     yield UInt32(self, "meth_desc_count", description="number of entries in method descriptor table")
     yield UInt32(self, "meth_desc_offset", description="offset to method descriptor table")
     yield UInt32(self, "field_count", description="number of entries in field table")
     yield UInt32(self, "field_offset", description="offset to field table")
     yield UInt32(self, "method_count", description="number of entries in method table")
     yield UInt32(self, "method_offset", description="offset to method table")
     yield UInt32(self, "class_count", description="number of entries in class table")
     yield UInt32(self, "class_offset", description="offset to class table")
     yield UInt32(self, "data_size", description="size of data region")
     yield UInt32(self, "data_offset", description="offset to data region")
Ejemplo n.º 3
0
    def createFields(self):
        yield ZipVersion(self, "version_made_by", "Version made by")
        # yield from ZipStartCommonFields(self)  # PY3
        for field in ZipStartCommonFields(self):
            yield field

        # Check unicode status
        charset = zipGetCharset(self)

        yield UInt16(self, "comment_length", "Comment length")
        yield UInt16(self, "disk_number_start", "Disk number start")
        yield UInt16(self, "internal_attr", "Internal file attributes")
        yield UInt32(self, "external_attr", "External file attributes")
        yield UInt32(self, "offset_header", "Relative offset of local header")
        yield String(self,
                     "filename",
                     self["filename_length"].value,
                     "Filename",
                     charset=charset)
        if 0 < self["extra_length"].value:
            yield ExtraFields(self,
                              "extra",
                              size=self["extra_length"].value * 8,
                              description="Extra fields")
        if 0 < self["comment_length"].value:
            yield String(self,
                         "comment",
                         self["comment_length"].value,
                         "Comment",
                         charset=charset)
Ejemplo n.º 4
0
 def createFields(self):
     yield String(self, "name", 20, strip='\0')
     yield GenericVector(self, "samples", 31, SampleInfo, "info")
     yield UInt8(self, "length")
     yield UInt8(self, "played_patterns_count")
     yield GenericVector(self, "patterns", 128, UInt8, "position")
     yield String(self, "type", 4)
Ejemplo n.º 5
0
    def createFields(self):
        yield String(self,
                     "signature",
                     4,
                     "AVI header (RIFF)",
                     charset="ASCII")
        yield filesizeHandler(UInt32(self, "filesize", "File size"))
        yield String(self,
                     "type",
                     4,
                     "Content type (\"AVI \", \"WAVE\", ...)",
                     charset="ASCII")

        # Choose chunk type depending on file type
        try:
            chunk_cls = self.VALID_TYPES[self["type"].value][0]
        except KeyError:
            chunk_cls = Chunk

        # Parse all chunks up to filesize
        while self.current_size < self["filesize"].value * 8 + 8:
            yield chunk_cls(self, "chunk[]")
        if not self.eof:
            yield RawBytes(self, "padding[]",
                           (self.size - self.current_size) // 8)
Ejemplo n.º 6
0
 def createFields(self):
     yield String(self,
                  "header_id",
                  4,
                  "DataBase Header Markup (\"mhbd\")",
                  charset="ISO-8859-1")
     yield UInt32(self, "header_length", "Header Length")
     yield UInt32(self, "entry_length", "Entry Length")
     yield UInt32(self, "unknown[]")
     yield UInt32(self, "version_number", "Version Number")
     yield UInt32(self, "child_number", "Number of Children")
     yield UInt64(self, "id", "ID for this database")
     yield UInt16(self, "unknown[]")
     yield UInt32(self, "unknown[]")
     yield UInt64(self, "unknown[]")
     yield UInt16(self, "unknown[]")
     yield UInt16(self, "hashing_scheme[]",
                  "Algorithm used to calculate the database hash")
     yield NullBytes(self, "unknown[]", 20)
     yield String(self, "language_id", 2, "Language ID")
     yield UInt64(self, "persistent_id", "Library Persistent ID")
     yield UInt32(self, "unknown[]")
     yield UInt32(self, "unknown[]")
     yield RawBytes(self, "hash[]", 20)
     yield Int32(self, "timezone_offset[]", "Timezone offset in seconds")
     yield UInt16(self, "unknown[]")
     yield RawBytes(self, "iphone_hash[]", 45)
     size = self["header_length"].value - self.current_size / 8
     if size > 0:
         yield NullBytes(self, "padding", size)
     for i in xrange(self["child_number"].value):
         yield DataSet(self, "dataset[]")
     padding = self.seekByte(self["entry_length"].value, "entry padding")
     if padding:
         yield padding
Ejemplo n.º 7
0
    def createFields(self):
        yield String(self,
                     "signature",
                     4,
                     'Format signature (".snd")',
                     charset="ASCII")
        yield UInt32(self, "data_ofs", "Data offset")
        yield filesizeHandler(UInt32(self, "data_size", "Data size"))
        yield Enum(UInt32(self, "codec", "Audio codec"), self.CODEC_NAME)
        yield displayHandler(
            UInt32(self, "sample_rate", "Number of samples/second"),
            humanFrequency)
        yield UInt32(self, "channels", "Number of interleaved channels")

        size = self["data_ofs"].value - self.current_size // 8
        if 0 < size:
            yield String(self,
                         "info",
                         size,
                         "Information",
                         strip=" \0",
                         charset="ISO-8859-1")

        size = min(self["data_size"].value,
                   (self.size - self.current_size) // 8)
        yield RawBytes(self, "audio_data", size, "Audio data")
Ejemplo n.º 8
0
 def createFields(self):
     yield RawBytes(self, "marker", len(self.MAGIC))
     yield WhiteSpace(self, "sep[]")
     yield String(self, "start_attribute_marker", 2)
     addr = self.absolute_address + self.current_size
     while self.stream.readBytes(addr, 2) != b'>>':
         yield WhiteSpace(self, "sep[]")
         t = PDFName(self, "type[]")
         yield t
         name = t.value.decode()
         self.info("Parsing PDFName '%s'" % name)
         if name == "Size":
             yield PDFNumber(self, "size", "Entries in the file cross-reference section")
         elif name == "Prev":
             yield PDFNumber(self, "offset")
         elif name == "Root":
             yield Catalog(self, "object_catalog")
         elif name == "Info":
             yield Catalog(self, "info")
         elif name == "ID":
             yield PDFArray(self, "id")
         elif name == "Encrypt":
             yield PDFDictionary(self, "decrypt")
         else:
             raise ParserError("Don't know trailer type '%s'" % name)
         addr = self.absolute_address + self.current_size
     yield String(self, "end_attribute_marker", 2)
     yield LineEnd(self, "line_end[]")
     yield String(self, "start_xref", 9)
     yield LineEnd(self, "line_end[]")
     yield PDFNumber(self, "cross_ref_table_start_address")
     yield LineEnd(self, "line_end[]")
     yield String(self, "end_marker", len(ENDMAGIC))
     yield LineEnd(self, "line_end[]")
Ejemplo n.º 9
0
 def createFields(self):
     size = self._size // 8
     # TODO: Strings charset?
     if self.stream.readBytes(self.absolute_address, 9) == "PeakValue":
         yield String(self, "text", 9, "Text")
         size -= 9
     yield String(self, "content", size, "Content")
Ejemplo n.º 10
0
    def createFields(self):
        # Header
        yield String(self, "magic", 3, "File magic code", charset="ASCII")
        yield String(self, "version", 3, "GIF version", charset="ASCII")

        yield ScreenDescriptor(self, "screen")
        if self["screen/global_map"].value:
            bpp = (self["screen/size_global_map"].value + 1)
            yield PaletteRGB(self, "color_map", 1 << bpp, "Color map")
            self.color_map = self["color_map"]
        else:
            self.color_map = None

        self.images = []
        while True:
            code = Enum(Character(self, "separator[]", "Separator code"),
                        self.separator_name)
            yield code
            code = code.value
            if code == "!":
                yield Extension(self, "extensions[]")
            elif code == ",":
                yield Image(self, "image[]")
            elif code == ";":
                # GIF Terminator
                break
            else:
                raise ParserError("Wrong GIF image separator: 0x%02X" %
                                  ord(code))
Ejemplo n.º 11
0
    def createFields(self):
        while self.stream.readBytes(self.absolute_address + self.current_size, 1) == '%':
            size = getLineEnd(self, 4)
            if size == 2:
                yield String(self, "crc32_comment", 1)
                yield textHandler(UInt16(self, "crc32"), hexadecimal)
            elif size == 4:
                yield String(self, "crc32_comment", 1)
                yield textHandler(UInt32(self, "crc32"), hexadecimal)
            elif self.stream.readBytes(self.absolute_address + self.current_size, size).isalpha():
                yield String(self, "comment[]", size)
            else:
                RawBytes(self, "unknown_data[]", size)
            yield LineEnd(self, "line_end[]")

        # abs_offset = self.current_size // 8
        # TODO: yield objects that read offsets and deduce size from
        # "/cross_ref_table/sub_section[]/entries/item[]"
        offsets = []
        for subsection in self.array("/cross_ref_table/sub_section"):
            for obj in subsection.array("entries/item"):
                if "byte_offset" in obj:
                    # Could be inserted already sorted
                    offsets.append(obj["byte_offset"].value)

        offsets.append(self["/cross_ref_table"].absolute_address // 8)
        offsets.sort()
        for index in xrange(len(offsets) - 1):
            yield Catalog(self, "object[]", size=offsets[index + 1] - offsets[index])
Ejemplo n.º 12
0
 def __init__(self, parent, name):
     n = 0
     while 1:
         ch = parent.stream.readBytes(parent.absolute_address + parent.current_size + n*8, 1)
         if not ch.isspace():
             break
         n += 1
     String.__init__(self, parent, name, n)
Ejemplo n.º 13
0
 def createFields(self):
     yield String(self, "marker", 5, MAGIC)
     length = getLineEnd(self, 4)
     if length is not None:
         # self.info("Found at position %08X" % len)
         yield String(self, "version", length - 1)
         yield LineEnd(self, "line_end")
     else:
         self.warning("Can't determine version!")
Ejemplo n.º 14
0
    def createFields(self):
        yield self.getType()
        yield String(self, "filename", 12, strip='\0')

        for field in self.getInstrumentFields():
            yield field

        yield String(self, "name", 28, strip='\0')
        yield String(self, "marker", 4, "Either 'SCRS' or '(empty)'", strip='\0')
Ejemplo n.º 15
0
 def createFields(self):
     yield String(self, "dict_start", 2)
     while not self.eof:
         addr = self.absolute_address + self.current_size
         if self.stream.readBytes(addr, 2) != '>>':
             for field in parsePDFType(self):
                 yield field
         else:
             break
     yield String(self, "dict_end", 2)
Ejemplo n.º 16
0
 def createFields(self):
     yield String(self, "signature", 4, "Signature (FORM)", charset="ASCII")
     yield filesizeHandler(UInt32(self, "filesize"))
     yield String(self,
                  "type",
                  4,
                  "Form type (AIFF or AIFC)",
                  charset="ASCII")
     while not self.eof:
         yield Chunk(self, "chunk[]")
Ejemplo n.º 17
0
 def createFields(self):
     yield String(self,
                  "start",
                  1,
                  "Dictionary start delimiter (d)",
                  charset="ASCII")
     while self.stream.readBytes(self.absolute_address + self.current_size,
                                 1) != "e":
         yield DictionaryItem(self, "item[]")
     yield String(self, "end", 1, "Dictionary end delimiter")
Ejemplo n.º 18
0
 def __init__(self,
              parent,
              name,
              nbytes,
              description=None,
              strip=' \0',
              charset='ISO-8859-1',
              *args,
              **kwargs):
     String.__init__(self, parent, name, nbytes, description, strip,
                     charset, *args, **kwargs)
Ejemplo n.º 19
0
 def createFields(self):
     yield String(self,
                  "header_id",
                  4,
                  "Data Object Header Markup (\"mhod\")",
                  charset="ISO-8859-1")
     yield UInt32(self, "header_length", "Header Length")
     yield UInt32(self, "entry_length", "Entry Length")
     yield Enum(UInt32(self, "type", "type"), self.type_name)
     if (self["type"].value == 15) or (self["type"].value == 16):
         yield UInt32(self, "unknown[]")
         yield UInt32(self, "unknown[]")
         yield String(self,
                      "string",
                      self._size // 8 - self["header_length"].value,
                      "String Data",
                      charset="UTF-8")
     elif (self["type"].value == 52):
         yield UInt32(self, "unknown[]", "unk1")
         yield UInt32(self, "unknown[]", "unk2")
         yield Enum(UInt32(self, "sort_index_type", "Sort Index Type"),
                    self.mhod52_sort_index_type_name)
         yield UInt32(self, "entry_count", "Entry Count")
         indexes_size = self["entry_count"].value * 4
         padding_offset = self["entry_length"].value - indexes_size
         padding = self.seekByte(padding_offset, "header padding")
         if padding:
             yield padding
         for i in xrange(self["entry_count"].value):
             yield UInt32(self, "index[" + str(i) + "]",
                          "Index of the " + str(i) + "nth mhit")
     elif (self["type"].value < 15) or (self["type"].value >
                                        17) or (self["type"].value >= 200):
         yield UInt32(self, "unknown[]")
         yield UInt32(self, "unknown[]")
         yield UInt32(self, "position", "Position")
         yield UInt32(self, "length", "String Length in bytes")
         yield UInt32(self, "unknown[]")
         yield UInt32(self, "unknown[]")
         yield String(self,
                      "string",
                      self["length"].value,
                      "String Data",
                      charset="UTF-16-LE")
     else:
         padding = self.seekByte(self["header_length"].value,
                                 "header padding")
         if padding:
             yield padding
     padding = self.seekBit(self._size, "entry padding")
     if padding:
         yield padding
Ejemplo n.º 20
0
 def createFields(self):
     yield UInt16(self, "length", "Length of this string")
     if self["length"].value:
         if self.root.hasUnicodeNames():
             yield String(self,
                          "data",
                          self["length"].value * 2,
                          charset="UTF-16-LE")
         else:
             yield String(self,
                          "data",
                          self["length"].value,
                          charset="ASCII")
Ejemplo n.º 21
0
def parseText(self):
    yield String(self,
                 "text",
                 self["size"].value,
                 strip=" \0",
                 truncate="\0",
                 charset="ISO-8859-1")
Ejemplo n.º 22
0
    def createFields(self):
        # Headers
        yield String(self, "header", 6, "Header (Exif\\0\\0)", charset="ASCII")
        if self["header"].value != "Exif\0\0":
            raise ParserError("Invalid EXIF signature!")
        iff_start = self.absolute_address + self.current_size
        ifds = []
        for field in TIFF(self):
            yield field
            if isinstance(field, IFD):
                ifds.append(field)

        for ifd in ifds:
            data = {}
            for i, entry in enumerate(ifd.array('entry')):
                data[entry['tag'].display] = entry
            if 'JPEGInterchangeFormat' in data and 'JPEGInterchangeFormatLength' in data:
                offs = ifd.getEntryValues(
                    data['JPEGInterchangeFormat'])[0].value
                size = ifd.getEntryValues(
                    data['JPEGInterchangeFormatLength'])[0].value
                if size == 0: continue
                self.seekByte(offs + iff_start // 8, relative=False)
                yield SubFile(self,
                              "thumbnail[]",
                              size,
                              "Thumbnail (JPEG file)",
                              mime_type="image/jpeg")
Ejemplo n.º 23
0
def TIFF(self):
    iff_start = self.absolute_address + self.current_size
    yield String(self, "endian", 2, "Endian ('II' or 'MM')", charset="ASCII")
    if self["endian"].value not in ("II", "MM"):
        raise ParserError("Invalid endian!")
    if self["endian"].value == "II":
        self.endian = LITTLE_ENDIAN
    else:
        self.endian = BIG_ENDIAN

    yield UInt16(self, "version", "TIFF version number")
    yield UInt32(self, "img_dir_ofs", "Next image directory offset")
    offsets = [(self['img_dir_ofs'].value, 'ifd[]', IFD)]
    while offsets:
        offset, name, klass = offsets.pop(0)
        self.seekByte(offset + iff_start // 8, relative=False)
        ifd = klass(self, name, iff_start)
        yield ifd
        for entry in ifd.array('entry'):
            tag = entry['tag'].value
            if tag in IFD_TAGS:
                name, klass = IFD_TAGS[tag]
                offsets.append(
                    (ifd.getEntryValues(entry)[0].value, name + '[]', klass))
            elif tag == IFDEntry.SUBIFD_POINTERS:
                for val in ifd.getEntryValues(entry):
                    offsets.append((val.value, ifd.name + '[]', IFD))
        if ifd['next'].value != 0:
            offsets.append((ifd['next'].value, 'ifd[]', IFD))
Ejemplo n.º 24
0
    def createFields(self):
        # Signature + version
        yield String(self, "header", 3, "Header (ID3)", charset="ASCII")
        yield UInt8(self, "ver_major", "Version (major)")
        yield UInt8(self, "ver_minor", "Version (minor)")

        # Check format
        if self["header"].value != "ID3":
            raise MatchError("Signature error, should be \"ID3\".")
        if self["ver_major"].value not in self.VALID_MAJOR_VERSIONS \
                or self["ver_minor"].value != 0:
            raise MatchError(
                "Unknown ID3 metadata version (2.%u.%u)" %
                (self["ver_major"].value, self["ver_minor"].value))

        # Flags
        yield Bit(self, "unsync", "Unsynchronisation is used?")
        yield Bit(self, "ext", "Extended header is used?")
        yield Bit(self, "exp", "Experimental indicator")
        yield NullBits(self, "padding[]", 5)

        # Size
        yield ID3_Size(self, "size")

        # All tags
        while self.current_size < self._size:
            field = ID3_Chunk(self, "field[]")
            yield field
            if field["size"].value == 0:
                break

        # Search first byte of the MPEG file
        padding = self.seekBit(self._size)
        if padding:
            yield padding
Ejemplo n.º 25
0
 def createFields(self):
     yield String(self,
                  "text",
                  self._size // 8,
                  "Text",
                  charset="ISO-8859-1",
                  strip=self.STRIP)
Ejemplo n.º 26
0
    def createFields(self):
        yield Bytes(self, "signature", 4, r'ELF signature ("\x7fELF")')
        yield Enum(UInt8(self, "class", "Class"), self.CLASS_NAME)
        if self["class"].value == 1:
            ElfLongWord = UInt32
        else:
            ElfLongWord = UInt64
        yield Enum(UInt8(self, "endian", "Endian"), self.ENDIAN_NAME)
        yield UInt8(self, "file_version", "File version")
        yield Enum(UInt8(self, "osabi_ident", "OS/syscall ABI identification"),
                   self.OSABI_NAME)
        yield UInt8(self, "abi_version", "syscall ABI version")
        yield String(self, "pad", 7, "Pad")

        yield Enum(UInt16(self, "type", "File type"), self.TYPE_NAME)
        yield Enum(UInt16(self, "machine", "Machine type"), self.MACHINE_NAME)
        yield UInt32(self, "version", "ELF format version")
        yield textHandler(ElfLongWord(self, "entry", "Entry point"),
                          hexadecimal)
        yield ElfLongWord(self, "phoff", "Program header file offset")
        yield ElfLongWord(self, "shoff", "Section header file offset")
        yield UInt32(self, "flags", "Architecture-specific flags")
        yield UInt16(self, "ehsize", "Elf header size (this header)")
        yield UInt16(self, "phentsize", "Program header entry size")
        yield UInt16(self, "phnum", "Program header entry count")
        yield UInt16(self, "shentsize", "Section header entry size")
        yield UInt16(self, "shnum", "Section header entry count")
        yield UInt16(self, "shstrndx", "Section header string table index")
Ejemplo n.º 27
0
    def createFields(self):
        yield UInt16(self, "size", "Node size (in bytes)")
        yield UInt16(self, "data_size")
        yield Enum(UInt16(self, "type"), self.TYPE_NAME)
        yield CString(self, "name", charset="UTF-16-LE")

        size = paddingSize(self.current_size // 8, 4)
        if size:
            yield NullBytes(self, "padding[]", size)
        size = self["data_size"].value
        if size:
            if self["type"].value == self.TYPE_STRING:
                if self.is_32bit:
                    size *= 2
                yield String(self, "value", size, charset="UTF-16-LE", truncate="\0")
            elif self["name"].value == "VS_VERSION_INFO":
                yield VersionInfoBinary(self, "value", size=size * 8)
                if self["value/file_flags_mask"].value == 0:
                    self.is_32bit = False
            else:
                yield RawBytes(self, "value", size)
        while 12 <= (self.size - self.current_size) // 8:
            yield VersionInfoNode(self, "node[]", self.is_32bit)
        size = (self.size - self.current_size) // 8
        if size:
            yield NullBytes(self, "padding[]", size)
Ejemplo n.º 28
0
    def createFields(self):
        # yield from ZipStartCommonFields(self) # PY3
        for field in ZipStartCommonFields(self):
            yield field
        length = self["filename_length"].value

        if length:
            filename = String(self,
                              "filename",
                              length,
                              "Filename",
                              charset=zipGetCharset(self))
            yield filename
            self.filename = filename.value
        if self["extra_length"].value:
            yield ExtraFields(self,
                              "extra",
                              size=self["extra_length"].value * 8,
                              description="Extra fields")
        size = self["compressed_size"].value
        if size > 0:
            yield self.data(size)
        elif self["flags/incomplete"].value:
            # yield from self.resync()  # PY3
            for field in self.resync():
                yield field
        if self["flags/has_descriptor"].value and self['crc32'].value == 0:
            yield ZipDataDescriptor(self, "data_desc", "Data descriptor")
Ejemplo n.º 29
0
    def createFields(self):
        yield UInt32(self, "size")
        yield String(self, "name", 22, charset="ASCII", strip=" \0")
        # Doc says type is always 0, but I've found values of 24 and 96 for
        # the _same_ song here, just different download sources for the file
        yield UInt8(self, "type")
        yield UInt16(self, "samples")
        num = self["samples"].value
        self.info(self.createDescription())

        if num:
            yield InstrumentSecondHeader(self, "second_header")

            for field in self.fixInstrumentHeader():
                yield field

            # This part probably wrong
            sample_size = []
            for index in xrange(num):
                sample = SampleHeader(self, "sample_header[]")
                yield sample
                sample_size.append(sample["length"].value)

            for size in sample_size:
                if size:
                    yield RawBytes(self, "sample_data[]", size, "Deltas")
        else:
            for field in self.fixInstrumentHeader():
                yield field
Ejemplo n.º 30
0
    def createFields(self):
        # Header
        yield NullBytes(self, "zero_vector", 16)
        yield GUID(self, "fs_guid")
        yield UInt64(self, "volume_len")
        yield String(self, "signature", 4)
        yield UInt32(self, "attributes")
        yield UInt16(self, "header_len")
        yield UInt16(self, "checksum")
        yield UInt16(self, "ext_header_offset")
        yield UInt8(self, "reserved")
        yield UInt8(self, "revision")
        while True:
            bm = BlockMap(self, "block_map[]")
            yield bm
            if bm['num_blocks'].value == 0 and bm['len'].value == 0:
                break
        # TODO must handle extended header

        # Content
        while not self.eof:
            padding = paddingSize(self.current_size // 8, 8)
            if padding:
                yield PaddingBytes(self, "padding[]", padding)
            yield File(self, "file[]")