From 4ec86678539ef8d26fc0ed6c8324d09bdc14a643 Mon Sep 17 00:00:00 2001 From: reugenio Date: Thu, 18 Dec 2025 11:33:35 +0100 Subject: [PATCH] fix: duplicar strings al cargar config para evitar dangling pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problema: Al recargar config, los strings asignados apuntaban al buffer de contenido del archivo que se liberaba con defer al final de load(). Esto causaba segfaults al acceder a los valores después. Solución: Usar dupeString() o allocator.dupe() para crear copias independientes de los strings antes de asignarlos a la config. Afecta tipos .string, .string_array y .color (cuando el campo es []const u8). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/zcatconfig.zig | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/zcatconfig.zig b/src/zcatconfig.zig index bab131f..85718a2 100644 --- a/src/zcatconfig.zig +++ b/src/zcatconfig.zig @@ -372,10 +372,18 @@ pub fn Engine(comptime variables: []const ConfigVariable, comptime ConfigType: t @field(config.*, v.name) = float_val; }, .string, .string_array => { - // Para strings, necesitamos que Config tenga dupeString o similar - // Si el campo es []const u8 con default, simplemente asignamos - // (asumimos que el llamador maneja la memoria) - @field(config.*, v.name) = value; + // IMPORTANTE: Duplicar el string porque 'value' apunta a 'content' + // que se libera con defer al final de load() + if (@hasDecl(ConfigType, "dupeString")) { + // Config tiene método para trackear strings alocados + @field(config.*, v.name) = config.dupeString(value) catch value; + } else if (@hasField(ConfigType, "allocator")) { + // Usar allocator del config directamente + @field(config.*, v.name) = config.allocator.dupe(u8, value) catch value; + } else { + // Fallback: asignar directamente (puede causar dangling pointer!) + @field(config.*, v.name) = value; + } }, .color => { const FieldType = @TypeOf(@field(config.*, v.name)); @@ -383,7 +391,15 @@ pub fn Engine(comptime variables: []const ConfigVariable, comptime ConfigType: t const color = Color.parse(value) orelse return ConfigError.InvalidValue; @field(config.*, v.name) = color; } else { - @field(config.*, v.name) = value; + // String que representa un color (nombre de paleta) + // También necesita duplicarse + if (@hasDecl(ConfigType, "dupeString")) { + @field(config.*, v.name) = config.dupeString(value) catch value; + } else if (@hasField(ConfigType, "allocator")) { + @field(config.*, v.name) = config.allocator.dupe(u8, value) catch value; + } else { + @field(config.*, v.name) = value; + } } }, }