Fix passing None to RegistersTracker.processLui

This commit is contained in:
angie 2023-09-22 17:01:14 -03:00
parent 802f953b59
commit d5bee1b537
5 changed files with 65 additions and 6 deletions

View File

@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `CHANGELOG.md`
- Add markdown linter to CI
### Fixed
- Fix passing `None` to `RegistersTracker.processLui`
## [1.7.9] - 2023-09-18
### Changed

View File

@ -73,11 +73,11 @@ Let's break up the example and explain each part:
To initialize our `instr` we need to call the pair `RabbitizerInstruction_init`
and `RabbitizerInstruction_processUniqueId`. `RabbitizerInstruction_init`
initialises all the members of the struct so it doesn't contain garbage data
anymore, while `RabbitizerInstruction_processUniqueId` does the heavy lifting of
identifying the actual instruction id out of the `word` we passed.
anymore, while `RabbitizerInstruction_processUniqueId` does the heavy lifting
of identifying the actual instruction id out of the `word` we passed.
A `RabbitizerInstruction` variable is not considered fully initialized until it
has been passed to this pair of functions.
A `RabbitizerInstruction` variable is not considered fully initialized until
it has been passed to this pair of functions.
```c
RabbitizerInstruction_init(&instr, word, vram);

View File

@ -44,6 +44,11 @@ extern PyTypeObject rabbitizer_type_LoPairingInfo_TypeObject;
extern PyTypeObject rabbitizer_type_TrackedRegisterState_TypeObject;
extern PyTypeObject rabbitizer_type_RegistersTracker_TypeObject;
int rabbitizer_type_Instruction_TypeObject_Check(PyObject *o);
int rabbitizer_converter_InstructionOrNone(PyObject *object, PyRabbitizerInstruction **address);
DECL_ENUM(Abi)
DECL_ENUM(InstrCategory)
DECL_ENUM(InstrId)

View File

@ -671,6 +671,57 @@ static PyObject *rabbitizer_type_Instruction_str(PyRabbitizerInstruction *self)
return rabbitizer_type_Instruction_disassemble(self, Py_BuildValue("()"), Py_BuildValue("{}"));
}
/**
* Returns:
* - 1 if `o` is an RabbitizerInstruction
* - 0 if not an instance of RabbitizerInstruction
* - -1 if an error occurred
*/
int rabbitizer_type_Instruction_TypeObject_Check(PyObject *o) {
int isInstance = PyObject_IsInstance(o, (PyObject*)&rabbitizer_type_Instruction_TypeObject);
if (isInstance < 0) {
/* An error happened */
/* PyObject_IsInstance already sets an exception, so nothing else to do here */
return -1;
}
if (isInstance == 0) {
/* `o` isn't an instance of RabbitizerInstruction */
return 0;
}
return 1;
}
int rabbitizer_converter_InstructionOrNone(PyObject *object, PyRabbitizerInstruction **address) {
int instanceCheck;
if ((object == NULL) || (address == NULL)) {
PyErr_Format(PyExc_RuntimeError, "%s: Internal error", __func__);
return 0; // fail
}
if (object == Py_None) {
*address = NULL;
return 1; // successful
}
instanceCheck = rabbitizer_type_Instruction_TypeObject_Check(object);
if (instanceCheck < 0) {
return 0; // fail
}
if (instanceCheck > 0) {
*address = (PyRabbitizerInstruction*)object;
return 1; // successful
}
// TypeError: argument 3 must be rabbitizer.Instruction, not None
PyErr_Format(PyExc_TypeError, "argument must be %s or None, not %s", rabbitizer_type_Instruction_TypeObject.tp_name, object->ob_type->tp_name);
return 0; // fail
}
PyTypeObject rabbitizer_type_Instruction_TypeObject = {
PyVarObject_HEAD_INIT(NULL, 0)

View File

@ -11,7 +11,6 @@ typedef struct PyRabbitizerRegistersTracker {
RabbitizerRegistersTracker tracker;
} PyRabbitizerRegistersTracker;
static void rabbitizer_type_RegistersTracker_dealloc(PyRabbitizerRegistersTracker *self) {
RabbitizerRegistersTracker_destroy(&self->tracker);
Py_TYPE(self)->tp_free((PyObject *) self);
@ -119,7 +118,7 @@ static PyObject *rabbitizer_type_RegistersTracker_processLui(PyRabbitizerRegiste
PyRabbitizerInstruction *pyPrevInstr = NULL;
RabbitizerInstruction *prevInstr = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!i|O!", kwlist, &rabbitizer_type_Instruction_TypeObject, &instr, &instrOffset, &rabbitizer_type_Instruction_TypeObject, &pyPrevInstr)) {
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!i|O&", kwlist, &rabbitizer_type_Instruction_TypeObject, &instr, &instrOffset, rabbitizer_converter_InstructionOrNone, &pyPrevInstr)) {
return NULL;
}