Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if self.file_structure_version != 1:
self.file_structure_version = 1
elif self._vd_type == VOLUME_DESCRIPTOR_TYPE_SUPPLEMENTARY:
if self.file_structure_version not in (1, 2):
raise pycdlibexception.PyCdlibInvalidISO('File structure version expected to be 1')
# According to Ecma-119, 8.4.31, the second unused field should be 0.
if unused2 != 0:
raise pycdlibexception.PyCdlibInvalidISO('data in 2nd unused field not zero')
# According to Ecma-119, the last 653 bytes of the VD should be all 0.
# However, we have seen ISOs in the wild that do not follow this, so
# relax the check.
# Check to make sure that the little-endian and big-endian versions
# of the parsed data agree with each other.
if space_size_le != utils.swab_32bit(space_size_be):
raise pycdlibexception.PyCdlibInvalidISO('Little-endian and big-endian space size disagree')
self.space_size = space_size_le
if set_size_le != utils.swab_16bit(set_size_be):
raise pycdlibexception.PyCdlibInvalidISO('Little-endian and big-endian set size disagree')
self.set_size = set_size_le
if seqnum_le != utils.swab_16bit(seqnum_be):
raise pycdlibexception.PyCdlibInvalidISO('Little-endian and big-endian seqnum disagree')
self.seqnum = seqnum_le
if logical_block_size_le != utils.swab_16bit(logical_block_size_be):
raise pycdlibexception.PyCdlibInvalidISO('Little-endian and big-endian logical block size disagree')
self.log_block_size = logical_block_size_le
if path_table_size_le != utils.swab_32bit(path_table_size_be):
raise pycdlibexception.PyCdlibInvalidISO('Little-endian and big-endian path table size disagree')
raise pycdlibexception.PyCdlibInvalidISO('PX record big and little-endian file user ID do not agree')
if posix_file_group_id_le != utils.swab_32bit(posix_file_group_id_be):
raise pycdlibexception.PyCdlibInvalidISO('PX record big and little-endian file group ID do not agree')
# In Rock Ridge 1.09 and 1.10, there is no serial number so the su_len
# is 36, while in Rock Ridge 1.12, there is an 8-byte serial number so
# su_len is 44.
if su_len == 36:
posix_file_serial_number_le = 0
elif su_len == 44:
(posix_file_serial_number_le,
posix_file_serial_number_be) = struct.unpack_from('
entry_list.cl_record.parse(recslice)
elif rtype == b'PL':
entry_list.pl_record = RRPLRecord()
entry_list.pl_record.parse(recslice)
elif rtype == b'RE':
entry_list.re_record = RRRERecord()
entry_list.re_record.parse(recslice)
elif rtype == b'TF':
entry_list.tf_record = RRTFRecord()
entry_list.tf_record.parse(recslice)
elif rtype == b'SF':
entry_list.sf_record = RRSFRecord()
entry_list.sf_record.parse(recslice)
sf_record_length = len(recslice)
else:
raise pycdlibexception.PyCdlibInvalidISO('Unknown SUSP record')
offset += su_len
left -= su_len
# Now let's determine the version of Rock Ridge that we have (1.09,
# 1.10, or 1.12). Unfortunately, there is no direct information from
# Rock Ridge, so we infer it from what is present. In an ideal world,
# the following table would tell us:
#
# | Feature/Rock Ridge version | 1.09 | 1.10 | 1.12 |
# +----------------------------+---------------+---------------+---------------+
# | Has RR Record? | True or False | False | False |
# | Has ES Record? | False | False | True or False |
# | Has SF Record? | False | True or False | True or False |
# | PX Record length | 36 | 36 | 44 |
# | SF Record length | N/A | 12 | 21 |
# | ER Desc string | RRIP_1991A | RRIP_1991A | IEEE_P1282 |
raise pycdlibexception.PyCdlibInvalidISO('Parent of the entry did not have Rock Ridge, ISO is corrupt')
if self.file_ident == b'\x00':
# If we are adding the dot directory, increment the parent
# file links and our file links.
self.parent.rock_ridge.add_to_file_links()
self.rock_ridge.add_to_file_links()
elif self.file_ident == b'\x01':
# If we are adding the dotdot directory, copy the file links
# from the dot directory of the grandparent.
if self.parent.parent is None:
raise pycdlibexception.PyCdlibInternalError('Grandparent of the entry did not exist; this cannot be')
if not self.parent.children:
raise pycdlibexception.PyCdlibInvalidISO('Grandparent of the entry did not have a dot entry; ISO is corrupt')
if self.parent.parent.children[0].rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Grandparent dotdot entry did not have Rock Ridge; ISO is corrupt')
self.rock_ridge.copy_file_links(self.parent.parent.children[0].rock_ridge)
else:
# For all other entries, increment the parents file links
# and the parents dot file links.
self.parent.rock_ridge.add_to_file_links()
if not self.parent.children:
raise pycdlibexception.PyCdlibInvalidISO('Parent of the entry did not have a dot entry; ISO is corrupt')
if self.parent.children[0].rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Dot child of the parent did not have a dot entry; ISO is corrupt')
self.parent.children[0].rock_ridge.add_to_file_links()
# If we are adding the dotdot directory, copy the file links
# from the dot directory of the grandparent.
if self.parent.parent is None:
raise pycdlibexception.PyCdlibInternalError('Grandparent of the entry did not exist; this cannot be')
if not self.parent.children:
raise pycdlibexception.PyCdlibInvalidISO('Grandparent of the entry did not have a dot entry; ISO is corrupt')
if self.parent.parent.children[0].rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Grandparent dotdot entry did not have Rock Ridge; ISO is corrupt')
self.rock_ridge.copy_file_links(self.parent.parent.children[0].rock_ridge)
else:
# For all other entries, increment the parents file links
# and the parents dot file links.
self.parent.rock_ridge.add_to_file_links()
if not self.parent.children:
raise pycdlibexception.PyCdlibInvalidISO('Parent of the entry did not have a dot entry; ISO is corrupt')
if self.parent.children[0].rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Dot child of the parent did not have a dot entry; ISO is corrupt')
self.parent.children[0].rock_ridge.add_to_file_links()
# If this is a directory, we have to manipulate the file links
# appropriately.
if self.parent.is_root:
if self.file_ident == b'\x00' or self.file_ident == b'\x01':
# For the dot and dotdot children of the root, add one
# directly to their Rock Ridge links.
self.rock_ridge.add_to_file_links()
else:
# For all other children of the root, make sure to add one
# to each of the dot and dotdot entries.
if len(self.parent.children) < 2:
raise pycdlibexception.PyCdlibInvalidISO('Expected at least 2 children of the root directory record, saw %d' % (len(self.parent.children)))
if self.parent.children[0].rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Dot child of directory has no Rock Ridge; ISO is corrupt')
self.parent.children[0].rock_ridge.add_to_file_links()
if self.parent.children[1].rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Dot-dot child of directory has no Rock Ridge; ISO is corrupt')
self.parent.children[1].rock_ridge.add_to_file_links()
else:
if self.parent.rock_ridge is None:
raise pycdlibexception.PyCdlibInvalidISO('Parent of the entry did not have Rock Ridge, ISO is corrupt')
if self.file_ident == b'\x00':
# If we are adding the dot directory, increment the parent
# file links and our file links.
self.parent.rock_ridge.add_to_file_links()
self.rock_ridge.add_to_file_links()
elif self.file_ident == b'\x01':
# If we are adding the dotdot directory, copy the file links
while True:
if left == 0:
break
if left == 1:
# There may be a padding byte on the end.
if bytes(bytearray([record[offset]])) != b'\x00':
raise pycdlibexception.PyCdlibInvalidISO('Invalid pad byte')
break
if left < 4:
raise pycdlibexception.PyCdlibInvalidISO('Not enough bytes left in the System Use field')
(rtype, su_len, su_entry_version) = struct.unpack_from('=2sBB', record[:offset + 4], offset)
if su_entry_version != SU_ENTRY_VERSION:
raise pycdlibexception.PyCdlibInvalidISO('Invalid RR version %d!' % su_entry_version)
if su_len == 0:
raise pycdlibexception.PyCdlibInvalidISO('Zero size for Rock Ridge entry length')
recslice = record[offset:]
if rtype in (b'SP', b'RR', b'CE', b'PX', b'ST', b'ER',
b'PN', b'CL', b'PL', b'RE', b'TF', b'SF'):
recname = rtype.decode('utf-8').lower() + '_record'
if self.has_entry(recname):
raise pycdlibexception.PyCdlibInvalidISO('Only single %s record supported' % (rtype.decode('utf-8')))
if rtype == b'SP':
if left < 7 or not is_first_dir_record_of_root:
raise pycdlibexception.PyCdlibInvalidISO('Invalid SUSP SP record')
# OK, this is the first Directory Record of the root
# directory, which means we should check it for the SUSP/RR
# extension, which is exactly 7 bytes and starts with 'SP'.
(tag_unused, icb_tag, self.uid, self.gid, self.perms, self.file_link_count,
record_format, record_display_attrs, record_len,
self.info_len, self.log_block_recorded, access_time, mod_time,
attr_time, checkpoint, extended_attr_icb, impl_ident, self.unique_id,
self.len_extended_attrs, len_alloc_descs) = struct.unpack_from(self.FMT, data, 0)
self.desc_tag = desc_tag
self.icb_tag = UDFICBTag()
self.icb_tag.parse(icb_tag)
if record_format != 0:
raise pycdlibexception.PyCdlibInvalidISO('File Entry record format is not 0')
if record_display_attrs != 0:
raise pycdlibexception.PyCdlibInvalidISO('File Entry record display attributes is not 0')
if record_len != 0:
raise pycdlibexception.PyCdlibInvalidISO('File Entry record length is not 0')
self.access_time = UDFTimestamp()
self.access_time.parse(access_time)
self.mod_time = UDFTimestamp()
self.mod_time.parse(mod_time)
self.attr_time = UDFTimestamp()
self.attr_time.parse(attr_time)
if checkpoint != 1:
raise pycdlibexception.PyCdlibInvalidISO('Only DVD Read-only disks supported')