mirror of
https://github.com/oven-sh/bun
synced 2026-02-13 12:29:07 +00:00
Add Windows PE codesigning support for standalone executables (#21091)
Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
This commit is contained in:
committed by
GitHub
parent
0ce70df96b
commit
32ce9a3890
@@ -13,6 +13,7 @@ const SourceMap = bun.sourcemap;
|
||||
const StringPointer = bun.StringPointer;
|
||||
|
||||
const macho = bun.macho;
|
||||
const pe = bun.pe;
|
||||
const w = std.os.windows;
|
||||
|
||||
pub const StandaloneModuleGraph = struct {
|
||||
@@ -137,6 +138,19 @@ pub const StandaloneModuleGraph = struct {
|
||||
}
|
||||
};
|
||||
|
||||
const PE = struct {
|
||||
pub extern "C" fn Bun__getStandaloneModuleGraphPELength() u32;
|
||||
pub extern "C" fn Bun__getStandaloneModuleGraphPEData() ?[*]u8;
|
||||
|
||||
pub fn getData() ?[]const u8 {
|
||||
const length = Bun__getStandaloneModuleGraphPELength();
|
||||
if (length == 0) return null;
|
||||
|
||||
const data_ptr = Bun__getStandaloneModuleGraphPEData() orelse return null;
|
||||
return data_ptr[0..length];
|
||||
}
|
||||
};
|
||||
|
||||
pub const File = struct {
|
||||
name: []const u8 = "",
|
||||
loader: bun.options.Loader,
|
||||
@@ -682,6 +696,44 @@ pub const StandaloneModuleGraph = struct {
|
||||
}
|
||||
return cloned_executable_fd;
|
||||
},
|
||||
.windows => {
|
||||
const input_result = bun.sys.File.readToEnd(.{ .handle = cloned_executable_fd }, bun.default_allocator);
|
||||
if (input_result.err) |err| {
|
||||
Output.prettyErrorln("Error reading standalone module graph: {}", .{err});
|
||||
cleanup(zname, cloned_executable_fd);
|
||||
Global.exit(1);
|
||||
}
|
||||
var pe_file = bun.pe.PEFile.init(bun.default_allocator, input_result.bytes.items) catch |err| {
|
||||
Output.prettyErrorln("Error initializing PE file: {}", .{err});
|
||||
cleanup(zname, cloned_executable_fd);
|
||||
Global.exit(1);
|
||||
};
|
||||
defer pe_file.deinit();
|
||||
pe_file.addBunSection(bytes) catch |err| {
|
||||
Output.prettyErrorln("Error adding Bun section to PE file: {}", .{err});
|
||||
cleanup(zname, cloned_executable_fd);
|
||||
Global.exit(1);
|
||||
};
|
||||
input_result.bytes.deinit();
|
||||
|
||||
switch (Syscall.setFileOffset(cloned_executable_fd, 0)) {
|
||||
.err => |err| {
|
||||
Output.prettyErrorln("Error seeking to start of temporary file: {}", .{err});
|
||||
cleanup(zname, cloned_executable_fd);
|
||||
Global.exit(1);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
var file = bun.sys.File{ .handle = cloned_executable_fd };
|
||||
const writer = file.writer();
|
||||
pe_file.write(writer) catch |err| {
|
||||
Output.prettyErrorln("Error writing PE file: {}", .{err});
|
||||
cleanup(zname, cloned_executable_fd);
|
||||
Global.exit(1);
|
||||
};
|
||||
return cloned_executable_fd;
|
||||
},
|
||||
else => {
|
||||
var total_byte_count: usize = undefined;
|
||||
if (Environment.isWindows) {
|
||||
@@ -888,6 +940,22 @@ pub const StandaloneModuleGraph = struct {
|
||||
return try StandaloneModuleGraph.fromBytes(allocator, @constCast(macho_bytes), offsets);
|
||||
}
|
||||
|
||||
if (comptime Environment.isWindows) {
|
||||
const pe_bytes = PE.getData() orelse return null;
|
||||
if (pe_bytes.len < @sizeOf(Offsets) + trailer.len) {
|
||||
Output.debugWarn("bun standalone module graph is too small to be valid", .{});
|
||||
return null;
|
||||
}
|
||||
const pe_bytes_slice = pe_bytes[pe_bytes.len - @sizeOf(Offsets) - trailer.len ..];
|
||||
const trailer_bytes = pe_bytes[pe_bytes.len - trailer.len ..][0..trailer.len];
|
||||
if (!bun.strings.eqlComptime(trailer_bytes, trailer)) {
|
||||
Output.debugWarn("bun standalone module graph has invalid trailer", .{});
|
||||
return null;
|
||||
}
|
||||
const offsets = std.mem.bytesAsValue(Offsets, pe_bytes_slice).*;
|
||||
return try StandaloneModuleGraph.fromBytes(allocator, @constCast(pe_bytes), offsets);
|
||||
}
|
||||
|
||||
// Do not invoke libuv here.
|
||||
const self_exe = openSelf() catch return null;
|
||||
defer self_exe.close();
|
||||
|
||||
Reference in New Issue
Block a user