def test_cbfs_invalid_file_type_on_read(self): """Check handling of an invalid file type when reading the CBFS""" size = 0xb0 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() # Read in the first file header cbr = cbfs_util.CbfsReader(data, read=False) with io.BytesIO(data) as fd: self.assertTrue(cbr._find_and_read_header(fd, len(data))) pos = fd.tell() hdr_data = fd.read(cbfs_util.FILE_HEADER_LEN) magic, size, ftype, attr, offset = struct.unpack( cbfs_util.FILE_HEADER_FORMAT, hdr_data) # Create a new CBFS with a change to the file type ftype = 0xff newdata = data[:pos] newdata += struct.pack(cbfs_util.FILE_HEADER_FORMAT, magic, size, ftype, attr, offset) newdata += data[pos + cbfs_util.FILE_HEADER_LEN:] # Read in this CBFS and make sure that the reader complains with self.assertRaises(ValueError) as e: cbfs_util.CbfsReader(newdata) self.assertIn('Unknown type 0xff when reading', str(e.exception))
def _check_hdr(self, data, size, offset=0, arch=cbfs_util.ARCHITECTURE_X86): """Check that the CBFS has the expected header Args: data: Data to check size: Expected ROM size offset: Expected offset to first CBFS file arch: Expected architecture Returns: CbfsReader object containing the CBFS """ cbfs = cbfs_util.CbfsReader(data) self.assertEqual(cbfs_util.HEADER_MAGIC, cbfs.magic) self.assertEqual(cbfs_util.HEADER_VERSION2, cbfs.version) self.assertEqual(size, cbfs.rom_size) self.assertEqual(0, cbfs.boot_block_size) self.assertEqual(cbfs_util.ENTRY_ALIGN, cbfs.align) self.assertEqual(offset, cbfs.cbfs_offset) self.assertEqual(arch, cbfs.arch) return cbfs
def test_cbfs_missing_attribute(self): """Check handling of an incomplete attribute tag""" if not self.have_lz4: self.skipTest('lz4 --no-frame-crc not available') size = 0x140 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', COMPRESS_DATA, None, compress=cbfs_util.COMPRESS_LZ4) data = cbw.get_data() # Read in the CBFS master header (only), then stop cbr = cbfs_util.CbfsReader(data, read=False) with io.BytesIO(data) as fd: self.assertTrue(cbr._find_and_read_header(fd, len(data))) pos = fd.tell() # Create a new CBFS with only the first 4 bytes of the compression tag, # then try to read the file tag_pos = pos + cbfs_util.FILE_HEADER_LEN + cbfs_util.FILENAME_ALIGN newdata = data[:tag_pos + 4] with test_util.capture_sys_output() as (stdout, _stderr): with io.BytesIO(newdata) as fd: fd.seek(pos) self.assertEqual(False, cbr._read_next_file(fd)) self.assertIn('Attribute tag at %x ran out of data' % tag_pos, stdout.getvalue())
def test_cbfs_bad_attribute(self): """Check handling of bad attribute tag""" if not self.have_lz4: self.skipTest('lz4 --no-frame-crc not available') size = 0x140 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', COMPRESS_DATA, None, compress=cbfs_util.COMPRESS_LZ4) data = cbw.get_data() # Search the CBFS for the expected compression tag with io.BytesIO(data) as fd: while True: pos = fd.tell() tag, = struct.unpack('>I', fd.read(4)) if tag == cbfs_util.FILE_ATTR_TAG_COMPRESSION: break # Create a new CBFS with the tag changed to something invalid newdata = data[:pos] + struct.pack('>I', 0x123) + data[pos + 4:] with test_util.capture_sys_output() as (stdout, _stderr): cbfs_util.CbfsReader(newdata) self.assertEqual('Unknown attribute tag 123\n', stdout.getvalue())
def ReadChildData(self, child, decomp=True): if not self.reader: data = Entry.ReadData(self, True) self.reader = cbfs_util.CbfsReader(data) reader = self.reader cfile = reader.files.get(child.name) return cfile.data if decomp else cfile.orig_data
def test_cbfs_check_offset(self): """Test that we can discover the offset of a file after writing it""" size = 0xb0 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) cbw.add_file_raw('u-boot-dtb', U_BOOT_DTB_DATA) data = cbw.get_data() cbfs = cbfs_util.CbfsReader(data) self.assertEqual(0x38, cbfs.files['u-boot'].cbfs_offset) self.assertEqual(0x78, cbfs.files['u-boot-dtb'].cbfs_offset)
def test_cbfs_file_master_header(self): """Check handling of a file containing a master header""" size = 0x100 cbw = CbfsWriter(size) cbw._add_fileheader = True cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() cbr = cbfs_util.CbfsReader(data) self.assertIn('u-boot', cbr.files) self.assertEqual(size, cbr.rom_size)
def test_cbfs_debug(self): """Check debug output""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() try: cbfs_util.DEBUG = True with test_util.capture_sys_output() as (stdout, _stderr): cbfs_util.CbfsReader(data) self.assertEqual('name u-boot\ndata %s\n' % U_BOOT_DATA, stdout.getvalue()) finally: cbfs_util.DEBUG = False
def test_cbfs_bad_header(self): """Check handling of a bad master header""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() # Drop most of the header and try reading the modified CBFS newdata = data[:cbw._header_offset + 4] with test_util.capture_sys_output() as (stdout, _stderr): with self.assertRaises(ValueError) as e: cbfs_util.CbfsReader(newdata) self.assertIn('Relative offset seems wrong', stdout.getvalue()) self.assertIn('Cannot find master header', str(e.exception))
def test_cbfs_bad_header_ptr(self): """Check handling of a bad master-header pointer""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() # Add one to the pointer to make it invalid newdata = data[:-4] + struct.pack('<I', cbw._header_offset + 1) # We should still be able to find the master header by searching with test_util.capture_sys_output() as (stdout, _stderr): cbfs = cbfs_util.CbfsReader(newdata) self.assertIn('Relative offset seems wrong', stdout.getvalue()) self.assertIn('u-boot', cbfs.files) self.assertEqual(size, cbfs.rom_size)
def test_cbfs_bad_file_header(self): """Check handling of a bad file header""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() # Read in the CBFS master header (only), then stop cbr = cbfs_util.CbfsReader(data, read=False) with io.BytesIO(data) as fd: self.assertTrue(cbr._find_and_read_header(fd, len(data))) pos = fd.tell() # Remove all but 4 bytes of the file headerm and try to read the file newdata = data[:pos + 4] with test_util.capture_sys_output() as (stdout, _stderr): with io.BytesIO(newdata) as fd: fd.seek(pos) self.assertEqual(False, cbr._read_next_file(fd)) self.assertIn('File header at 0x0 ran out of data', stdout.getvalue())
def test_cbfs_bad_file_string(self): """Check handling of an incomplete filename string""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('16-characters xx', U_BOOT_DATA) data = cbw.get_data() # Read in the CBFS master header (only), then stop cbr = cbfs_util.CbfsReader(data, read=False) with io.BytesIO(data) as fd: self.assertTrue(cbr._find_and_read_header(fd, len(data))) pos = fd.tell() # Create a new CBFS with only the first 16 bytes of the file name, then # try to read the file newdata = data[:pos + cbfs_util.FILE_HEADER_LEN + 16] with test_util.capture_sys_output() as (stdout, _stderr): with io.BytesIO(newdata) as fd: fd.seek(pos) self.assertEqual(False, cbr._read_next_file(fd)) self.assertIn('String at %#x ran out of data' % cbfs_util.FILE_HEADER_LEN, stdout.getvalue())