diff options
author | 2021-10-28 19:03:49 -0700 | |
---|---|---|
committer | 2021-10-28 19:03:49 -0700 | |
commit | 417c4e0faad886979ee162809ec70bc60d623b0d (patch) | |
tree | d651d1fd1cb52a7a5b65a5d9c75480db105676c9 | |
parent | b6675dd0abadbcd29c6ff10010fda1afefbc4559 (diff) | |
download | bun-417c4e0faad886979ee162809ec70bc60d623b0d.tar.gz bun-417c4e0faad886979ee162809ec70bc60d623b0d.tar.zst bun-417c4e0faad886979ee162809ec70bc60d623b0d.zip |
- Fix consistentcy issue with runtime hash
- Fix edgecases in strings.eqlComptime by simplifying the implementation
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | build.zig | 11 | ||||
-rw-r--r-- | src/cli/upgrade_command.zig | 27 | ||||
-rw-r--r-- | src/env.zig | 2 | ||||
-rw-r--r-- | src/runtime.version | 2 | ||||
-rw-r--r-- | src/string_immutable.zig | 187 |
6 files changed, 98 insertions, 135 deletions
@@ -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
\ No newline at end of file + USE_EXISTING_PROCESS=true TEST_SERVER_URL=http://localhost:3000 node integration/scripts/browser.js
\ No newline at end of file @@ -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); diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig index af6c4e97a..41349090a 100644 --- a/src/cli/upgrade_command.zig +++ b/src/cli/upgrade_command.zig @@ -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)); diff --git a/src/env.zig b/src/env.zig index 4dd26d56b..a24baa00b 100644 --- a/src/env.zig +++ b/src/env.zig @@ -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"; diff --git a/src/runtime.version b/src/runtime.version index ccfdfb532..0d5913bcd 100644 --- a/src/runtime.version +++ b/src/runtime.version @@ -1 +1 @@ -7be53da538434cb0
\ No newline at end of file +a85b24fd6904248e
\ No newline at end of file diff --git a/src/string_immutable.zig b/src/string_immutable.zig index fe4c52a99..4c41b1e63 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -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]); + switch (a.len) { + b.len => {}, + else => return false, + } + } - 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]); + 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 check_len) and self.len != alt.len) or first != std.mem.readIntNative(u64, self[0..8])) { + 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; - } - 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]); + comptime b_ptr += @sizeOf(u32); - 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; - } + if (comptime b_ptr == b.len) return true; + } + } - inline for (alt[13..]) |c, i| { - if (self[i + 13] != c) return false; - } + 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; - 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."); - }, + 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 { |