[Bugfix] updateVisibility() gridstate.size()==0 guard doesn't validate against current grid dimensions #276

Closed
opened 2026-03-07 23:25:35 +00:00 by john · 0 comments
Owner

Summary

UIEntity::updateVisibility() has a lazy initialization guard if (gridstate.size() == 0) at line 41 that only initializes gridstate when it's completely empty. If the entity has gridstate from a previous grid of different size, this guard is skipped and the function proceeds to iterate using the current grid's dimensions — writing past the end of the undersized vector.

While the primary fix for this class of bug is in the grid transfer entry points (set_grid, append, extend, insert, setitem, slice — see issues #258-#263), updateVisibility() itself should have a defense-in-depth check.

Root Cause

UIEntity.cpp:36-71:

void UIEntity::updateVisibility()
{
    if (!grid) return;

    // Lazy initialize gridstate if needed
    if (gridstate.size() == 0) {          // Only checks for empty, not wrong-sized
        gridstate.resize(grid->grid_w * grid->grid_h);
        ...
    }

    // Iterates using CURRENT grid dimensions
    for (int gy = 0; gy < grid->grid_h; gy++) {
        for (int gx = 0; gx < grid->grid_w; gx++) {
            int idx = gy * grid->grid_w + gx;    // idx up to grid_w*grid_h - 1
            if (grid->isInFOV(gx, gy)) {
                gridstate[idx].visible = true;     // Out of bounds if gridstate is wrong size

Fix

Change the guard to validate against the current grid dimensions:

size_t expected_size = static_cast<size_t>(grid->grid_w * grid->grid_h);
if (gridstate.size() != expected_size) {
    gridstate.resize(expected_size);
    for (auto& state : gridstate) {
        state.visible = false;
        state.discovered = false;
    }
}

This provides defense-in-depth: even if a grid transfer entry point misses the resize, updateVisibility() will catch and correct the mismatch before iterating.

Severity

Medium — defense-in-depth fix. The primary fixes are in the grid transfer methods, but this guards against any future code path that sets entity->grid without resizing gridstate.

  • #258-#263 — gridstate resize bugs in EntityCollection methods
  • Original 7DRL 2026 hotfix in UIEntity::set_grid()
## Summary `UIEntity::updateVisibility()` has a lazy initialization guard `if (gridstate.size() == 0)` at line 41 that only initializes gridstate when it's completely empty. If the entity has gridstate from a previous grid of different size, this guard is skipped and the function proceeds to iterate using the current grid's dimensions — writing past the end of the undersized vector. While the primary fix for this class of bug is in the grid transfer entry points (set_grid, append, extend, insert, setitem, slice — see issues #258-#263), `updateVisibility()` itself should have a defense-in-depth check. ## Root Cause `UIEntity.cpp:36-71`: ```cpp void UIEntity::updateVisibility() { if (!grid) return; // Lazy initialize gridstate if needed if (gridstate.size() == 0) { // Only checks for empty, not wrong-sized gridstate.resize(grid->grid_w * grid->grid_h); ... } // Iterates using CURRENT grid dimensions for (int gy = 0; gy < grid->grid_h; gy++) { for (int gx = 0; gx < grid->grid_w; gx++) { int idx = gy * grid->grid_w + gx; // idx up to grid_w*grid_h - 1 if (grid->isInFOV(gx, gy)) { gridstate[idx].visible = true; // Out of bounds if gridstate is wrong size ``` ## Fix Change the guard to validate against the current grid dimensions: ```cpp size_t expected_size = static_cast<size_t>(grid->grid_w * grid->grid_h); if (gridstate.size() != expected_size) { gridstate.resize(expected_size); for (auto& state : gridstate) { state.visible = false; state.discovered = false; } } ``` This provides defense-in-depth: even if a grid transfer entry point misses the resize, `updateVisibility()` will catch and correct the mismatch before iterating. ## Severity **Medium** — defense-in-depth fix. The primary fixes are in the grid transfer methods, but this guards against any future code path that sets `entity->grid` without resizing gridstate. ## Related - #258-#263 — gridstate resize bugs in EntityCollection methods - Original 7DRL 2026 hotfix in UIEntity::set_grid()
john closed this issue 2026-03-14 06:25:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
john/McRogueFace#276
No description provided.