def read(self, fp): sections = [] matched = False self.valid = True metaData = defaultdict(list) for (lineNumber, line) in enumerate(fp.readlines(), 1): for formatType, format in self.formats: if isinstance(line, bytes): match = format.match(line.decode()) else: match = format.match(line) if match: matched = True container = Container() container.lineNumber = lineNumber dict_ = match.groupdict() if dict_ != {}: # Handle scalar values. for key, value in dict_.items(): if key not in ('chunk', 'junk'): setattr(container, key, atoi(value)) elif key == 'junk': setattr(container, key, value) if 'chunk' in dict_: if self.parseData(container, formatType): chunk = bytearray( map(atoi, BYTES.findall(dict_['chunk']))) else: # don't convert/parse stuff like symbols. chunk = dict_['chunk'] dict_.pop('chunk') setattr(container, 'chunk', chunk) self.checkLine(container, formatType) # this is to handle esoteric stuff like Intel seg:offs addressing and symbols. self.specialProcessing(container, formatType) if self.isDataLine(container, formatType): # print chunk sections.append( Section(container.address, container.chunk)) else: chunk = container.chunk if hasattr( container, 'chunk') else None address = container.address if hasattr( container, 'address') else None metaData[formatType].append( MetaRecord(formatType, address, chunk)) break if not matched: self.warn("Ignoring garbage line #{0:d}".format(lineNumber)) if sections: return Image(joinSections(sections), metaData, self.valid) else: self.error("File seems to be invalid.") return Image([], valid=False)
def test_get_section_raises(join): img = Image(join=join) img.insert_section(data=range(10), start_address=0x030) img.insert_section(data=range(10), start_address=0x020) img.insert_section(data=range(10), start_address=0x010) img.insert_section(data=range(10), start_address=0x000) with pytest.raises(InvalidAddressError): sec = img.get_section(0x3a) with pytest.raises(InvalidAddressError): sec = img.get_section(0x2b) with pytest.raises(InvalidAddressError): sec = img.get_section(0x1c) with pytest.raises(InvalidAddressError): sec = img.get_section(0x0d)
def test_get_section1(): img = Image(join=False) img.insert_section(data=range(16), start_address=0x030) img.insert_section(data=range(16), start_address=0x020) img.insert_section(data=range(16), start_address=0x010) img.insert_section(data=range(16), start_address=0x000) sec = img.get_section(0x33) assert sec.start_address == 0x30 sec = img.get_section(0x22) assert sec.start_address == 0x20 sec = img.get_section(0x11) assert sec.start_address == 0x10 sec = img.get_section(0x02) assert sec.start_address == 0x00
def load(self, fp, address=0x0000): data = fp.read() sec = Section(address, data) img = Image([sec], valid=True) if hasattr(fp, "close"): fp.close() return img
def setUp(self): if PYTHON_VERSION.major == 3: self.buf = io.TextIOWrapper(create_string_buffer()) else: self.buf = create_string_buffer() #self.stdout = sys.stdout #sys.stdout = self.buf self.image = Image()
class TestHexfile(unittest.TestCase): def setUp(self): self.image = Image() def tearDown(self): del self.image def testAddSectionAliasWorks(self): self.image.insert_section(range(64), 0x1000) # Ok, if no exception gets raised. def testRaisesInvalidChecksumError(self): self.assertRaises(hexfile.InvalidRecordChecksumError, loads, "srec", b'S110000048656C6C6F2C20776F726C6421AA') def testRaisesError(self): # self.assertRaises(hexfile.InvalidRecordChecksumError, loads, "srec", b'S110000048656C6C6F20776F726C642166') pass
def test_read_write_uint64_array(): img = Image(Section(data=bytearray(128), start_address=0x1000)) img.write_numeric_array(0x1000, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "uint64_be") assert img[0].length == 128 assert img.read_numeric_array(0x1000, 10, "uint64_be") == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) img.write_numeric_array(0x1000, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "uint64_le") assert img[0].length == 128 assert img.read_numeric_array(0x1000, 10, "uint64_le") == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
def test_dump_shf1(): SREC1 = b"""S113B000576F77212044696420796F7520726561D8 S113B0106C6C7920676F207468726F756768206143 S113B0206C20746861742074726F75626C6520742E S10FB0306F207265616420746869733FCE S9030000FC""" sr = loads("srec", SREC1) img = Image([sr[0]]) shf = dumps("shf", img) assert shf == """<?xml version="1.0" encoding="UTF-8"?>
def test_get_section2(): img = Image(join=True) img.insert_section(data=range(16), start_address=0x030) img.insert_section(data=range(16), start_address=0x020) img.insert_section(data=range(16), start_address=0x010) img.insert_section(data=range(16), start_address=0x000) sec = img.get_section(0x33) assert sec.start_address == 0x00 assert len(sec) == 64
def test_read_write_int64_array(): img = Image(Section(data=bytearray(128), start_address=0x1000)) img.write_numeric_array(0x1000, [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10], "int64_be") assert img[0].length == 128 assert img.read_numeric_array(0x1000, 10, "int64_be") == (-1, -2, -3, -4, -5, -6, -7, -8, -9, -10) img.write_numeric_array(0x1000, [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10], "int64_le") assert img[0].length == 128 assert img.read_numeric_array(0x1000, 10, "int64_le") == (-1, -2, -3, -4, -5, -6, -7, -8, -9, -10)
def test_read_write_float64_array(): img = Image(Section(data=bytearray(128), start_address=0x1000)) img.write_numeric_array( 0x1000, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], "float64_be") assert img[0].length == 128 assert img.read_numeric_array(0x1000, 10, "float64_be") == (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) img.write_numeric_array( 0x1000, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], "float64_le") assert img[0].length == 128 assert img.read_numeric_array(0x1000, 10, "float64_le") == (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)
def createImage(self, record_type, s5record, start_address=None): image = Image() image.insert_section(range(10), 0x1000) image.join_sections() return dumps("srec", image, record_type=record_type, s5record=s5record, start_address=start_address)
def test_sorting8(capsys): RES = """ Section #0000 ------------- 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| * 00000030 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| --------------- 64 bytes --------------- """ img = Image(join=True) img.insert_section(data=range(16), start_address=0x030) img.insert_section(data=range(16), start_address=0x020) img.insert_section(data=range(16), start_address=0x010) img.insert_section(data=range(16), start_address=0x000) img.hexdump(sys.stdout) captured = capsys.readouterr() assert captured.out == RES
def testLoadsWorks(self): image = Image() image.insert_section( "Wow! Did you really go through al that trouble to read this?", 0xb000) image.join_sections() self.assertEqual( dumps("srec", image, record_type=1, s5record=False, start_address=0x0000), SREC1)
def read(self, fp): if PYTHON_VERSION.major == 3: lines = fp.read().decode() else: lines = fp.read() self.sections = [] self.address = 0 breakRequest = False for line in lines.splitlines(): for pattern, action in self.patterns: match = pattern.match(line) if match: if not action(line, match): breakRequest = True break if breakRequest: break return Image(joinSections(self.sections))
def test_read_write_float64(): img = Image(Section(data=bytearray(32), start_address=0x1000)) img.write_numeric(0x1000, 1234.5678, "float64_be") assert img.read_numeric(0x1000, "float64_be") == 1234.5678 img.write_numeric(0x1000, 1234.5678, "float64_le") assert img.read_numeric(0x1000, "float64_le") == 1234.5678
def test_read_uint8_array_boundary_case2(): img = Image(Section(data=bytearray(10), start_address=0x1000)) assert img.read_numeric_array(0x1005, 5, "uint8_be") == (0, 0, 0, 0, 0)
def test_read_write_string(): img = Image(Section(data=bytearray(32), start_address=0x1000)) img.write_string(0x1000, 'hello') assert img.read_string(0x1000) == "hello"
def setUp(self): self.image = Image()
def testImageRepresentation(self): image = Image() image.insert_section([x % 256 for x in range(10000)]) image.join_sections() self.assertEqual(repr(image), RESULT)
def load(self, fp): if isinstance(fp, str): fp = open(fp, "rb") data = fp.read() root = ET.fromstring(data) sections = [] for idx, child in enumerate(root): tag = child.tag attrib = child.attrib text = remove_ws(child.text) section_data = bytearray.fromhex(text) name = attrib.get('name') if name is None: self.logger.error( "Block #{}: Missing required attribute `name`.".format( idx)) continue address = attrib.get('address') if address: address = remove_ws(address) address = int(address, 16) else: self.logger.error( "Block #{}: Missing required attribute `address`.".format( idx)) continue length = attrib.get('length') if length: length = remove_ws(length) length = int(length, 16) else: self.logger.error( "Block #{}: Missing required attribute `length`.".format( idx)) continue word_size = attrib.get('word_size') if word_size: word_size = remove_ws(word_size) word_size = int(word_size, 16) else: self.logger.error( "Block #{}: Missing required attribute `wordsize`.".format( idx)) continue if len(section_data) != (length * word_size): self.logger.error( "Block #{}: Mismatch between (`length` * `word_size`) and actual block length." .format(idx)) continue checksum = attrib.get('checksum') if checksum: checksum = remove_ws(checksum) if SHA1_DIGEST(section_data) != checksum: self.logger.error( "Block #{}: Wrong `checksum`.".format(idx)) continue else: self.logger.error( "Block #{}: Missing required attribute `checksum`.".format( idx)) continue #print(tag, attrib) #print(section_data, SHA1_DIGEST(section_data)) sections.append(Section(address, section_data)) img = Image(sections) if hasattr(fp, "close"): fp.close() return img
def test_read_uint32_negative_offset(): img = Image(Section(data=bytearray(10), start_address=0x1000)) with pytest.raises(InvalidAddressError): img.read_numeric(0x0fff, "uint32_le")
def test_read_write_string_length(): img = Image(Section(data=bytearray(32), start_address=0x1000)) img.write_string(0x1000, 'hello world!!!') assert img.read_string(0x1000, length=5) == "hello"
def test_write_int16_negative_offset(): img = Image(Section(data=bytearray(10), start_address=0x1000)) with pytest.raises(InvalidAddressError): img.write_numeric(0x0fff, 0xff, "int16_le")
def test_write_float64_negative_offset(): img = Image(Section(data=bytearray(10), start_address=0x1000)) with pytest.raises(InvalidAddressError): img.write_numeric(0x0fff, 3.14159, "float64_le")
def test_read_unterminated_string_raises(): img = Image(Section(data=bytearray(b"\x0a" * 32), start_address=0x1000)) img.write(0x1000, b'hello') with pytest.raises(TypeError): data = img.read_string(0x1000)
def test_write_array_data_must_be_iterable(): img = Image(Section(data=bytearray(32), start_address=0x1000)) with pytest.raises(TypeError): img.write_numeric_array(0x1000, 0x55, "uint8_be")
def test_write_uint8_array_boundary_case2(): img = Image(Section(data=bytearray(10), start_address=0x1000)) img.write_numeric_array(0x1005, [1, 2, 3, 4, 5], "uint8_be") assert img[0].length == 10
def test_read_uint8_array_boundary_case4(): img = Image(Section(data=bytearray(10), start_address=0x1000)) with pytest.raises(InvalidAddressError): img.read_numeric_array(0x0fff, 5, "uint8_be") == (0, 0, 0, 0, 0)
def test_write_uint8_array_boundary_case4(): img = Image(Section(data=bytearray(10), start_address=0x1000)) with pytest.raises(InvalidAddressError): img.write_numeric_array(0x0fff, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "uint8_be")