From 531924e7e70c84c1ead2f5b05210dda4f256dd9b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 21 Aug 2025 07:27:40 -0700 Subject: [PATCH] terminal: explicitly initialize undefined fields at runtime This works around the Zig issue as noted in the comment. No new Valgrind issues found from this. --- src/terminal/Parser.zig | 34 ++++++++++++++++++------- src/terminal/kitty/graphics_command.zig | 24 ++++++++++++----- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/terminal/Parser.zig b/src/terminal/Parser.zig index ed099ee47..0223545e5 100644 --- a/src/terminal/Parser.zig +++ b/src/terminal/Parser.zig @@ -209,26 +209,42 @@ const MAX_INTERMEDIATE = 4; const MAX_PARAMS = 24; /// Current state of the state machine -state: State = .ground, +state: State, /// Intermediate tracking. -intermediates: [MAX_INTERMEDIATE]u8 = undefined, -intermediates_idx: u8 = 0, +intermediates: [MAX_INTERMEDIATE]u8, +intermediates_idx: u8, /// Param tracking, building -params: [MAX_PARAMS]u16 = undefined, -params_sep: Action.CSI.SepList = .initEmpty(), -params_idx: u8 = 0, -param_acc: u16 = 0, -param_acc_idx: u8 = 0, +params: [MAX_PARAMS]u16, +params_sep: Action.CSI.SepList, +params_idx: u8, +param_acc: u16, +param_acc_idx: u8, /// Parser for OSC sequences osc_parser: osc.Parser, pub fn init() Parser { - return .{ + var result: Parser = .{ + .state = .ground, + .intermediates_idx = 0, + .params_sep = .initEmpty(), + .params_idx = 0, + .param_acc = 0, + .param_acc_idx = 0, .osc_parser = .init(), + + .intermediates = undefined, + .params = undefined, }; + if (std.valgrind.runningOnValgrind() > 0) { + // Initialize our undefined fields so Valgrind can catch it. + // https://github.com/ziglang/zig/issues/19148 + result.intermediates = undefined; + result.params = undefined; + } + return result; } pub fn deinit(self: *Parser) void { diff --git a/src/terminal/kitty/graphics_command.zig b/src/terminal/kitty/graphics_command.zig index adc6edafe..dcb4850c9 100644 --- a/src/terminal/kitty/graphics_command.zig +++ b/src/terminal/kitty/graphics_command.zig @@ -21,14 +21,14 @@ pub const Parser = struct { arena: ArenaAllocator, /// This is the list of KV pairs that we're building up. - kv: KV = .{}, + kv: KV, /// This is used as a buffer to store the key/value of a KV pair. The value /// of a KV pair is at most a 32-bit integer which at most is 10 characters /// (4294967295), plus one character for the sign bit on signed ints. - kv_temp: [11]u8 = undefined, - kv_temp_len: u4 = 0, - kv_current: u8 = 0, // Current kv key + kv_temp: [11]u8, + kv_temp_len: u4, + kv_current: u8, // Current kv key /// This is the list we use to collect the bytes from the data payload. /// The Kitty Graphics protocol specification seems to imply that the @@ -38,7 +38,7 @@ pub const Parser = struct { data: std.ArrayList(u8), /// Internal state for parsing. - state: State = .control_key, + state: State, const State = enum { /// Parsing k/v pairs. The "ignore" variants are in that state @@ -57,10 +57,22 @@ pub const Parser = struct { pub fn init(alloc: Allocator) Parser { var arena = ArenaAllocator.init(alloc); errdefer arena.deinit(); - return .{ + var result: Parser = .{ .arena = arena, .data = std.ArrayList(u8).init(alloc), + .kv = .{}, + .kv_temp_len = 0, + .kv_current = 0, + .state = .control_key, + + .kv_temp = undefined, }; + if (std.valgrind.runningOnValgrind() > 0) { + // Initialize our undefined fields so Valgrind can catch it. + // https://github.com/ziglang/zig/issues/19148 + result.kv_temp = undefined; + } + return result; } pub fn deinit(self: *Parser) void {