From 5b01cb353de47a0053c313e3bc20170cbece679e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 27 Nov 2024 08:46:03 -0800 Subject: [PATCH] config: need to dupe filepath for diagnostics Fixes #2800 The source string with the filepath is not guaranteed to exist beyond the lifetime of the parse operation. We must copy it. --- src/cli/args.zig | 13 ++++++++----- src/cli/diagnostics.zig | 4 ++-- src/config/Config.zig | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/cli/args.zig b/src/cli/args.zig index 3e378f347..454ca360e 100644 --- a/src/cli/args.zig +++ b/src/cli/args.zig @@ -104,7 +104,7 @@ pub fn parse( try dst._diagnostics.append(arena_alloc, .{ .key = try arena_alloc.dupeZ(u8, arg), .message = "invalid field", - .location = diags.Location.fromIter(iter), + .location = try diags.Location.fromIter(iter, arena_alloc), }); continue; @@ -145,7 +145,7 @@ pub fn parse( try dst._diagnostics.append(arena_alloc, .{ .key = try arena_alloc.dupeZ(u8, key), .message = message, - .location = diags.Location.fromIter(iter), + .location = try diags.Location.fromIter(iter, arena_alloc), }); }; } @@ -1140,7 +1140,7 @@ pub fn ArgsIterator(comptime Iterator: type) type { } /// Returns a location for a diagnostic message. - pub fn location(self: *const Self) ?diags.Location { + pub fn location(self: *const Self, _: Allocator) error{}!?diags.Location { return .{ .cli = self.index }; } }; @@ -1262,12 +1262,15 @@ pub fn LineIterator(comptime ReaderType: type) type { } /// Returns a location for a diagnostic message. - pub fn location(self: *const Self) ?diags.Location { + pub fn location( + self: *const Self, + alloc: Allocator, + ) Allocator.Error!?diags.Location { // If we have no filepath then we have no location. if (self.filepath.len == 0) return null; return .{ .file = .{ - .path = self.filepath, + .path = try alloc.dupe(u8, self.filepath), .line = self.line, } }; } diff --git a/src/cli/diagnostics.zig b/src/cli/diagnostics.zig index 8090684fd..40fed3001 100644 --- a/src/cli/diagnostics.zig +++ b/src/cli/diagnostics.zig @@ -56,7 +56,7 @@ pub const Location = union(enum) { pub const Key = @typeInfo(Location).Union.tag_type.?; - pub fn fromIter(iter: anytype) Location { + pub fn fromIter(iter: anytype, alloc: Allocator) Allocator.Error!Location { const Iter = t: { const T = @TypeOf(iter); break :t switch (@typeInfo(T)) { @@ -67,7 +67,7 @@ pub const Location = union(enum) { }; if (!@hasDecl(Iter, "location")) return .none; - return iter.location() orelse .none; + return (try iter.location(alloc)) orelse .none; } pub fn clone(self: *const Location, alloc: Allocator) Allocator.Error!Location { diff --git a/src/config/Config.zig b/src/config/Config.zig index 2dc732752..a3bc79099 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2988,7 +2988,7 @@ pub fn parseManuallyHook( if (command.items.len == 0) { try self._diagnostics.append(alloc, .{ - .location = cli.Location.fromIter(iter), + .location = try cli.Location.fromIter(iter, alloc), .message = try std.fmt.allocPrintZ( alloc, "missing command after {s}",