diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 16 | ||||
-rw-r--r-- | src/deps/c_ares.zig | 77 | ||||
m--------- | src/deps/uws | 0 | ||||
-rw-r--r-- | src/js/node/tls.js | 10 | ||||
-rw-r--r-- | src/js/out/modules/node/tls.js | 6 |
5 files changed, 82 insertions, 27 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index b853f585e..b7171b21c 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -127,6 +127,7 @@ using namespace Bun; extern "C" JSC::EncodedJSValue Bun__fetch(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +extern "C" JSC::EncodedJSValue Bun__canonicalizeIP(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); using JSGlobalObject = JSC::JSGlobalObject; @@ -1634,6 +1635,7 @@ JSC: return JSValue::encode( JSFunction::create(vm, globalObject, 1, pathToFileURLString, functionPathToFileURL, ImplementationVisibility::Public, NoIntrinsic)); } + if (string == "fileURLToPath"_s) { return JSValue::encode( JSFunction::create(vm, globalObject, 1, fileURLToPathString, functionFileURLToPath, ImplementationVisibility::Public, NoIntrinsic)); @@ -1663,12 +1665,17 @@ JSC: return JSValue::encode(obj); } - if (string == "rootCertificates"_s) { + if (string == "internal/tls"_s) { + auto* obj = constructEmptyObject(globalObject); + auto sourceOrigin = callFrame->callerSourceOrigin(vm).url(); +// expose for tests in debug mode only +#ifndef BUN_DEBUG bool isBuiltin = sourceOrigin.protocolIs("builtin"_s); if (!isBuiltin) { return JSC::JSValue::encode(JSC::jsUndefined()); } +#endif struct us_cert_string_t* out; auto size = us_raw_root_certs(&out); if (size < 0) { @@ -1680,7 +1687,12 @@ JSC: auto str = WTF::String::fromUTF8(raw.str, raw.len); rootCertificates->putDirectIndex(globalObject, i, JSC::jsString(vm, str)); } - return JSValue::encode(rootCertificates); + obj->putDirect( + vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "rootCertificates"_s)), rootCertificates, 0); + + obj->putDirect( + vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "canonicalizeIP"_s)), JSC::JSFunction::create(vm, globalObject, 1, "canonicalizeIP"_s, Bun__canonicalizeIP, ImplementationVisibility::Public, NoIntrinsic), 0); + return JSValue::encode(obj); } if (string == "masqueradesAsUndefined"_s) { diff --git a/src/deps/c_ares.zig b/src/deps/c_ares.zig index a8ad9f02b..777827662 100644 --- a/src/deps/c_ares.zig +++ b/src/deps/c_ares.zig @@ -1,6 +1,7 @@ const c = @import("std").c; const std = @import("std"); const bun = @import("root").bun; +const JSC = bun.JSC; const strings = bun.strings; const iovec = @import("std").os.iovec; const struct_in_addr = std.os.sockaddr.in; @@ -180,8 +181,6 @@ pub const struct_hostent = extern struct { h_length: c_int, h_addr_list: [*c][*c]u8, - const JSC = bun.JSC; - pub fn toJSReponse(this: *struct_hostent, _: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime lookup_name: []const u8) JSC.JSValue { // A cname lookup always returns a single record but we follow the common API here. @@ -296,13 +295,12 @@ pub const AddrInfo_node = extern struct { return len; } }; + pub const AddrInfo = extern struct { cnames_: [*c]AddrInfo_cname = null, node: ?*AddrInfo_node = null, name_: ?[*:0]u8 = null, - const JSC = bun.JSC; - pub fn toJSArray( addr_info: *AddrInfo, parent_allocator: std.mem.Allocator, @@ -624,8 +622,6 @@ pub const struct_ares_caa_reply = extern struct { value: [*c]u8, length: usize, - const JSC = bun.JSC; - pub fn toJSReponse(this: *struct_ares_caa_reply, parent_allocator: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime _: []const u8) JSC.JSValue { var stack = std.heap.stackFallback(2048, parent_allocator); var arena = @import("root").bun.ArenaAllocator.init(stack.get()); @@ -703,7 +699,6 @@ pub const struct_ares_srv_reply = extern struct { priority: c_ushort, weight: c_ushort, port: c_ushort, - const JSC = bun.JSC; pub fn toJSReponse(this: *struct_ares_srv_reply, parent_allocator: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime _: []const u8) JSC.JSValue { var stack = std.heap.stackFallback(2048, parent_allocator); @@ -788,8 +783,6 @@ pub const struct_ares_mx_reply = extern struct { host: [*c]u8, priority: c_ushort, - const JSC = bun.JSC; - pub fn toJSReponse(this: *struct_ares_mx_reply, parent_allocator: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime _: []const u8) JSC.JSValue { var stack = std.heap.stackFallback(2048, parent_allocator); var arena = @import("root").bun.ArenaAllocator.init(stack.get()); @@ -864,8 +857,6 @@ pub const struct_ares_txt_reply = extern struct { txt: [*c]u8, length: usize, - const JSC = bun.JSC; - pub fn toJSReponse(this: *struct_ares_txt_reply, parent_allocator: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime _: []const u8) JSC.JSValue { var stack = std.heap.stackFallback(2048, parent_allocator); var arena = @import("root").bun.ArenaAllocator.init(stack.get()); @@ -946,8 +937,6 @@ pub const struct_ares_naptr_reply = extern struct { order: c_ushort, preference: c_ushort, - const JSC = bun.JSC; - pub fn toJSReponse(this: *struct_ares_naptr_reply, parent_allocator: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime _: []const u8) JSC.JSValue { var stack = std.heap.stackFallback(2048, parent_allocator); var arena = @import("root").bun.ArenaAllocator.init(stack.get()); @@ -1040,8 +1029,6 @@ pub const struct_ares_soa_reply = extern struct { expire: c_uint, minttl: c_uint, - const JSC = bun.JSC; - pub fn toJSReponse(this: *struct_ares_soa_reply, parent_allocator: std.mem.Allocator, globalThis: *JSC.JSGlobalObject, comptime _: []const u8) JSC.JSValue { var stack = std.heap.stackFallback(2048, parent_allocator); var arena = @import("root").bun.ArenaAllocator.init(stack.get()); @@ -1377,3 +1364,63 @@ pub const ares_soa_reply = struct_ares_soa_reply; pub const ares_uri_reply = struct_ares_uri_reply; pub const ares_addr_node = struct_ares_addr_node; pub const ares_addr_port_node = struct_ares_addr_port_node; + +pub export fn Bun__canonicalizeIP( + ctx: *JSC.JSGlobalObject, + callframe: *JSC.CallFrame, +) callconv(.C) JSC.JSValue { + JSC.markBinding(@src()); + + const globalThis = ctx.ptr(); + const arguments = callframe.arguments(1); + + if (arguments.len == 0) { + globalThis.throwInvalidArguments("canonicalizeIP() expects a string but received no arguments.", .{}); + return .zero; + } + // windows uses 65 bytes for ipv6 addresses and linux/macos uses 46 + const INET6_ADDRSTRLEN = if (comptime bun.Environment.isWindows) 65 else 46; + + var script_ctx = globalThis.bunVM(); + var args = JSC.Node.ArgumentsSlice.init(script_ctx, arguments.ptr[0..arguments.len]); + var addr_arg = args.nextEat().?; + + if (bun.String.tryFromJS(addr_arg, globalThis)) |addr| { + const addr_slice = addr.toSlice(bun.default_allocator); + defer addr_slice.deinit(); + const addr_str = addr_slice.slice(); + if (addr_str.len >= INET6_ADDRSTRLEN) { + return JSC.JSValue.jsUndefined(); + } + + var ip_std_text: [INET6_ADDRSTRLEN + 1]u8 = undefined; + // we need a null terminated string as input + var ip_addr: [INET6_ADDRSTRLEN + 1]u8 = undefined; + bun.copy(u8, &ip_addr, addr_str); + ip_addr[addr_str.len] = 0; + + var af: c_int = std.os.AF.INET; + // get the standard text representation of the IP + if (ares_inet_pton(af, &ip_addr, &ip_std_text) != 1) { + af = std.os.AF.INET6; + if (ares_inet_pton(af, &ip_addr, &ip_std_text) != 1) { + return JSC.JSValue.jsUndefined(); + } + } + // ip_addr will contain the null-terminated string of the cannonicalized IP + if (ares_inet_ntop(af, &ip_std_text, &ip_addr, @sizeOf(@TypeOf(ip_addr))) == null) { + return JSC.JSValue.jsUndefined(); + } + // use the null-terminated size to return the string + const size = bun.len(bun.cast([*:0]u8, &ip_addr)); + return JSC.ZigString.init(ip_addr[0..size]).toValueGC(globalThis); + } else { + globalThis.throwInvalidArguments("address must be a string", .{}); + return .zero; + } +} +comptime { + if (!JSC.is_bindgen) { + _ = Bun__canonicalizeIP; + } +} diff --git a/src/deps/uws b/src/deps/uws -Subproject 0e9ddbe6944c3ca6b6957e5938d77d8ed9a8181 +Subproject 824ed80728c16c76164085685031c4e1c85aaa5 diff --git a/src/js/node/tls.js b/src/js/node/tls.js index aa3601311..567baddc1 100644 --- a/src/js/node/tls.js +++ b/src/js/node/tls.js @@ -5,6 +5,9 @@ const InternalTCPSocket = net[Symbol.for("::bunternal::")]; const bunSocketInternal = Symbol.for("::bunnetsocketinternal::"); const { RegExp, Array, String } = $lazy("primordials"); + +const { rootCertificates, canonicalizeIP } = $lazy("internal/tls"); + const SymbolReplace = Symbol.replace; const RegExpPrototypeSymbolReplace = RegExp.prototype[SymbolReplace]; const RegExpPrototypeExec = RegExp.prototype.exec; @@ -146,11 +149,6 @@ function splitEscapedAltNames(altNames) { return result; } -// TODO: -function canonicalizeIP(ip) { - return ip; -} - function checkServerIdentity(hostname, cert) { const subject = cert.subject; const altNames = cert.subjectaltname; @@ -683,7 +681,7 @@ function convertALPNProtocols(protocols, out) { out.ALPNProtocols = protocols; } } -var rootCertificates = $lazy("rootCertificates"); + var exports = { [Symbol.for("CommonJS")]: 0, CLIENT_RENEG_LIMIT, diff --git a/src/js/out/modules/node/tls.js b/src/js/out/modules/node/tls.js index 1888b4703..245699578 100644 --- a/src/js/out/modules/node/tls.js +++ b/src/js/out/modules/node/tls.js @@ -67,8 +67,6 @@ var parseCertString = function() { currentToken += StringPrototypeSubstring.call(altNames, offset), offset = altNames.length; } return ArrayPrototypePush.call(result, currentToken), result; -}, canonicalizeIP = function(ip) { - return ip; }, checkServerIdentity = function(hostname, cert) { const { subject, subjectaltname: altNames } = cert, dnsNames = [], ips = []; if (hostname = "" + hostname, altNames) { @@ -151,7 +149,7 @@ var parseCertString = function() { out.ALPNProtocols = Buffer.from(protocols.buffer.slice(protocols.byteOffset, protocols.byteOffset + protocols.byteLength)); else if (Buffer.isBuffer(protocols)) out.ALPNProtocols = protocols; -}, InternalTCPSocket = net[Symbol.for("::bunternal::")], bunSocketInternal = Symbol.for("::bunnetsocketinternal::"), { RegExp, Array, String } = globalThis[Symbol.for("Bun.lazy")]("primordials"), SymbolReplace = Symbol.replace, RegExpPrototypeSymbolReplace = RegExp.prototype[SymbolReplace], RegExpPrototypeExec = RegExp.prototype.exec, StringPrototypeStartsWith = String.prototype.startsWith, StringPrototypeSlice = String.prototype.slice, StringPrototypeIncludes = String.prototype.includes, StringPrototypeSplit = String.prototype.split, StringPrototypeIndexOf = String.prototype.indexOf, StringPrototypeSubstring = String.prototype.substring, StringPrototypeEndsWith = String.prototype.endsWith, StringFromCharCode = String.fromCharCode, StringPrototypeCharCodeAt = String.prototype.charCodeAt, ArrayPrototypeIncludes = Array.prototype.includes, ArrayPrototypeJoin = Array.prototype.join, ArrayPrototypeForEach = Array.prototype.forEach, ArrayPrototypePush = Array.prototype.push, ArrayPrototypeSome = Array.prototype.some, ArrayPrototypeReduce = Array.prototype.reduce, jsonStringPattern = /^"(?:[^"\\\u0000-\u001f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/, InternalSecureContext = class SecureContext2 { +}, InternalTCPSocket = net[Symbol.for("::bunternal::")], bunSocketInternal = Symbol.for("::bunnetsocketinternal::"), { RegExp, Array, String } = globalThis[Symbol.for("Bun.lazy")]("primordials"), { rootCertificates, canonicalizeIP } = globalThis[Symbol.for("Bun.lazy")]("internal/tls"), SymbolReplace = Symbol.replace, RegExpPrototypeSymbolReplace = RegExp.prototype[SymbolReplace], RegExpPrototypeExec = RegExp.prototype.exec, StringPrototypeStartsWith = String.prototype.startsWith, StringPrototypeSlice = String.prototype.slice, StringPrototypeIncludes = String.prototype.includes, StringPrototypeSplit = String.prototype.split, StringPrototypeIndexOf = String.prototype.indexOf, StringPrototypeSubstring = String.prototype.substring, StringPrototypeEndsWith = String.prototype.endsWith, StringFromCharCode = String.fromCharCode, StringPrototypeCharCodeAt = String.prototype.charCodeAt, ArrayPrototypeIncludes = Array.prototype.includes, ArrayPrototypeJoin = Array.prototype.join, ArrayPrototypeForEach = Array.prototype.forEach, ArrayPrototypePush = Array.prototype.push, ArrayPrototypeSome = Array.prototype.some, ArrayPrototypeReduce = Array.prototype.reduce, jsonStringPattern = /^"(?:[^"\\\u0000-\u001f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/, InternalSecureContext = class SecureContext2 { context; constructor(options) { const context = {}; @@ -416,7 +414,7 @@ var CLIENT_RENEG_LIMIT = 3, CLIENT_RENEG_WINDOW = 600, DEFAULT_ECDH_CURVE = "aut return new TLSSocket(port).connect(port, host2, connectListener); } return new TLSSocket().connect(port, host2, connectListener); -}, connect = createConnection, rootCertificates = globalThis[Symbol.for("Bun.lazy")]("rootCertificates"), exports = { +}, connect = createConnection, exports = { [Symbol.for("CommonJS")]: 0, CLIENT_RENEG_LIMIT, CLIENT_RENEG_WINDOW, |