Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
25d15d6544 One less system call to verify patch files 2024-10-20 16:55:04 -07:00
Jarred Sumner
004111cfff Fixes #14701 2024-10-20 15:45:28 -07:00
3 changed files with 60 additions and 59 deletions

View File

@@ -61,21 +61,22 @@ const Walker = @import("../walker_skippable.zig");
const anyhow = bun.anyhow;
pub const bun_hash_tag = ".bun-tag-";
pub const max_hex_hash_len: comptime_int = brk: {
var buf: [128]u8 = undefined;
break :brk (std.fmt.bufPrint(buf[0..], "{x}", .{std.math.maxInt(u64)}) catch @panic("Buf wasn't big enough.")).len;
};
pub const max_buntag_hash_buf_len: comptime_int = max_hex_hash_len + bun_hash_tag.len + 1;
pub const BuntagHashBuf = [max_buntag_hash_buf_len]u8;
pub const BunTagFile = struct {
const bun_hash_tag = ".bun-tag-";
const max_hex_hash_len: comptime_int = brk: {
var buf: [128]u8 = undefined;
break :brk (std.fmt.bufPrint(buf[0..], "{x}", .{std.math.maxInt(u64)}) catch @panic("Buf wasn't big enough.")).len;
};
pub const Buffer = [max_hex_hash_len * 2]u8;
pub fn buntaghashbuf_make(buf: *BuntagHashBuf, patch_hash: u64) [:0]u8 {
@memcpy(buf[0..bun_hash_tag.len], bun_hash_tag);
const digits = std.fmt.bufPrint(buf[bun_hash_tag.len..], "{x}", .{patch_hash}) catch bun.outOfMemory();
buf[bun_hash_tag.len + digits.len] = 0;
const bunhashtag = buf[0 .. bun_hash_tag.len + digits.len :0];
return bunhashtag;
}
pub fn path(buf: *Buffer, patch_hash: u64) [:0]u8 {
@memcpy(buf[0..bun_hash_tag.len], bun_hash_tag);
const digits = std.fmt.bufPrint(buf[bun_hash_tag.len..], "{x}", .{patch_hash}) catch bun.outOfMemory();
buf[bun_hash_tag.len + digits.len] = 0;
const bunhashtag = buf[0 .. bun_hash_tag.len + digits.len :0];
return bunhashtag;
}
};
pub const patch = @import("./patch_install.zig");
pub const PatchTask = patch.PatchTask;
@@ -1079,29 +1080,28 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type {
bun.debugAssert(!this.patch.isNull());
// hash from the .patch file, to be checked against bun tag
const patchfile_contents_hash = this.patch.patch_contents_hash;
var buf: BuntagHashBuf = undefined;
const bunhashtag = buntaghashbuf_make(&buf, patchfile_contents_hash);
var patch_buf: BunTagFile.Buffer = undefined;
const tag_filename = BunTagFile.path(&patch_buf, this.patch.patch_contents_hash);
const patch_tag_path = bun.path.joinZ(&[_][]const u8{
this.destination_dir_subpath,
bunhashtag,
}, .posix);
if (comptime bun.Environment.isPosix) {
const patch_tag_path = bun.path.joinZ(
&[_][]const u8{
this.node_modules.path.items,
this.destination_dir_subpath,
tag_filename,
},
.auto,
);
return bun.sys.existsAt(bun.toFD(root_node_modules_dir.fd), patch_tag_path);
}
var destination_dir = this.node_modules.openDir(root_node_modules_dir) catch return false;
defer {
if (std.fs.cwd().fd != destination_dir.fd) destination_dir.close();
destination_dir.close();
}
if (comptime bun.Environment.isPosix) {
_ = bun.sys.fstatat(bun.toFD(destination_dir.fd), patch_tag_path).unwrap() catch return false;
} else {
switch (bun.sys.openat(bun.toFD(destination_dir.fd), patch_tag_path, bun.O.RDONLY, 0)) {
.err => return false,
.result => |fd| _ = bun.sys.close(fd),
}
}
return true;
return bun.sys.existsAt(bun.toFD(destination_dir.fd), tag_filename);
}
// 1. verify that .bun-tag exists (was it installed from bun?)
@@ -11598,7 +11598,7 @@ pub const PackageManager = struct {
Global.crash();
});
var bunpatchtagbuf: BuntagHashBuf = undefined;
var bunpatchtagbuf: BunTagFile.Buffer = undefined;
// If the package was already patched then it might have a ".bun-tag-XXXXXXXX"
// we need to rename this out and back too.
const bun_patch_tag: ?[:0]const u8 = has_bun_patch_tag: {
@@ -11606,7 +11606,7 @@ pub const PackageManager = struct {
const patch_tag = patch_tag: {
if (lockfile.patched_dependencies.get(name_and_version_hash)) |patchdep| {
if (patchdep.patchfileHash()) |hash| {
break :patch_tag buntaghashbuf_make(&bunpatchtagbuf, hash);
break :patch_tag BunTagFile.path(&bunpatchtagbuf, hash);
}
}
break :has_bun_patch_tag null;
@@ -14048,21 +14048,28 @@ pub const PackageManager = struct {
const all_name_hashes: []PackageNameHash = brk: {
if (!manager.summary.overrides_changed) break :brk &.{};
const hashes_len = manager.lockfile.overrides.map.entries.len + lockfile.overrides.map.entries.len;
const original_keys = manager.lockfile.overrides.map.keys();
const new_keys = lockfile.overrides.map.keys();
const hashes_len = original_keys.len + new_keys.len;
if (hashes_len == 0) break :brk &.{};
var all_name_hashes = try bun.default_allocator.alloc(PackageNameHash, hashes_len);
@memcpy(all_name_hashes[0..manager.lockfile.overrides.map.entries.len], manager.lockfile.overrides.map.keys());
@memcpy(all_name_hashes[manager.lockfile.overrides.map.entries.len..], lockfile.overrides.map.keys());
var i = manager.lockfile.overrides.map.entries.len;
while (i < all_name_hashes.len) {
if (std.mem.indexOfScalar(PackageNameHash, all_name_hashes[0..i], all_name_hashes[i]) != null) {
all_name_hashes[i] = all_name_hashes[all_name_hashes.len - 1];
all_name_hashes.len -= 1;
} else {
i += 1;
var outlen: usize = 0;
for (original_keys) |key| {
if (std.mem.indexOfScalar(PackageNameHash, all_name_hashes[0..outlen], key) == null) {
all_name_hashes[outlen] = key;
outlen += 1;
}
}
break :brk all_name_hashes;
for (new_keys) |key| {
if (std.mem.indexOfScalar(PackageNameHash, all_name_hashes[0..outlen], key) == null) {
all_name_hashes[outlen] = key;
outlen += 1;
}
}
break :brk all_name_hashes[0..outlen];
};
manager.lockfile.overrides = try lockfile.overrides.clone(&lockfile, manager.lockfile, builder);

View File

@@ -31,13 +31,7 @@ pub const PreparePatchPackageInstall = bun.install.PreparePatchPackageInstall;
const Fs = @import("../fs.zig");
const FileSystem = Fs.FileSystem;
pub const bun_hash_tag = bun.install.bun_hash_tag;
pub const max_hex_hash_len: comptime_int = brk: {
var buf: [128]u8 = undefined;
break :brk (std.fmt.bufPrint(buf[0..], "{x}", .{std.math.maxInt(u64)}) catch @panic("Buf wasn't big enough.")).len;
};
pub const max_buntag_hash_buf_len: comptime_int = max_hex_hash_len + bun_hash_tag.len + 1;
pub const BuntagHashBuf = [max_buntag_hash_buf_len]u8;
const BunTagFile = bun.install.BunTagFile;
pub const PatchTask = struct {
manager: *PackageManager,
@@ -354,20 +348,17 @@ pub const PatchTask = struct {
}
// 5. Add bun tag
const bun_tag_prefix = bun_hash_tag;
var buntagbuf: BuntagHashBuf = undefined;
@memcpy(buntagbuf[0..bun_tag_prefix.len], bun_tag_prefix);
const hashlen = (std.fmt.bufPrint(buntagbuf[bun_tag_prefix.len..], "{x}", .{this.callback.apply.patch_hash}) catch unreachable).len;
buntagbuf[bun_tag_prefix.len + hashlen] = 0;
var buntagbuf: BunTagFile.Buffer = undefined;
const bun_tag_hash = BunTagFile.path(&buntagbuf, this.callback.apply.patch_hash);
const buntagfd = switch (bun.sys.openat(
bun.toFD(patch_pkg_dir.fd),
buntagbuf[0 .. bun_tag_prefix.len + hashlen :0],
bun_tag_hash,
bun.O.RDWR | bun.O.CREAT,
0o666,
)) {
.result => |fd| fd,
.err => |e| {
return try log.addErrorFmtNoLoc(this.manager.allocator, "failed adding bun tag: {}", .{e.withPath(buntagbuf[0 .. bun_tag_prefix.len + hashlen :0])});
return try log.addErrorFmtNoLoc(this.manager.allocator, "failed adding bun tag: {}", .{e.withPath(bun_tag_hash)});
},
};
_ = bun.sys.close(buntagfd);

View File

@@ -2585,7 +2585,10 @@ pub fn setNonblocking(fd: bun.FileDescriptor) Maybe(void) {
pub fn existsAt(fd: bun.FileDescriptor, subpath: [:0]const u8) bool {
if (comptime Environment.isPosix) {
return faccessat(fd, subpath).result;
return switch (faccessat(fd, subpath)) {
.err => false,
.result => |result| result,
};
}
if (comptime Environment.isWindows) {