-
Notifications
You must be signed in to change notification settings - Fork 38
Description
VariableDatum objects throw struct.error when you try to store negative signed integers (e.g. -1=b'\xff') in the variableData field, then serialize.
MVP
This is the minimum viable product to reproduce the error
from opendis.dis7 import VariableDatum
from opendis.DataOutputStream import DataOutputStream
from io import BytesIO
import struct
variable_datum = VariableDatum()
data = list((b'\x00'*4)+struct.pack('>i',-1))
variable_datum.variableData = data
variable_datum.variableDatumLength = len(data)*8
memoryStream = BytesIO()
outputStream = DataOutputStream(memoryStream)
variable_datum.serialize(outputStream)
print(memoryStream.getvalue())Expected Behavior
I expect variable_datum to serialize without an error, and for the final print to display the serialized object (should be b'\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\xff\xff\xff\xff')
Actual Behavior
The script throws a struct.error when variable_datum tries to serialize.
Full error
This is the full error that is thrown when variable_datum tries to serialize.
Traceback (most recent call last):
File "test.py", line 12, in <module>
variable_datum.serialize(outputStream)
File "C:\Users\e389403\AppData\Local\Programs\Python\Python37-32\lib\site-packages\opendis\dis7.py", line 3586, in serialize
outputStream.write_byte(self.variableData[x])
File "C:\Users\e389403\AppData\Local\Programs\Python\Python37-32\lib\site-packages\opendis\DataOutputStream.py", line 17, in write_byte
self.stream.write(struct.pack('b', val))
struct.error: byte format requires -128 <= number <= 127
Possible solutions
From what I can gather, when serialize is called:
serialize()is called- for each byte in the
variableDatabytesobject, it callsoutputStream.write_byte())
This means that when it reachesb'\xff's, it tries to write255as a signed byte tooutputStream. - thus it tries to call
struct.pack('b', 255)which results in an error, rightly so because it's out ofrange(0, 256).
When I changed dis7.py line 3586 to outputStream.write_unsigned_byte(self.variableData[x]), then I got the expected behavior.
Notes
Signed integers actually parse without error. This makes sense, since inputStream.read_byte() is used to parse the bytes when forming the variableData list.
from opendis.dis7 import VariableDatum
from opendis.DataInputStream import DataInputStream
from io import BytesIO
memoryStream = BytesIO(b'\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\xff\xff\xff\xff')
inputStream = DataInputStream(memoryStream)
new_variable_datum = VariableDatum()
new_variable_datum.parse(inputStream)
print(new_variable_datum.variableData) # [0, 0, 0, 0, -1, -1, -1, -1]