Skip to content

Commit 8de27b3

Browse files
authored
Merge pull request #813 from lightpanda-io/crypto_get_random_values_fix
Crypto.getRandomValues consistency
2 parents 0a27e12 + f56b0a5 commit 8de27b3

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

src/browser/crypto/crypto.zig

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818

1919
const std = @import("std");
20+
const Env = @import("../env.zig").Env;
2021
const uuidv4 = @import("../../id.zig").uuidv4;
2122

2223
// https://w3c.github.io/webcrypto/#crypto-interface
2324
pub const Crypto = struct {
2425
_not_empty: bool = true,
2526

26-
pub fn _getRandomValues(_: *const Crypto, into: RandomValues) !RandomValues {
27+
pub fn _getRandomValues(_: *const Crypto, js_obj: Env.JsObject) !Env.JsObject {
28+
var into = try js_obj.toZig(Crypto, "getRandomValues", RandomValues);
2729
const buf = into.asBuffer();
2830
if (buf.len > 65_536) {
2931
return error.QuotaExceededError;
3032
}
3133
std.crypto.random.bytes(buf);
32-
return into;
34+
return js_obj;
3335
}
3436

3537
pub fn _randomUUID(_: *const Crypto) [36]u8 {
@@ -50,16 +52,16 @@ const RandomValues = union(enum) {
5052
uint64: []u64,
5153

5254
fn asBuffer(self: RandomValues) []u8 {
53-
switch (self) {
54-
.int8 => |b| return (@as([]u8, @ptrCast(b)))[0..b.len],
55-
.uint8 => |b| return (@as([]u8, @ptrCast(b)))[0..b.len],
56-
.int16 => |b| return (@as([]u8, @ptrCast(b)))[0 .. b.len * 2],
57-
.uint16 => |b| return (@as([]u8, @ptrCast(b)))[0 .. b.len * 2],
58-
.int32 => |b| return (@as([]u8, @ptrCast(b)))[0 .. b.len * 4],
59-
.uint32 => |b| return (@as([]u8, @ptrCast(b)))[0 .. b.len * 4],
60-
.int64 => |b| return (@as([]u8, @ptrCast(b)))[0 .. b.len * 8],
61-
.uint64 => |b| return (@as([]u8, @ptrCast(b)))[0 .. b.len * 8],
62-
}
55+
return switch (self) {
56+
.int8 => |b| (@as([]u8, @ptrCast(b)))[0..b.len],
57+
.uint8 => |b| (@as([]u8, @ptrCast(b)))[0..b.len],
58+
.int16 => |b| (@as([]u8, @ptrCast(b)))[0 .. b.len * 2],
59+
.uint16 => |b| (@as([]u8, @ptrCast(b)))[0 .. b.len * 2],
60+
.int32 => |b| (@as([]u8, @ptrCast(b)))[0 .. b.len * 4],
61+
.uint32 => |b| (@as([]u8, @ptrCast(b)))[0 .. b.len * 4],
62+
.int64 => |b| (@as([]u8, @ptrCast(b)))[0 .. b.len * 8],
63+
.uint64 => |b| (@as([]u8, @ptrCast(b)))[0 .. b.len * 8],
64+
};
6365
}
6466
};
6567

@@ -84,4 +86,12 @@ test "Browser.Crypto" {
8486
.{ "new Set(r2).size", "5" },
8587
.{ "r1.every((v, i) => v === r2[i])", "true" },
8688
}, .{});
89+
90+
try runner.testCases(&.{
91+
.{ "var r3 = new Uint8Array(16)", null },
92+
.{ "let r4 = crypto.getRandomValues(r3)", "undefined" },
93+
.{ "r4[6] = 10", null },
94+
.{ "r4[6]", "10" },
95+
.{ "r3[6]", "10" },
96+
}, .{});
8797
}

src/runtime/js.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
16031603
const str = try self.js_obj.getConstructorName();
16041604
return jsStringToZig(allocator, str, self.js_context.isolate);
16051605
}
1606+
1607+
pub fn toZig(self: JsObject, comptime Struct: type, comptime name: []const u8, comptime T: type) !T {
1608+
const named_function = comptime NamedFunction.init(Struct, name);
1609+
return self.js_context.jsValueToZig(named_function, T, self.js_obj.toValue());
1610+
}
16061611
};
16071612

16081613
// This only exists so that we know whether a function wants the opaque

0 commit comments

Comments
 (0)