summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2025-08-13 21:15:24 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2025-08-13 21:15:24 +0200
commitb25e1f4a3d42024500a0987f2be55cba85672fbe (patch)
treeb991d8bd03741982430aed5686ef66afa65f64d2 /src
parentc623a9171b711f1a0cbd761e4fc8ae5f64a52c95 (diff)
Fix memory leaks.
Diffstat (limited to 'src')
-rw-r--r--src/syntax.zig52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/syntax.zig b/src/syntax.zig
index dde6dba..af4833c 100644
--- a/src/syntax.zig
+++ b/src/syntax.zig
@@ -199,6 +199,10 @@ pub const Command = union(enum) {
redirect.redirects.deinit();
},
.External => |*external| {
+ allocator.free(external.program);
+ for (external.args.items) |arg| {
+ allocator.free(arg);
+ }
external.args.deinit();
},
.Builtin => |builtin| {
@@ -224,6 +228,36 @@ pub const Command = union(enum) {
},
.Remove => |remove| allocator.free(remove.path),
.Mkdir => |mkdir| allocator.free(mkdir.path),
+ .Deltree => |deltree| allocator.free(deltree.path),
+ .Tree => |tree| allocator.free(tree.path),
+ .Rmdir => |rmdir| allocator.free(rmdir.path),
+ .PathSet => |pathset| allocator.free(pathset.value),
+ .PromptSet => |promptset| allocator.free(promptset.message),
+ .Set => |set| {
+ allocator.free(set.name);
+ allocator.free(set.value);
+ },
+ .Rem => |rem| allocator.free(rem.message),
+ .Rename => |rename| {
+ switch (rename.from) {
+ .Path => |path| allocator.free(path),
+ else => {},
+ }
+ switch (rename.to) {
+ .Path => |path| allocator.free(path),
+ else => {},
+ }
+ },
+ .Xcopy => |xcopy| {
+ switch (xcopy.from) {
+ .Path => |path| allocator.free(path),
+ else => {},
+ }
+ switch (xcopy.to) {
+ .Path => |path| allocator.free(path),
+ else => {},
+ }
+ },
else => {},
}
},
@@ -485,7 +519,12 @@ const Parser = struct {
}
}
- return try self.parseBuiltinCommand(command_name, args);
+ const result = try self.parseBuiltinCommand(command_name, args);
+ // For builtin commands, free the args ArrayList (the strings inside belong to tokens and will be freed later)
+ if (result == .Builtin) {
+ args.deinit();
+ }
+ return result;
},
else => return error.UnexpectedToken,
}
@@ -565,8 +604,15 @@ const Parser = struct {
const path = try self.allocator.dupe(u8, args.items[0]);
return Command{ .Builtin = BuiltinCommand{ .Mkdir = .{ .path = path } } };
} else {
- // External command
- return Command{ .External = .{ .program = command_name, .args = args } };
+ // External command - need to duplicate all strings
+ const program_copy = try self.allocator.dupe(u8, command_name);
+ var args_copy = ArrayList([]const u8).init(self.allocator);
+ for (args.items) |arg| {
+ const arg_copy = try self.allocator.dupe(u8, arg);
+ try args_copy.append(arg_copy);
+ }
+ args.deinit(); // Free the original args list (but not the strings, as they belong to tokens)
+ return Command{ .External = .{ .program = program_copy, .args = args_copy } };
}
}
};