From 7f8870d890ee0e82cefe086ba7ee3d2c366d81c2 Mon Sep 17 00:00:00 2001 From: reugenio Date: Thu, 25 Dec 2025 23:03:54 +0100 Subject: [PATCH] fix(advanced_table): Use std.mem.swap for Row sorting + doc warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace manual temp variable swap with std.mem.swap (more explicit) - Add documentation warning about pointer invalidation after sort/setRows - Row contains StringHashMap with internal pointers - swap is safe but pointers obtained via getRow() are invalidated after mutations Based on INFORME_AUDITORIA_PROFUNDA_20251225.md ยง1.2 --- src/widgets/advanced_table/advanced_table.zig | 9 +++++---- src/widgets/advanced_table/state.zig | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/widgets/advanced_table/advanced_table.zig b/src/widgets/advanced_table/advanced_table.zig index a66a8dc..cbe7ffb 100644 --- a/src/widgets/advanced_table/advanced_table.zig +++ b/src/widgets/advanced_table/advanced_table.zig @@ -1243,10 +1243,11 @@ fn sortRows( }; if (should_swap) { - // Swap rows - const temp = table_state.rows.items[i]; - table_state.rows.items[i] = table_state.rows.items[i + 1]; - table_state.rows.items[i + 1] = temp; + // Swap rows usando std.mem.swap (seguro para structs con punteros internos) + // NOTA: Row contiene StringHashMap que tiene punteros a buckets. + // El swap mueve el struct completo, no clona los datos. + // Los punteros obtenidos via getRow() se invalidan tras sort. + std.mem.swap(Row, &table_state.rows.items[i], &table_state.rows.items[i + 1]); // Swap state map entries swapRowStates(table_state, i, i + 1); diff --git a/src/widgets/advanced_table/state.zig b/src/widgets/advanced_table/state.zig index aa7fa53..a7f05c6 100644 --- a/src/widgets/advanced_table/state.zig +++ b/src/widgets/advanced_table/state.zig @@ -231,12 +231,16 @@ pub const AdvancedTableState = struct { } /// Get row by index + /// ADVERTENCIA: El puntero retornado se invalida tras sortRows() o setRows(). + /// No guardar el puntero entre frames - obtenerlo de nuevo cuando sea necesario. pub fn getRow(self: *AdvancedTableState, index: usize) ?*Row { if (index >= self.rows.items.len) return null; return &self.rows.items[index]; } /// Get row by index (const) + /// ADVERTENCIA: El puntero retornado se invalida tras sortRows() o setRows(). + /// No guardar el puntero entre frames - obtenerlo de nuevo cuando sea necesario. pub fn getRowConst(self: *const AdvancedTableState, index: usize) ?*const Row { if (index >= self.rows.items.len) return null; return &self.rows.items[index];