Skip to content

Commit e92b129

Browse files
committed
Compilation: fix use after free
Closes #23967
1 parent 9176408 commit e92b129

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/Compilation.zig

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,9 +1990,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
19901990
};
19911991
errdefer if (opt_zcu) |zcu| zcu.deinit();
19921992

1993-
var windows_libs = try std.StringArrayHashMapUnmanaged(void).init(gpa, options.windows_lib_names, &.{});
1994-
errdefer windows_libs.deinit(gpa);
1995-
19961993
comp.* = .{
19971994
.gpa = gpa,
19981995
.arena = arena,
@@ -2037,7 +2034,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
20372034
.incremental = options.incremental,
20382035
.root_name = root_name,
20392036
.sysroot = sysroot,
2040-
.windows_libs = windows_libs,
2037+
.windows_libs = .empty,
20412038
.version = options.version,
20422039
.libc_installation = libc_dirs.libc_installation,
20432040
.compiler_rt_strat = compiler_rt_strat,
@@ -2065,6 +2062,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
20652062
.emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
20662063
};
20672064

2065+
errdefer {
2066+
for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
2067+
comp.windows_libs.deinit(gpa);
2068+
}
2069+
try comp.windows_libs.ensureUnusedCapacity(gpa, options.windows_lib_names.len);
2070+
for (options.windows_lib_names) |windows_lib| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, windows_lib), {});
2071+
20682072
// Prevent some footguns by making the "any" fields of config reflect
20692073
// the default Module settings.
20702074
comp.config.any_unwind_tables = any_unwind_tables;
@@ -2387,7 +2391,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
23872391

23882392
// When linking mingw-w64 there are some import libs we always need.
23892393
try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
2390-
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
2394+
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {});
23912395
} else {
23922396
return error.LibCUnavailable;
23932397
}
@@ -2480,6 +2484,7 @@ pub fn destroy(comp: *Compilation) void {
24802484
comp.c_object_work_queue.deinit();
24812485
comp.win32_resource_work_queue.deinit();
24822486

2487+
for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
24832488
comp.windows_libs.deinit(gpa);
24842489

24852490
{
@@ -7563,7 +7568,12 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
75637568
// If we haven't seen this library yet and we're targeting Windows, we need
75647569
// to queue up a work item to produce the DLL import library for this.
75657570
const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
7566-
if (!gop.found_existing) try comp.queueJob(.{ .windows_import_lib = comp.windows_libs.count() - 1 });
7571+
if (gop.found_existing) return;
7572+
{
7573+
errdefer _ = comp.windows_libs.pop();
7574+
gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
7575+
}
7576+
try comp.queueJob(.{ .windows_import_lib = gop.index });
75677577
}
75687578

75697579
/// This decides the optimization mode for all zig-provided libraries, including

0 commit comments

Comments
 (0)