From a4c2c04343e666bd85bf7786cc50947214e77584 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Tue, 6 Jan 2026 04:38:56 -0500 Subject: [PATCH] bugfix: segfault in Grid.at() due to internal types not exported to module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After #184/#189 made GridPoint and GridPointState internal-only types, code using PyObject_GetAttrString(mcrf_module, "GridPoint") would get NULL and crash when dereferencing. Fixed by using the type directly via &mcrfpydef::PyUIGridPointType instead of looking it up in the module. Affected functions: - UIGrid::py_at() - UIGridPointState::get_point() - UIEntity::at() - UIGridPointState_to_PyObject() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/UIEntity.cpp | 13 ++++--------- src/UIGrid.cpp | 4 ++-- src/UIGridPoint.cpp | 7 ++----- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/UIEntity.cpp b/src/UIEntity.cpp index fe13678..e689670 100644 --- a/src/UIEntity.cpp +++ b/src/UIEntity.cpp @@ -122,9 +122,9 @@ PyObject* UIEntity::at(PyUIEntityObject* self, PyObject* args, PyObject* kwds) { return NULL; } - auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPointState"); + // Use type directly since GridPointState is internal-only (not exported to module) + auto type = &mcrfpydef::PyUIGridPointStateType; auto obj = (PyUIGridPointStateObject*)type->tp_alloc(type, 0); - Py_DECREF(type); obj->data = &(self->data->gridstate[y * self->data->grid->grid_x + x]); obj->grid = self->data->grid; obj->entity = self->data; @@ -320,14 +320,10 @@ sf::Vector2i PyObject_to_sfVector2i(PyObject* obj) { PyObject* UIGridPointState_to_PyObject(const UIGridPointState& state) { // Create a new GridPointState Python object (detached - no grid/entity context) - auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPointState"); - if (!type) { - return NULL; - } - + // Use type directly since GridPointState is internal-only (not exported to module) + auto type = &mcrfpydef::PyUIGridPointStateType; auto obj = (PyUIGridPointStateObject*)type->tp_alloc(type, 0); if (!obj) { - Py_DECREF(type); return NULL; } @@ -342,7 +338,6 @@ PyObject* UIGridPointState_to_PyObject(const UIGridPointState& state) { obj->x = -1; obj->y = -1; - Py_DECREF(type); return (PyObject*)obj; } diff --git a/src/UIGrid.cpp b/src/UIGrid.cpp index eb2935c..2910005 100644 --- a/src/UIGrid.cpp +++ b/src/UIGrid.cpp @@ -1182,8 +1182,8 @@ PyObject* UIGrid::py_at(PyUIGridObject* self, PyObject* args, PyObject* kwds) return NULL; } - //PyUIGridPointObject* obj = (PyUIGridPointObject*)((&PyUIGridPointType)->tp_alloc(&PyUIGridPointType, 0)); - auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPoint"); + // Use the type directly since GridPoint is internal-only (not exported to module) + auto type = &mcrfpydef::PyUIGridPointType; auto obj = (PyUIGridPointObject*)type->tp_alloc(type, 0); //auto target = std::static_pointer_cast(target); // #123 - Use at() method to route through chunks for large grids diff --git a/src/UIGridPoint.cpp b/src/UIGridPoint.cpp index 3e7eb8f..f66f0f6 100644 --- a/src/UIGridPoint.cpp +++ b/src/UIGridPoint.cpp @@ -201,12 +201,9 @@ PyObject* UIGridPointState::get_point(PyUIGridPointStateObject* self, void* clos return NULL; } - // Return the GridPoint at this position - auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPoint"); - if (!type) return NULL; - + // Return the GridPoint at this position (use type directly since it's internal-only) + auto type = &mcrfpydef::PyUIGridPointType; auto obj = (PyUIGridPointObject*)type->tp_alloc(type, 0); - Py_DECREF(type); if (!obj) return NULL; // Get the GridPoint from the grid