fix: fix memory leaks related to updating config variables

adds an edge case in analysis.makeScopeInternal to prevent
leaking memory when adding duplicate container fields w/ name "other"
This commit is contained in:
nullptrdevs 2022-08-21 17:11:50 -07:00
parent 3e20a7a50b
commit 2c5ae262f7
3 changed files with 12 additions and 12 deletions

View File

@ -200,22 +200,18 @@ pub fn configChanged(config: *Config, allocator: std.mem.Allocator, builtin_crea
config.builtin_path = try std.fs.path.join(allocator, &.{ builtin_creation_dir.?, "builtin.zig" }); config.builtin_path = try std.fs.path.join(allocator, &.{ builtin_creation_dir.?, "builtin.zig" });
} }
config.build_runner_path = if (config.build_runner_path) |p| if (null == config.build_runner_path) {
try allocator.dupe(u8, p)
else blk: {
var exe_dir_bytes: [std.fs.MAX_PATH_BYTES]u8 = undefined; var exe_dir_bytes: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const exe_dir_path = try std.fs.selfExeDirPath(&exe_dir_bytes); const exe_dir_path = try std.fs.selfExeDirPath(&exe_dir_bytes);
break :blk try std.fs.path.resolve(allocator, &[_][]const u8{ exe_dir_path, "build_runner.zig" }); config.build_runner_path = try std.fs.path.resolve(allocator, &[_][]const u8{ exe_dir_path, "build_runner.zig" });
}; }
config.global_cache_path = if (config.global_cache_path) |p| if (null == config.global_cache_path) {
try allocator.dupe(u8, p)
else blk: {
const cache_dir_path = (try known_folders.getPath(allocator, .cache)) orelse { const cache_dir_path = (try known_folders.getPath(allocator, .cache)) orelse {
logger.warn("Known-folders could not fetch the cache path", .{}); logger.warn("Known-folders could not fetch the cache path", .{});
return; return;
}; };
defer allocator.free(cache_dir_path); defer allocator.free(cache_dir_path);
break :blk try std.fs.path.resolve(allocator, &[_][]const u8{ cache_dir_path, "zls" }); config.global_cache_path = try std.fs.path.resolve(allocator, &[_][]const u8{ cache_dir_path, "zls" });
}; }
} }

View File

@ -2440,7 +2440,11 @@ pub fn processJsonRpc(server: *Server, writer: anytype, json: []const u8) !void
if (value != .Null) { if (value != .Null) {
const new_value: field.field_type = switch (ft) { const new_value: field.field_type = switch (ft) {
[]const u8 => switch (value) { []const u8 => switch (value) {
.String => |s| try server.allocator.dupe(u8, s), // TODO: Allocation model? (same with didChangeConfiguration); imo this isn't *that* bad but still .String => |s| blk: {
var nv = try server.allocator.dupe(u8, s);
server.allocator.free(@field(server.config, field.name).?);
break :blk nv;
}, // TODO: Allocation model? (same with didChangeConfiguration); imo this isn't *that* bad but still
else => @panic("Invalid configuration value"), // TODO: Handle this else => @panic("Invalid configuration value"), // TODO: Handle this
}, },
else => switch (ti) { else => switch (ti) {

View File

@ -2542,7 +2542,7 @@ fn makeInnerScope(allocator: std.mem.Allocator, context: ScopeContext, node_idx:
}; };
if (container_field) |_| { if (container_field) |_| {
if (!std.mem.eql(u8, name, "_")) { if (!std.mem.eql(u8, name, "_") and !std.mem.eql(u8, name, "other")) {
try context.enums.put(allocator, .{ try context.enums.put(allocator, .{
.label = name, .label = name,
.kind = .Constant, .kind = .Constant,