diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2025-06-19 17:54:25 -0400 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2025-06-19 18:41:11 -0400 |
| commit | e92b12906338207975ee73aa99db63cb9240bf04 (patch) | |
| tree | 6fa7801d2b900d02067f48d700f8d9194be384f9 /src/Compilation.zig | |
| parent | 917640810e7f3e18daff9e75b5ecefe761a1896c (diff) | |
| download | zig-e92b12906338207975ee73aa99db63cb9240bf04.tar.gz zig-e92b12906338207975ee73aa99db63cb9240bf04.zip | |
Compilation: fix use after free
Closes #23967
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 402a3f9761..e0f8cf5a56 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1990,9 +1990,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil }; errdefer if (opt_zcu) |zcu| zcu.deinit(); - var windows_libs = try std.StringArrayHashMapUnmanaged(void).init(gpa, options.windows_lib_names, &.{}); - errdefer windows_libs.deinit(gpa); - comp.* = .{ .gpa = gpa, .arena = arena, @@ -2037,7 +2034,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil .incremental = options.incremental, .root_name = root_name, .sysroot = sysroot, - .windows_libs = windows_libs, + .windows_libs = .empty, .version = options.version, .libc_installation = libc_dirs.libc_installation, .compiler_rt_strat = compiler_rt_strat, @@ -2065,6 +2062,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil .emit_docs = try options.emit_docs.resolve(arena, &options, .docs), }; + errdefer { + for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib); + comp.windows_libs.deinit(gpa); + } + try comp.windows_libs.ensureUnusedCapacity(gpa, options.windows_lib_names.len); + for (options.windows_lib_names) |windows_lib| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, windows_lib), {}); + // Prevent some footguns by making the "any" fields of config reflect // the default Module settings. comp.config.any_unwind_tables = any_unwind_tables; @@ -2387,7 +2391,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil // When linking mingw-w64 there are some import libs we always need. try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len); - for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {}); + for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {}); } else { return error.LibCUnavailable; } @@ -2480,6 +2484,7 @@ pub fn destroy(comp: *Compilation) void { comp.c_object_work_queue.deinit(); comp.win32_resource_work_queue.deinit(); + for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib); comp.windows_libs.deinit(gpa); { @@ -7563,7 +7568,12 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { // If we haven't seen this library yet and we're targeting Windows, we need // to queue up a work item to produce the DLL import library for this. const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name); - if (!gop.found_existing) try comp.queueJob(.{ .windows_import_lib = comp.windows_libs.count() - 1 }); + if (gop.found_existing) return; + { + errdefer _ = comp.windows_libs.pop(); + gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name); + } + try comp.queueJob(.{ .windows_import_lib = gop.index }); } /// This decides the optimization mode for all zig-provided libraries, including |
