mirror of
https://github.com/oven-sh/bun
synced 2026-02-12 20:09:04 +00:00
Support digest("base64" | "hex") in the hashings
This commit is contained in:
@@ -1118,19 +1118,7 @@ pub const Class = NewClass(
|
||||
.rfn = JSC.WebCore.Blob.writeFile,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.sha1 = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA1, "hash", false, false),
|
||||
},
|
||||
.sha256 = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA256, "hash", false, false),
|
||||
},
|
||||
.sha384 = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA384, "hash", false, false),
|
||||
},
|
||||
.sha512 = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA512, "hash", false, false),
|
||||
},
|
||||
.sha512_256 = .{
|
||||
.sha = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA512_256, "hash", false, false),
|
||||
},
|
||||
},
|
||||
@@ -1189,17 +1177,27 @@ pub const Class = NewClass(
|
||||
.unsafe = .{
|
||||
.get = getUnsafe,
|
||||
},
|
||||
|
||||
.SHA1 = .{
|
||||
.get = Crypto.SHA1.getter,
|
||||
},
|
||||
.SHA256 = .{
|
||||
.get = Crypto.SHA256.getter,
|
||||
.MD5 = .{
|
||||
.get = Crypto.MD5.getter,
|
||||
},
|
||||
.MD4 = .{
|
||||
.get = Crypto.MD4.getter,
|
||||
},
|
||||
.SHA224 = .{
|
||||
.get = Crypto.SHA224.getter,
|
||||
},
|
||||
.SHA512 = .{
|
||||
.get = Crypto.SHA512.getter,
|
||||
},
|
||||
.SHA384 = .{
|
||||
.get = Crypto.SHA384.getter,
|
||||
},
|
||||
.SHA512 = .{
|
||||
.get = Crypto.SHA512.getter,
|
||||
.SHA256 = .{
|
||||
.get = Crypto.SHA256.getter,
|
||||
},
|
||||
.SHA512_256 = .{
|
||||
.get = Crypto.SHA512_256.getter,
|
||||
@@ -1238,7 +1236,7 @@ pub const Crypto = struct {
|
||||
@This(),
|
||||
.{
|
||||
.hash = .{
|
||||
.rfn = JSC.wrapSync(@This(), "hash"),
|
||||
.rfn = JSC.wrapWithHasContainer(@This(), "hash", false, false),
|
||||
},
|
||||
.constructor = .{ .rfn = constructor },
|
||||
},
|
||||
@@ -1258,8 +1256,8 @@ pub const Crypto = struct {
|
||||
.update = .{
|
||||
.rfn = JSC.wrapSync(@This(), "update"),
|
||||
},
|
||||
.final = .{
|
||||
.rfn = JSC.wrapSync(@This(), "final"),
|
||||
.digest = .{
|
||||
.rfn = JSC.wrapSync(@This(), "digest"),
|
||||
},
|
||||
.finalize = finalize,
|
||||
},
|
||||
@@ -1270,7 +1268,20 @@ pub const Crypto = struct {
|
||||
},
|
||||
);
|
||||
|
||||
pub fn hash(
|
||||
fn hashToEncoding(
|
||||
globalThis: *JSGlobalObject,
|
||||
input: JSC.Node.StringOrBuffer,
|
||||
encoding: JSC.Node.Encoding,
|
||||
exception: JSC.C.ExceptionRef,
|
||||
) JSC.JSValue {
|
||||
var output_digest_buf: Hasher.Digest = undefined;
|
||||
|
||||
Hasher.hash(input.slice(), &output_digest_buf, JSC.VirtualMachine.vm.rareData().boringEngine());
|
||||
|
||||
return encoding.encodeWithSize(globalThis, Hasher.digest, &output_digest_buf, exception);
|
||||
}
|
||||
|
||||
fn hashToBytes(
|
||||
globalThis: *JSGlobalObject,
|
||||
input: JSC.Node.StringOrBuffer,
|
||||
output: ?JSC.ArrayBuffer,
|
||||
@@ -1293,7 +1304,7 @@ pub const Crypto = struct {
|
||||
output_digest_slice = bytes[0..Hasher.digest];
|
||||
}
|
||||
|
||||
Hasher.hash(input.slice(), output_digest_slice);
|
||||
Hasher.hash(input.slice(), output_digest_slice, JSC.VirtualMachine.vm.rareData().boringEngine());
|
||||
|
||||
if (output) |output_buf| {
|
||||
return output_buf.value;
|
||||
@@ -1303,6 +1314,37 @@ pub const Crypto = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash(
|
||||
globalThis: *JSGlobalObject,
|
||||
input: JSC.Node.StringOrBuffer,
|
||||
output: ?JSC.Node.StringOrBuffer,
|
||||
exception: JSC.C.ExceptionRef,
|
||||
) JSC.JSValue {
|
||||
if (output) |string_or_buffer| {
|
||||
switch (string_or_buffer) {
|
||||
.string => |str| {
|
||||
const encoding = JSC.Node.Encoding.from(str) orelse {
|
||||
JSC.JSError(
|
||||
bun.default_allocator,
|
||||
"Unknown encoding",
|
||||
.{},
|
||||
globalThis.ref(),
|
||||
exception,
|
||||
);
|
||||
return JSC.JSValue.zero;
|
||||
};
|
||||
|
||||
return hashToEncoding(globalThis, input, encoding, exception);
|
||||
},
|
||||
.buffer => |buffer| {
|
||||
return hashToBytes(globalThis, input, buffer.buffer, exception);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return hashToBytes(globalThis, input, null, exception);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn constructor(
|
||||
ctx: js.JSContextRef,
|
||||
_: js.JSObjectRef,
|
||||
@@ -1336,12 +1378,47 @@ pub const Crypto = struct {
|
||||
return existing.asObjectRef();
|
||||
}
|
||||
|
||||
pub fn update(this: *@This(), buffer: JSC.Node.StringOrBuffer) JSC.JSValue {
|
||||
pub fn update(this: *@This(), thisObj: JSC.C.JSObjectRef, buffer: JSC.Node.StringOrBuffer) JSC.JSValue {
|
||||
this.hashing.update(buffer.slice());
|
||||
return JSC.JSValue.jsUndefined();
|
||||
return JSC.JSValue.c(thisObj);
|
||||
}
|
||||
|
||||
pub fn final(this: *@This(), globalThis: *JSGlobalObject, exception: JSC.C.ExceptionRef, output: ?JSC.ArrayBuffer) JSC.JSValue {
|
||||
pub fn digest(
|
||||
this: *@This(),
|
||||
globalThis: *JSGlobalObject,
|
||||
output: ?JSC.Node.StringOrBuffer,
|
||||
exception: JSC.C.ExceptionRef,
|
||||
) JSC.JSValue {
|
||||
if (output) |string_or_buffer| {
|
||||
switch (string_or_buffer) {
|
||||
.string => |str| {
|
||||
const encoding = JSC.Node.Encoding.from(str) orelse {
|
||||
JSC.JSError(
|
||||
bun.default_allocator,
|
||||
"Unknown encoding",
|
||||
.{},
|
||||
globalThis.ref(),
|
||||
exception,
|
||||
);
|
||||
return JSC.JSValue.zero;
|
||||
};
|
||||
|
||||
return this.digestToEncoding(globalThis, exception, encoding);
|
||||
},
|
||||
.buffer => |buffer| {
|
||||
return this.digestToBytes(
|
||||
globalThis,
|
||||
exception,
|
||||
buffer.buffer,
|
||||
);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return this.digestToBytes(globalThis, exception, null);
|
||||
}
|
||||
}
|
||||
|
||||
fn digestToBytes(this: *@This(), globalThis: *JSGlobalObject, exception: JSC.C.ExceptionRef, output: ?JSC.ArrayBuffer) JSC.JSValue {
|
||||
var output_digest_buf: Hasher.Digest = undefined;
|
||||
var output_digest_slice: *Hasher.Digest = &output_digest_buf;
|
||||
if (output) |output_buf| {
|
||||
@@ -1370,6 +1447,7 @@ pub const Crypto = struct {
|
||||
}
|
||||
|
||||
this.hashing.final(output_digest_slice);
|
||||
|
||||
if (output) |output_buf| {
|
||||
return output_buf.value;
|
||||
} else {
|
||||
@@ -1378,17 +1456,39 @@ pub const Crypto = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn digestToEncoding(this: *@This(), globalThis: *JSGlobalObject, exception: JSC.C.ExceptionRef, encoding: JSC.Node.Encoding) JSC.JSValue {
|
||||
var output_digest_buf: Hasher.Digest = comptime brk: {
|
||||
var bytes: Hasher.Digest = undefined;
|
||||
var i: usize = 0;
|
||||
while (i < Hasher.digest) {
|
||||
bytes[i] = 0;
|
||||
i += 1;
|
||||
}
|
||||
break :brk bytes;
|
||||
};
|
||||
|
||||
var output_digest_slice: *Hasher.Digest = &output_digest_buf;
|
||||
|
||||
this.hashing.final(output_digest_slice);
|
||||
|
||||
return encoding.encodeWithSize(globalThis, Hasher.digest, output_digest_slice, exception);
|
||||
}
|
||||
|
||||
pub fn finalize(this: *@This()) void {
|
||||
VirtualMachine.vm.allocator.destroy(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const SHA1 = CryptoHasher(Hashers.SHA1, "SHA1", "Bun_SHA1");
|
||||
pub const SHA256 = CryptoHasher(Hashers.SHA256, "SHA256", "Bun_SHA256");
|
||||
pub const SHA384 = CryptoHasher(Hashers.SHA384, "SHA384", "Bun_SHA384");
|
||||
pub const SHA512 = CryptoHasher(Hashers.SHA512, "SHA512", "Bun_SHA512");
|
||||
pub const SHA512_256 = CryptoHasher(Hashers.SHA512_256, "SHA512_256", "Bun_SHA512_256");
|
||||
pub const SHA1 = CryptoHasher(Hashers.SHA1, "SHA1", "Bun_Crypto_SHA1");
|
||||
pub const MD5 = CryptoHasher(Hashers.MD5, "MD5", "Bun_Crypto_MD5");
|
||||
pub const MD4 = CryptoHasher(Hashers.MD4, "MD4", "Bun_Crypto_MD4");
|
||||
pub const SHA224 = CryptoHasher(Hashers.SHA224, "SHA224", "Bun_Crypto_SHA224");
|
||||
pub const SHA512 = CryptoHasher(Hashers.SHA512, "SHA512", "Bun_Crypto_SHA512");
|
||||
pub const SHA384 = CryptoHasher(Hashers.SHA384, "SHA384", "Bun_Crypto_SHA384");
|
||||
pub const SHA256 = CryptoHasher(Hashers.SHA256, "SHA256", "Bun_Crypto_SHA256");
|
||||
pub const SHA512_256 = CryptoHasher(Hashers.SHA512_256, "SHA512_256", "Bun_Crypto_SHA512_256");
|
||||
pub const MD5_SHA1 = CryptoHasher(Hashers.MD5_SHA1, "MD5_SHA1", "Bun_Crypto_MD5_SHA1");
|
||||
};
|
||||
|
||||
pub fn serve(
|
||||
|
||||
@@ -2557,10 +2557,14 @@ const SSLServer = JSC.API.SSLServer;
|
||||
const DebugServer = JSC.API.DebugServer;
|
||||
const DebugSSLServer = JSC.API.DebugSSLServer;
|
||||
const SHA1 = JSC.API.Bun.Crypto.SHA1;
|
||||
const SHA256 = JSC.API.Bun.Crypto.SHA256;
|
||||
const SHA384 = JSC.API.Bun.Crypto.SHA384;
|
||||
const MD5 = JSC.API.Bun.Crypto.MD5;
|
||||
const MD4 = JSC.API.Bun.Crypto.MD4;
|
||||
const SHA224 = JSC.API.Bun.Crypto.SHA224;
|
||||
const SHA512 = JSC.API.Bun.Crypto.SHA512;
|
||||
const SHA384 = JSC.API.Bun.Crypto.SHA384;
|
||||
const SHA256 = JSC.API.Bun.Crypto.SHA256;
|
||||
const SHA512_256 = JSC.API.Bun.Crypto.SHA512_256;
|
||||
const MD5_SHA1 = JSC.API.Bun.Crypto.MD5_SHA1;
|
||||
|
||||
pub const JSPrivateDataPtr = TaggedPointerUnion(.{
|
||||
AttributeIterator,
|
||||
@@ -2584,6 +2588,9 @@ pub const JSPrivateDataPtr = TaggedPointerUnion(.{
|
||||
HTMLRewriter,
|
||||
JSNode,
|
||||
LazyPropertiesObject,
|
||||
MD4,
|
||||
MD5_SHA1,
|
||||
MD5,
|
||||
ModuleNamespace,
|
||||
NodeFS,
|
||||
Request,
|
||||
@@ -2591,6 +2598,12 @@ pub const JSPrivateDataPtr = TaggedPointerUnion(.{
|
||||
Response,
|
||||
Router,
|
||||
Server,
|
||||
SHA1,
|
||||
SHA224,
|
||||
SHA256,
|
||||
SHA384,
|
||||
SHA512_256,
|
||||
SHA512,
|
||||
SSLServer,
|
||||
Stats,
|
||||
TextChunk,
|
||||
@@ -2598,11 +2611,6 @@ pub const JSPrivateDataPtr = TaggedPointerUnion(.{
|
||||
TextEncoder,
|
||||
TimeoutTask,
|
||||
Transpiler,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA384,
|
||||
SHA512,
|
||||
SHA512_256,
|
||||
});
|
||||
|
||||
pub inline fn GetJSPrivateData(comptime Type: type, ref: js.JSObjectRef) ?*Type {
|
||||
|
||||
@@ -193,6 +193,11 @@ pub const Encoding = enum(u8) {
|
||||
var str = JSC.ZigString.Empty;
|
||||
value.toZigString(&str, global);
|
||||
const slice = str.slice();
|
||||
return from(slice);
|
||||
}
|
||||
|
||||
/// Caller must verify the value is a string
|
||||
pub fn from(slice: []const u8) ?Encoding {
|
||||
return switch (slice.len) {
|
||||
0...2 => null,
|
||||
else => switch (Eight.matchLower(slice)) {
|
||||
@@ -214,6 +219,34 @@ pub const Encoding = enum(u8) {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn encodeWithSize(encoding: Encoding, globalThis: *JSC.JSGlobalObject, comptime size: usize, input: *const [size]u8, exception: JSC.C.ExceptionRef) JSC.JSValue {
|
||||
switch (encoding) {
|
||||
.base64 => {
|
||||
var base64: [std.base64.standard.Encoder.calcSize(size)]u8 = undefined;
|
||||
const result = JSC.ZigString.init(std.base64.standard.Encoder.encode(&base64, input)).toValueGC(globalThis);
|
||||
return result;
|
||||
},
|
||||
.base64url => {
|
||||
var buf: [std.base64.url_safe.Encoder.calcSize(size) + "data:;base64,".len]u8 = undefined;
|
||||
var encoded = std.base64.url_safe.Encoder.encode(buf["data:;base64,".len..], input);
|
||||
buf[0.."data:;base64,".len].* = "data:;base64,".*;
|
||||
|
||||
const result = JSC.ZigString.init(buf[0 .. "data:;base64,".len + encoded.len]).toValueGC(globalThis);
|
||||
return result;
|
||||
},
|
||||
.hex => {
|
||||
var buf: [size * 4]u8 = undefined;
|
||||
var out = std.fmt.bufPrint(&buf, "{}", .{std.fmt.fmtSliceHexLower(input)}) catch unreachable;
|
||||
const result = JSC.ZigString.init(out).toValueGC(globalThis);
|
||||
return result;
|
||||
},
|
||||
else => {
|
||||
JSC.throwInvalidArguments("Unexpected encoding", .{}, globalThis.ref(), exception);
|
||||
return JSC.JSValue.zero;
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const PathOrBuffer = union(Tag) {
|
||||
|
||||
@@ -6,12 +6,21 @@ const RareData = @This();
|
||||
const Syscall = @import("./node/syscall.zig");
|
||||
const JSC = @import("javascript_core");
|
||||
const std = @import("std");
|
||||
const BoringSSL = @import("boringssl");
|
||||
boring_ssl_engine: ?*BoringSSL.ENGINE = null,
|
||||
|
||||
editor_context: EditorContext = EditorContext{},
|
||||
stderr_store: ?*Blob.Store = null,
|
||||
stdin_store: ?*Blob.Store = null,
|
||||
stdout_store: ?*Blob.Store = null,
|
||||
|
||||
pub fn boringEngine(rare: *RareData) *BoringSSL.ENGINE {
|
||||
return rare.boring_ssl_engine orelse brk: {
|
||||
rare.boring_ssl_engine = BoringSSL.ENGINE_new();
|
||||
break :brk rare.boring_ssl_engine.?;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stderr(rare: *RareData) *Blob.Store {
|
||||
return rare.stderr_store orelse brk: {
|
||||
var store = default_allocator.create(Blob.Store) catch unreachable;
|
||||
|
||||
Reference in New Issue
Block a user