mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
- Fix consistentcy issue with runtime hash
- Fix edgecases in strings.eqlComptime by simplifying the implementation
This commit is contained in:
4
Makefile
4
Makefile
@@ -609,7 +609,7 @@ test-dev-no-hmr: copy-test-node-modules
|
||||
test-dev-bun-run:
|
||||
cd integration/apps && BUN_BIN=$(DEBUG_BUN) bash bun-run-check.sh
|
||||
|
||||
test-dev-all: test-dev-with-hmr test-dev-no-hmr test-dev-create-next text-dev-create-react test-dev-bun-run
|
||||
test-dev-all: test-dev-with-hmr test-dev-no-hmr test-dev-create-next test-dev-create-react test-dev-bun-run
|
||||
|
||||
test-dev: test-dev-with-hmr
|
||||
|
||||
@@ -806,4 +806,4 @@ run-unit:
|
||||
test: build-unit run-unit
|
||||
|
||||
integration-test-dev:
|
||||
USE_EXISTING_PROCESS=true node integration/scripts/browser.js
|
||||
USE_EXISTING_PROCESS=true TEST_SERVER_URL=http://localhost:3000 node integration/scripts/browser.js
|
||||
11
build.zig
11
build.zig
@@ -133,16 +133,21 @@ pub fn build(b: *std.build.Builder) !void {
|
||||
0,
|
||||
try runtime_out_file.readToEndAlloc(b.allocator, try runtime_out_file.getEndPos()),
|
||||
);
|
||||
const runtime_version_file = std.fs.cwd().openFile("src/runtime.version", .{ .write = true }) catch unreachable;
|
||||
runtime_version_file.writer().print("{x}", .{runtime_hash}) catch unreachable;
|
||||
const runtime_version_file = std.fs.cwd().createFile("src/runtime.version", .{ .truncate = true }) catch unreachable;
|
||||
defer runtime_version_file.close();
|
||||
runtime_version_file.writer().print("{x}", .{runtime_hash}) catch unreachable;
|
||||
var fallback_out_file = try std.fs.cwd().openFile("src/fallback.out.js", .{ .read = true });
|
||||
const fallback_hash = std.hash.Wyhash.hash(
|
||||
0,
|
||||
try fallback_out_file.readToEndAlloc(b.allocator, try fallback_out_file.getEndPos()),
|
||||
);
|
||||
const fallback_version_file = std.fs.cwd().openFile("src/fallback.version", .{ .write = true }) catch unreachable;
|
||||
|
||||
|
||||
|
||||
const fallback_version_file = std.fs.cwd().createFile("src/fallback.version", .{ .truncate = true }) catch unreachable;
|
||||
|
||||
fallback_version_file.writer().print("{x}", .{fallback_hash}) catch unreachable;
|
||||
|
||||
defer fallback_version_file.close();
|
||||
|
||||
exe.setTarget(target);
|
||||
|
||||
@@ -70,23 +70,25 @@ pub const Version = struct {
|
||||
};
|
||||
|
||||
pub const UpgradeCheckerThread = struct {
|
||||
var update_checker_thread: std.Thread = undefined;
|
||||
pub fn spawn(env_loader: *DotEnv.Loader) void {
|
||||
if (env_loader.map.get("BUN_DISABLE_UPGRADE_CHECK") != null or env_loader.map.get("CI") != null) return;
|
||||
var thread = std.Thread.spawn(.{}, run, .{env_loader}) catch return;
|
||||
thread.setName("Update Checker") catch {};
|
||||
thread.detach();
|
||||
update_checker_thread = std.Thread.spawn(.{}, run, .{env_loader}) catch return;
|
||||
update_checker_thread.detach();
|
||||
}
|
||||
|
||||
fn _run(env_loader: *DotEnv.Loader) anyerror!void {
|
||||
|
||||
var rand = std.rand.DefaultPrng.init(@intCast(u64, @maximum(std.time.milliTimestamp(), 0)));
|
||||
const delay = rand.random.intRangeAtMost(u64, 100, 10000);
|
||||
std.time.sleep(std.time.ns_per_ms * delay);
|
||||
|
||||
Output.Source.configureThread();
|
||||
|
||||
const version = (try UpgradeCommand.getLatestVersion(default_allocator, env_loader, undefined, undefined, true)) orelse return;
|
||||
|
||||
if (!version.isCurrent()) {
|
||||
if (version.name()) |name| {
|
||||
Output.Source.configureThread();
|
||||
Output.prettyErrorln("\n<r><d>Bun v{s} is out. Run <b><cyan>bun upgrade<r> to upgrade.\n", .{name});
|
||||
Output.flush();
|
||||
}
|
||||
@@ -272,14 +274,27 @@ pub const UpgradeCommand = struct {
|
||||
while (assets.next()) |asset| {
|
||||
if (asset.asProperty("content_type")) |content_type| {
|
||||
const content_type_ = (content_type.expr.asString(allocator)) orelse continue;
|
||||
if (!strings.eqlComptime(content_type, "application/zip")) continue;
|
||||
if (comptime isDebug) {
|
||||
Output.prettyln("Content-type: {s}", .{content_type_});
|
||||
Output.flush();
|
||||
}
|
||||
|
||||
if (!strings.eqlComptime(content_type_, "application/zip")) continue;
|
||||
}
|
||||
|
||||
if (asset.asProperty("name")) |name_| {
|
||||
if (name_.expr.asString(allocator)) |name| {
|
||||
if (comptime isDebug) {
|
||||
Output.prettyln("Comparing {s} vs {s}", .{name, Version.zip_filename});
|
||||
Output.flush();
|
||||
}
|
||||
if (strings.eqlComptime(name, Version.zip_filename)) {
|
||||
version.zip_url = (asset.asProperty("browser_download_url") orelse break :get_asset).expr.asString(allocator) orelse break :get_asset;
|
||||
|
||||
if (comptime isDebug) {
|
||||
Output.prettyln("Found Zip {s}", .{version.zip_url});
|
||||
Output.flush();
|
||||
}
|
||||
|
||||
if (asset.asProperty("size")) |size_| {
|
||||
if (size_.expr.data == .e_number) {
|
||||
version.size = @intCast(u32, @maximum(@floatToInt(i32, std.math.ceil(size_.expr.data.e_number.value)), 0));
|
||||
|
||||
@@ -21,6 +21,6 @@ pub const isDebug = std.builtin.Mode.Debug == std.builtin.mode;
|
||||
pub const isRelease = std.builtin.Mode.Debug != std.builtin.mode and !isTest;
|
||||
pub const isTest = std.builtin.is_test;
|
||||
pub const isLinux = std.Target.current.os.tag == .linux;
|
||||
pub const isAarch64 = std.Target.current.cpu.arch == .aarch64;
|
||||
pub const isAarch64 = std.Target.current.cpu.arch.isAARCH64();
|
||||
|
||||
pub const analytics_url = if (isDebug) "http://localhost:4000/events" else "http://i.bun.sh/events";
|
||||
|
||||
@@ -1 +1 @@
|
||||
7be53da538434cb0
|
||||
a85b24fd6904248e
|
||||
@@ -175,6 +175,31 @@ pub fn copyLowercase(in: string, out: []u8) string {
|
||||
return out[0..in.len];
|
||||
}
|
||||
|
||||
test "eqlComptimeCheckLen" {
|
||||
try std.testing.expectEqual(eqlComptime("bun-darwin-aarch64.zip", "bun-darwin-aarch64.zip"), true);
|
||||
const sizes = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 23, 22, 24 };
|
||||
inline for (sizes) |size| {
|
||||
var buf: [size]u8 = undefined;
|
||||
std.mem.set(u8, &buf, 'a');
|
||||
var buf_copy: [size]u8 = undefined;
|
||||
std.mem.set(u8, &buf_copy, 'a');
|
||||
|
||||
var bad: [size]u8 = undefined;
|
||||
std.mem.set(u8, &bad, 'b');
|
||||
try std.testing.expectEqual(std.mem.eql(u8, &buf, &buf_copy), eqlComptime(&buf, comptime brk: {
|
||||
var buf_copy_: [size]u8 = undefined;
|
||||
std.mem.set(u8, &buf_copy_, 'a');
|
||||
break :brk buf_copy_;
|
||||
}));
|
||||
|
||||
try std.testing.expectEqual(std.mem.eql(u8, &buf, &bad), eqlComptime(&bad, comptime brk: {
|
||||
var buf_copy_: [size]u8 = undefined;
|
||||
std.mem.set(u8, &buf_copy_, 'a');
|
||||
break :brk buf_copy_;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
test "copyLowercase" {
|
||||
{
|
||||
var in = "Hello, World!";
|
||||
@@ -324,137 +349,55 @@ pub fn eqlComptimeIgnoreLen(self: string, comptime alt: anytype) bool {
|
||||
return eqlComptimeCheckLen(self, alt, false);
|
||||
}
|
||||
|
||||
inline fn eqlComptimeCheckLen(self: string, comptime alt: anytype, comptime check_len: bool) bool {
|
||||
switch (comptime alt.len) {
|
||||
0 => {
|
||||
@compileError("Invalid size passed to eqlComptime");
|
||||
},
|
||||
2 => {
|
||||
const check = comptime std.mem.readIntNative(u16, alt[0..alt.len]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and std.mem.readIntNative(u16, self[0..2]) == check;
|
||||
},
|
||||
1, 3 => {
|
||||
if ((comptime check_len) and alt.len != self.len) {
|
||||
return false;
|
||||
}
|
||||
inline fn eqlComptimeCheckLen(a: string, comptime b: anytype, comptime check_len: bool) bool {
|
||||
if (comptime check_len) {
|
||||
if (comptime b.len == 0) {
|
||||
return a.len == 0;
|
||||
}
|
||||
|
||||
inline for (alt) |c, i| {
|
||||
if (self[i] != c) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
4 => {
|
||||
const check = comptime std.mem.readIntNative(u32, alt[0..alt.len]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and std.mem.readIntNative(u32, self[0..4]) == check;
|
||||
},
|
||||
6 => {
|
||||
const first = std.mem.readIntNative(u32, alt[0..4]);
|
||||
const second = std.mem.readIntNative(u16, alt[4..6]);
|
||||
|
||||
return self.len == alt.len and first == std.mem.readIntNative(u32, self[0..4]) and
|
||||
second == std.mem.readIntNative(u16, self[4..6]);
|
||||
},
|
||||
5, 7 => {
|
||||
const check = comptime std.mem.readIntNative(u32, alt[0..4]);
|
||||
if (((comptime check_len) and
|
||||
self.len != alt.len) or
|
||||
std.mem.readIntNative(u32, self[0..4]) != check)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const remainder = self[4..];
|
||||
inline for (alt[4..]) |c, i| {
|
||||
if (remainder[i] != c) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
8 => {
|
||||
const check = comptime std.mem.readIntNative(u64, alt[0..alt.len]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and std.mem.readIntNative(u64, self[0..8]) == check;
|
||||
},
|
||||
9...11 => {
|
||||
const first = std.mem.readIntNative(u64, alt[0..8]);
|
||||
|
||||
if (((comptime check_len) and self.len != alt.len) or first != std.mem.readIntNative(u64, self[0..8])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline for (alt[8..]) |c, i| {
|
||||
if (self[i + 8] != c) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
12 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u32, alt[8..12]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and first == std.mem.readIntNative(u64, self[0..8]) and second == std.mem.readIntNative(u32, self[8..12]);
|
||||
},
|
||||
13...15 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u32, alt[8..12]);
|
||||
|
||||
if (((comptime !check_len) or self.len != alt.len) or first != std.mem.readIntNative(u64, self[0..8]) or second != std.mem.readIntNative(u32, self[8..12])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline for (alt[13..]) |c, i| {
|
||||
if (self[i + 13] != c) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
16 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u64, alt[8..16]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and first == std.mem.readIntNative(u64, self[0..8]) and second == std.mem.readIntNative(u64, self[8..16]);
|
||||
},
|
||||
17 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u64, alt[8..16]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and
|
||||
first == std.mem.readIntNative(u64, self[0..8]) and second ==
|
||||
std.mem.readIntNative(u64, self[8..16]) and
|
||||
alt[16] == self[16];
|
||||
},
|
||||
18 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u64, alt[8..16]);
|
||||
const third = comptime std.mem.readIntNative(u16, alt[16..18]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and
|
||||
first == std.mem.readIntNative(u64, self[0..8]) and second ==
|
||||
std.mem.readIntNative(u64, self[8..16]) and
|
||||
std.mem.readIntNative(u16, self[16..18]) == third;
|
||||
},
|
||||
23 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u64, alt[8..16]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and
|
||||
first == std.mem.readIntNative(u64, self[0..8]) and
|
||||
second == std.mem.readIntNative(u64, self[8..16]) and
|
||||
eqlComptimeIgnoreLen(self[16..23], comptime alt[16..23]);
|
||||
},
|
||||
22 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u64, alt[8..16]);
|
||||
|
||||
return ((comptime !check_len) or self.len == alt.len) and
|
||||
first == std.mem.readIntNative(u64, self[0..8]) and
|
||||
second == std.mem.readIntNative(u64, self[8..16]) and
|
||||
eqlComptimeIgnoreLen(self[16..22], comptime alt[16..22]);
|
||||
},
|
||||
24 => {
|
||||
const first = comptime std.mem.readIntNative(u64, alt[0..8]);
|
||||
const second = comptime std.mem.readIntNative(u64, alt[8..16]);
|
||||
const third = comptime std.mem.readIntNative(u64, alt[16..24]);
|
||||
return ((comptime !check_len) or self.len == alt.len) and
|
||||
first == std.mem.readIntNative(u64, self[0..8]) and
|
||||
second == std.mem.readIntNative(u64, self[8..16]) and
|
||||
third == std.mem.readIntNative(u64, self[16..24]);
|
||||
},
|
||||
else => {
|
||||
@compileError(alt ++ " is too long.");
|
||||
},
|
||||
switch (a.len) {
|
||||
b.len => {},
|
||||
else => return false,
|
||||
}
|
||||
}
|
||||
|
||||
const len = comptime b.len;
|
||||
comptime var dword_length = b.len >> 3;
|
||||
comptime var b_ptr: usize = 0;
|
||||
|
||||
inline while (dword_length > 0) : (dword_length -= 1) {
|
||||
const slice = comptime if (@typeInfo(@TypeOf(b)) != .Pointer) b else std.mem.span(b);
|
||||
if (@bitCast(usize, a[b_ptr..][0..@sizeOf(usize)].*) != comptime @bitCast(usize, (slice[b_ptr..])[0..@sizeOf(usize)].*))
|
||||
return false;
|
||||
comptime b_ptr += @sizeOf(usize);
|
||||
if (comptime b_ptr == b.len) return true;
|
||||
}
|
||||
|
||||
if (comptime @sizeOf(usize) == 8) {
|
||||
if (comptime (len & 4) != 0) {
|
||||
const slice = comptime if (@typeInfo(@TypeOf(b)) != .Pointer) b else std.mem.span(b);
|
||||
if (@bitCast(u32, a[b_ptr..][0..@sizeOf(u32)].*) != comptime @bitCast(u32, (slice[b_ptr..])[0..@sizeOf(u32)].*))
|
||||
return false;
|
||||
|
||||
comptime b_ptr += @sizeOf(u32);
|
||||
|
||||
if (comptime b_ptr == b.len) return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (comptime (len & 2) != 0) {
|
||||
const slice = comptime if (@typeInfo(@TypeOf(b)) != .Pointer) b else std.mem.span(b);
|
||||
if (@bitCast(u16, a[b_ptr..][0..@sizeOf(u16)].*) != comptime @bitCast(u16, slice[b_ptr .. b_ptr + @sizeOf(u16)].*))
|
||||
return false;
|
||||
|
||||
comptime b_ptr += @sizeOf(u16);
|
||||
|
||||
if (comptime b_ptr == b.len) return true;
|
||||
}
|
||||
|
||||
if ((comptime ( len & 1) != 0) and a[b_ptr] != comptime b[b_ptr]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub inline fn append(allocator: *std.mem.Allocator, self: string, other: string) !string {
|
||||
|
||||
Reference in New Issue
Block a user