aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ai Hoshino <ambiguous404@gmail.com> 2023-07-09 22:20:52 +0800
committerGravatar GitHub <noreply@github.com> 2023-07-09 07:20:52 -0700
commit565d1689e9f2c1f6b657f14b07fa9b95e50a5a56 (patch)
tree8534cb81892929de7846b9cdc2056ce68d02e5a9
parent59570fe237f91dd04ce8f37779902cffa4352010 (diff)
downloadbun-565d1689e9f2c1f6b657f14b07fa9b95e50a5a56.tar.gz
bun-565d1689e9f2c1f6b657f14b07fa9b95e50a5a56.tar.zst
bun-565d1689e9f2c1f6b657f14b07fa9b95e50a5a56.zip
fix metadata bits of uuid (`randomUUID()`) (#3583)
* fix uuid version Close: https://github.com/oven-sh/bun/issues/3575 * add unittest * small fix * avoid unnecessary copying
-rw-r--r--src/bun.js/rare_data.zig8
-rw-r--r--src/bun.js/uuid.zig10
-rw-r--r--src/bun.js/webcore.zig11
-rw-r--r--src/bun.js/webcore/blob.zig2
-rw-r--r--src/http/websocket_http_client.zig2
-rw-r--r--test/js/web/web-globals.test.js19
6 files changed, 41 insertions, 11 deletions
diff --git a/src/bun.js/rare_data.zig b/src/bun.js/rare_data.zig
index ddda96bf4..3b29896a4 100644
--- a/src/bun.js/rare_data.zig
+++ b/src/bun.js/rare_data.zig
@@ -9,6 +9,7 @@ const std = @import("std");
const BoringSSL = @import("root").bun.BoringSSL;
const bun = @import("root").bun;
const WebSocketClientMask = @import("../http/websocket_http_client.zig").Mask;
+const UUID = @import("./uuid.zig");
boring_ssl_engine: ?*BoringSSL.ENGINE = null,
editor_context: EditorContext = EditorContext{},
@@ -47,13 +48,16 @@ pub fn filePolls(this: *RareData, vm: *JSC.VirtualMachine) *JSC.FilePoll.HiveArr
};
}
-pub fn nextUUID(this: *RareData) [16]u8 {
+pub fn nextUUID(this: *RareData) UUID {
if (this.entropy_cache == null) {
this.entropy_cache = default_allocator.create(EntropyCache) catch unreachable;
this.entropy_cache.?.init();
}
- return this.entropy_cache.?.get();
+ this.entropy_cache.?.fill();
+
+ const bytes = this.entropy_cache.?.get();
+ return UUID.initWith(&bytes);
}
pub fn entropySlice(this: *RareData, len: usize) []u8 {
diff --git a/src/bun.js/uuid.zig b/src/bun.js/uuid.zig
index e8bdff661..e38ed567f 100644
--- a/src/bun.js/uuid.zig
+++ b/src/bun.js/uuid.zig
@@ -18,6 +18,16 @@ pub fn init() UUID {
uuid.bytes[6] = (uuid.bytes[6] & 0x0f) | 0x40;
// Variant 1
uuid.bytes[8] = (uuid.bytes[8] & 0x3f) | 0x80;
+
+ return uuid;
+}
+
+pub fn initWith(bytes: *const [16]u8) UUID {
+ var uuid = UUID{ .bytes = bytes.* };
+
+ uuid.bytes[6] = (uuid.bytes[6] & 0x0f) | 0x40;
+ uuid.bytes[8] = (uuid.bytes[8] & 0x3f) | 0x80;
+
return uuid;
}
diff --git a/src/bun.js/webcore.zig b/src/bun.js/webcore.zig
index fd69b0262..8cb9ec80a 100644
--- a/src/bun.js/webcore.zig
+++ b/src/bun.js/webcore.zig
@@ -366,7 +366,6 @@ pub const Prompt = struct {
};
pub const Crypto = struct {
- const UUID = @import("./uuid.zig");
const BoringSSL = @import("root").bun.BoringSSL;
pub const Class = JSC.NewClass(
void,
@@ -693,9 +692,8 @@ pub const Crypto = struct {
_: []const JSC.JSValue,
) JSC.JSValue {
var out: [36]u8 = undefined;
- const uuid: UUID = .{
- .bytes = globalThis.bunVM().rareData().nextUUID(),
- };
+ const uuid = globalThis.bunVM().rareData().nextUUID();
+
uuid.print(&out);
return JSC.ZigString.init(&out).toValueGC(globalThis);
}
@@ -723,9 +721,8 @@ pub const Crypto = struct {
_: *anyopaque,
) callconv(.C) JSC.JSValue {
var out: [36]u8 = undefined;
- const uuid: UUID = .{
- .bytes = globalThis.bunVM().rareData().nextUUID(),
- };
+ const uuid = globalThis.bunVM().rareData().nextUUID();
+
uuid.print(&out);
return JSC.ZigString.init(&out).toValueGC(globalThis);
}
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig
index 86b5414e3..ef2520049 100644
--- a/src/bun.js/webcore/blob.zig
+++ b/src/bun.js/webcore/blob.zig
@@ -249,7 +249,7 @@ pub const Blob = struct {
var hex_buf: [70]u8 = undefined;
const boundary = brk: {
- var random = globalThis.bunVM().rareData().nextUUID();
+ var random = globalThis.bunVM().rareData().nextUUID().bytes;
var formatter = std.fmt.fmtSliceHexLower(&random);
break :brk std.fmt.bufPrint(&hex_buf, "-WebkitFormBoundary{any}", .{formatter}) catch unreachable;
};
diff --git a/src/http/websocket_http_client.zig b/src/http/websocket_http_client.zig
index f495af3b7..ae8e40763 100644
--- a/src/http/websocket_http_client.zig
+++ b/src/http/websocket_http_client.zig
@@ -60,7 +60,7 @@ fn buildRequestBody(
extra_headers: NonUTF8Headers,
) std.mem.Allocator.Error![]u8 {
const allocator = vm.allocator;
- const input_rand_buf = vm.rareData().nextUUID();
+ const input_rand_buf = vm.rareData().nextUUID().bytes;
const temp_buf_size = comptime std.base64.standard.Encoder.calcSize(16);
var encoded_buf: [temp_buf_size]u8 = undefined;
const accept_key = std.base64.standard.Encoder.encode(&encoded_buf, &input_rand_buf);
diff --git a/test/js/web/web-globals.test.js b/test/js/web/web-globals.test.js
index b7a243190..d687a1290 100644
--- a/test/js/web/web-globals.test.js
+++ b/test/js/web/web-globals.test.js
@@ -138,6 +138,25 @@ it("crypto.randomUUID", () => {
});
});
+it("crypto.randomUUID version, issues#3575", () => {
+ var uuid = crypto.randomUUID();
+
+ function validate(uuid) {
+ const regex =
+ /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
+ return typeof uuid === "string" && regex.test(uuid);
+ }
+ function version(uuid) {
+ if (!validate(uuid)) {
+ throw TypeError("Invalid UUID");
+ }
+
+ return parseInt(uuid.slice(14, 15), 16);
+ }
+
+ expect(version(uuid)).toBe(4);
+});
+
it("URL.prototype.origin", () => {
const url = new URL("https://html.spec.whatwg.org/");
const { origin, host, hostname } = url;