예제 #1
0
파일: __init__.py 프로젝트: molnarg/cfb
    def __init__(self, name, raise_if=ErrorDefect, lazy=False):
        super(CfbIO, self).__init__(name, mode='rb')
        MaybeDefected.__init__(self, raise_if=raise_if)

        self.size = fstat(self.fileno()).st_size
        self.header = Header(self)

        self.directory = Directory(self)
        if not lazy:
            self.directory.read()
예제 #2
0
    def __init__(self, name, raise_if=ErrorDefect, lazy=False):
        super(CfbIO, self).__init__(name, mode='rb')
        MaybeDefected.__init__(self, raise_if=raise_if)

        self.size = fstat(self.fileno()).st_size
        self.header = Header(self)

        self.directory = Directory(self)
        if not lazy:
            self.directory.read()
예제 #3
0
    def __init__(self, value, raise_if=WarningDefect):
        value = b(value)

        super(MockCfbIO, self).__init__(value)
        MaybeDefected.__init__(self, raise_if=raise_if)

        header_like = namedtuple("Header", "version cutoff_size "
                                           "mini_sector_size "
                                           "mini_sector_shift")
        self.header = header_like(version=(3, 0),
                                  cutoff_size=0x00001000,
                                  mini_sector_size=2 ** 0x0009,
                                  mini_sector_shift=0x0009)

        self.root = BytesIO()
        self.default = value
        self.current = value
예제 #4
0
    def test_main(self):
        me = MaybeDefected(raise_if=ErrorDefect)

        self.assertRaises(FatalDefect, me._fatal, "Fatal!")
        self.assertRaises(ErrorDefect, me._error, "Error!")

        simplefilter("error")
        self.assertRaises(SyntaxWarning, me._warning, "Warning!")
예제 #5
0
파일: header.py 프로젝트: django-stars/cfb
    def __init__(self, source):
        super(Header, self).__init__(source.read(76))
        MaybeDefected.__init__(self, raise_if=source.minimum_defect)

        try:
            if unpack('>Q', self.read(8))[0] != self.signature:
                raise UnpackError("Bad signature")
        except UnpackError:
            self._fatal('Identification signature for the compound file '
                        'structure, and MUST be set to the value 0xD0, '
                        '0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.')

        try:
            self.clsid = Guid(self.read(16))
            if self.clsid != GUID_NULL:
                raise ValueError("Bad CLSID")
        except ValueError:
            self._error('Reserved and unused class ID that MUST be set to all '
                        'zeroes (CLSID_NULL).')

        try:
            minor, major, byte_order, self.sector_shift, \
                self.mini_sector_shift = unpack('<HHHHH', self.read(10))
            if major not in (3, 4):
                self._error('Version number for breaking changes. This field '
                            'MUST be set to either 0x0003 (version 3) or '
                            '0x0004 (version 4).')
            if minor != 0x003E:
                self._warning('Version number for non-breaking changes. This '
                              'field SHOULD be set to 0x003E if the major '
                              'version field is either 0x0003 or 0x0004.')

            if byte_order != 0xFFFE:
                self._fatal('This field MUST be set to 0xFFFE. This field is '
                            'a byte order mark for all integer fields, '
                            'specifying little-endian byte order.')

            if self.sector_shift not in (0x0009, 0x000C):
                self._error('This field MUST be set to 0x0009, or 0x000c, '
                            'depending on the Major Version field.')
            if self.sector_shift == 0x0009 and major != 3:
                self._error('If Major Version is 3, then the Sector Shift '
                            'MUST be 0x0009, specifying a sector size of '
                            '512 bytes.')
            if self.sector_shift == 0x000C and major != 4:
                self._error('If Major Version is 4, then the Sector Shift '
                            'MUST be 0x000C, specifying a sector size of '
                            '4096 bytes.')

            if self.mini_sector_shift != 0x0006:
                self._error('This field MUST be set to 0x0006. This field '
                            'specifies the sector size of the Mini Stream as '
                            'a power of 2.')

            if self.read(6) != b('\0' * 6):
                self._error('Reversed field MUST be set to all zeroes.')

            # TODO Add additional attributes checks
            (self.directory_sector_count, self.fat_sectors_count,
             self.directory_sector_start, self.transaction_count,
             self.cutoff_size, self.minifat_sector_start,
             self.minifat_sector_count, self.difat_sector_start,
             self.difat_sector_count) = unpack('<LLLLLLLLL', self.read(36))

            if major == 3 and self.directory_sector_count:
                self._error('If Major Version is 3, then the Number of '
                            'Directory Sectors MUST be zero. This field is '
                            'not supported for version 3 compound files.')

            if self.cutoff_size != 0x00001000:
                self._error('This integer field MUST be set to 0x00001000. '
                            'This field specifies the maximum size of a '
                            'user-defined data stream allocated from the '
                            'mini FAT and mini stream, and that cutoff is '
                            '4096 bytes. Any user-defined data stream larger '
                            'than or equal to this cutoff size must be '
                            'allocated as normal sectors from the FAT.')

            self.version = major, minor

            self.sector_size = 2 ** self.sector_shift
            self.mini_sector_size = 2 ** self.mini_sector_shift

        except UnpackError:
            self._fatal('Bad file attributes detected.')
예제 #6
0
 def __init__(self, value="", raise_if=ErrorDefect):
     super(SourceMock, self).__init__(b(value))
     MaybeDefected.__init__(self, raise_if=raise_if)
예제 #7
0
 def __init__(self, value="", raise_if=ErrorDefect):
     super(SourceMock, self).__init__(b(value))
     MaybeDefected.__init__(self, raise_if=raise_if)
예제 #8
0
    def __init__(self, source):
        super(Header, self).__init__(source.read(76))
        MaybeDefected.__init__(self, raise_if=source.minimum_defect)

        try:
            if unpack('>Q', self.read(8))[0] != self.signature:
                raise UnpackError("Bad signature")
        except UnpackError:
            self._fatal('Identification signature for the compound file '
                        'structure, and MUST be set to the value 0xD0, '
                        '0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.')

        try:
            self.clsid = Guid(self.read(16))
            if self.clsid != GUID_NULL:
                raise ValueError("Bad CLSID")
        except ValueError:
            self._error('Reserved and unused class ID that MUST be set to all '
                        'zeroes (CLSID_NULL).')

        try:
            minor, major, byte_order, self.sector_shift, \
                self.mini_sector_shift = unpack('<HHHHH', self.read(10))
            if major not in (3, 4):
                self._error('Version number for breaking changes. This field '
                            'MUST be set to either 0x0003 (version 3) or '
                            '0x0004 (version 4).')
            if minor != 0x003E:
                self._warning('Version number for non-breaking changes. This '
                              'field SHOULD be set to 0x003E if the major '
                              'version field is either 0x0003 or 0x0004.')

            if byte_order != 0xFFFE:
                self._fatal('This field MUST be set to 0xFFFE. This field is '
                            'a byte order mark for all integer fields, '
                            'specifying little-endian byte order.')

            if self.sector_shift not in (0x0009, 0x000C):
                self._error('This field MUST be set to 0x0009, or 0x000c, '
                            'depending on the Major Version field.')
            if self.sector_shift == 0x0009 and major != 3:
                self._error('If Major Version is 3, then the Sector Shift '
                            'MUST be 0x0009, specifying a sector size of '
                            '512 bytes.')
            if self.sector_shift == 0x000C and major != 4:
                self._error('If Major Version is 4, then the Sector Shift '
                            'MUST be 0x000C, specifying a sector size of '
                            '4096 bytes.')

            if self.mini_sector_shift != 0x0006:
                self._error('This field MUST be set to 0x0006. This field '
                            'specifies the sector size of the Mini Stream as '
                            'a power of 2.')

            if self.read(6) != b('\0' * 6):
                self._error('Reversed field MUST be set to all zeroes.')

            # TODO Add additional attributes checks
            (self.directory_sector_count, self.fat_sectors_count,
             self.directory_sector_start, self.transaction_count,
             self.cutoff_size, self.minifat_sector_start,
             self.minifat_sector_count, self.difat_sector_start,
             self.difat_sector_count) = unpack('<LLLLLLLLL', self.read(36))

            if major == 3 and self.directory_sector_count:
                self._error('If Major Version is 3, then the Number of '
                            'Directory Sectors MUST be zero. This field is '
                            'not supported for version 3 compound files.')

            if self.cutoff_size != 0x00001000:
                self._error('This integer field MUST be set to 0x00001000. '
                            'This field specifies the maximum size of a '
                            'user-defined data stream allocated from the '
                            'mini FAT and mini stream, and that cutoff is '
                            '4096 bytes. Any user-defined data stream larger '
                            'than or equal to this cutoff size must be '
                            'allocated as normal sectors from the FAT.')

            self.version = major, minor

            self.sector_size = 2**self.sector_shift
            self.mini_sector_size = 2**self.mini_sector_shift

        except UnpackError:
            self._fatal('Bad file attributes detected.')