Compare commits

..

1 Commits

Author SHA1 Message Date
Jarred Sumner
b3fbcc2d58 test(node): add http writable after close test 2025-05-28 22:37:02 -07:00
34 changed files with 104 additions and 980 deletions

View File

@@ -1,3 +0,0 @@
{
"terminals": []
}

View File

@@ -1,13 +1,27 @@
---
description: How to build Bun
globs:
alwaysApply: false
globs:
---
# How to build Bun
Run:
## CMake
```bash
bun bd
Bun is built using CMake, which you can find in `CMakeLists.txt` and in the `cmake/` directory.
* `CMakeLists.txt`
* `cmake/`
* `Globals.cmake` - macros and functions used by all the other files
* `Options.cmake` - build options for configuring the build (e.g. debug/release mode)
* `CompilerFlags.cmake` - compiler and linker flags used by all the targets
* `tools/` - setup scripts for various build tools (e.g. llvm, zig, webkit, rust, etc.)
* `targets/` - targets for bun and its dependencies (e.g. brotli, boringssl, libuv, etc.)
## How to
There are `package.json` scripts that make it easy to build Bun without calling CMake directly, for example:
```sh
bun run build # builds a debug build: `build/debug/bun-debug`
bun run build:release # builds a release build: `build/release/bun`
bun run build:assert # builds a release build with debug assertions: `build/assert/bun`
```

View File

@@ -770,15 +770,8 @@ create_ssl_context_from_options(struct us_socket_context_options_t options) {
* buffer allocated in a different address */
SSL_CTX_set_mode(ssl_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
if (options.min_version) {
SSL_CTX_set_min_proto_version(ssl_context, options.min_version);
} else {
/* Anything below TLS 1.2 is disabled */
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
}
if (options.max_version) {
SSL_CTX_set_max_proto_version(ssl_context, options.max_version);
}
/* Anything below TLS 1.2 is disabled */
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
/* The following are helpers. You may easily implement whatever you want by
* using the native handle directly */
@@ -1153,14 +1146,8 @@ SSL_CTX *create_ssl_context_from_bun_options(
* buffer allocated in a different address */
SSL_CTX_set_mode(ssl_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
if (options.min_version) {
SSL_CTX_set_min_proto_version(ssl_context, options.min_version);
} else {
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
}
if (options.max_version) {
SSL_CTX_set_max_proto_version(ssl_context, options.max_version);
}
/* Anything below TLS 1.2 is disabled */
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
/* The following are helpers. You may easily implement whatever you want by
* using the native handle directly */

View File

@@ -233,8 +233,6 @@ struct us_bun_socket_context_options_t {
const char **ca;
unsigned int ca_count;
unsigned int secure_options;
unsigned int min_version;
unsigned int max_version;
int reject_unauthorized;
int request_cert;
unsigned int client_renegotiation_limit;

View File

@@ -74,8 +74,6 @@ namespace uWS {
const char **ca = nullptr;
unsigned int ca_count = 0;
unsigned int secure_options = 0;
unsigned int min_version = 0;
unsigned int max_version = 0;
int reject_unauthorized = 0;
int request_cert = 0;
unsigned int client_renegotiation_limit = 3;

View File

@@ -858,8 +858,7 @@ function getSshKeys() {
const sshFiles = readdirSync(sshPath, { withFileTypes: true, encoding: "utf-8" });
const publicPaths = sshFiles
.filter(entry => entry.isFile() && entry.name.endsWith(".pub"))
.map(({ name }) => join(sshPath, name))
.filter(path => !readFile(path, { cache: true }).startsWith("ssh-ed25519"));
.map(({ name }) => join(sshPath, name));
sshKeys.push(
...publicPaths.map(publicPath => ({

View File

@@ -41,14 +41,6 @@ const MimeType = HTTP.MimeType;
const Blob = JSC.WebCore.Blob;
const BoringSSL = bun.BoringSSL.c;
const Arena = @import("../../allocators/mimalloc_arena.zig").Arena;
fn parseTLSVersion(str: []const u8) ?u16 {
if (strings.eqlComptime(str, "TLSv1")) return BoringSSL.TLS1_VERSION;
if (strings.eqlComptime(str, "TLSv1.1")) return BoringSSL.TLS1_1_VERSION;
if (strings.eqlComptime(str, "TLSv1.2")) return BoringSSL.TLS1_2_VERSION;
if (strings.eqlComptime(str, "TLSv1.3")) return BoringSSL.TLS1_3_VERSION;
return null;
}
const SendfileContext = struct {
fd: bun.FileDescriptor,
socket_fd: bun.FileDescriptor = bun.invalid_fd,
@@ -669,8 +661,6 @@ pub const ServerConfig = struct {
ca_count: u32 = 0,
secure_options: u32 = 0,
min_version: u16 = 0,
max_version: u16 = 0,
request_cert: i32 = 0,
reject_unauthorized: i32 = 0,
ssl_ciphers: ?[*:0]const u8 = null,
@@ -714,8 +704,6 @@ pub const ServerConfig = struct {
}
ctx_opts.request_cert = this.request_cert;
ctx_opts.reject_unauthorized = this.reject_unauthorized;
ctx_opts.min_version = this.min_version;
ctx_opts.max_version = this.max_version;
return ctx_opts;
}
@@ -1189,22 +1177,6 @@ pub const ServerConfig = struct {
}
}
if (try obj.getStringish(global, "minVersion")) |minv| {
var slice = try minv.toSlice(global, bun.default_allocator);
defer slice.deinit();
if (parseTLSVersion(slice.slice())) |ver| {
result.min_version = ver;
}
}
if (try obj.getStringish(global, "maxVersion")) |maxv| {
var slice = try maxv.toSlice(global, bun.default_allocator);
defer slice.deinit();
if (parseTLSVersion(slice.slice())) |ver| {
result.max_version = ver;
}
}
if (try obj.getTruthy(global, "clientRenegotiationLimit")) |client_renegotiation_limit| {
if (client_renegotiation_limit.isNumber()) {
result.client_renegotiation_limit = client_renegotiation_limit.toU32();

View File

@@ -2030,14 +2030,13 @@ enum class BunProcessStdinFdType : int32_t {
extern "C" BunProcessStdinFdType Bun__Process__getStdinFdType(void*, int fd);
extern "C" void Bun__ForceFileSinkToBeSynchronousForProcessObjectStdio(JSC::JSGlobalObject*, JSC::EncodedJSValue);
static JSValue constructStdioWriteStream(JSC::JSGlobalObject* globalObject, JSC::JSObject* processObject, int fd)
static JSValue constructStdioWriteStream(JSC::JSGlobalObject* globalObject, int fd)
{
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_CATCH_SCOPE(vm);
JSC::JSFunction* getStdioWriteStream = JSC::JSFunction::create(vm, globalObject, processObjectInternalsGetStdioWriteStreamCodeGenerator(vm), globalObject);
JSC::MarkedArgumentBuffer args;
args.append(processObject);
args.append(JSC::jsNumber(fd));
args.append(jsBoolean(bun_stdio_tty[fd]));
BunProcessStdinFdType fdType = Bun__Process__getStdinFdType(Bun::vm(vm), fd);
@@ -2046,11 +2045,8 @@ static JSValue constructStdioWriteStream(JSC::JSGlobalObject* globalObject, JSC:
JSC::CallData callData = JSC::getCallData(getStdioWriteStream);
auto result = JSC::profiledCall(globalObject, ProfilingReason::API, getStdioWriteStream, callData, globalObject->globalThis(), args);
if (auto* exception = scope.exception()) {
Zig::GlobalObject::reportUncaughtExceptionAtEventLoop(globalObject, exception);
scope.clearException();
return jsUndefined();
}
scope.assertNoExceptionExceptTermination();
CLEAR_AND_RETURN_IF_EXCEPTION(scope, jsUndefined());
ASSERT_WITH_MESSAGE(JSC::isJSArray(result), "Expected an array from getStdioWriteStream");
JSC::JSArray* resultObject = JSC::jsCast<JSC::JSArray*>(result);
@@ -2081,12 +2077,12 @@ static JSValue constructStdioWriteStream(JSC::JSGlobalObject* globalObject, JSC:
static JSValue constructStdout(VM& vm, JSObject* processObject)
{
return constructStdioWriteStream(processObject->globalObject(), processObject, 1);
return constructStdioWriteStream(processObject->globalObject(), 1);
}
static JSValue constructStderr(VM& vm, JSObject* processObject)
{
return constructStdioWriteStream(processObject->globalObject(), processObject, 2);
return constructStdioWriteStream(processObject->globalObject(), 2);
}
#if OS(WINDOWS)
@@ -2096,22 +2092,17 @@ static JSValue constructStderr(VM& vm, JSObject* processObject)
static JSValue constructStdin(VM& vm, JSObject* processObject)
{
auto* globalObject = processObject->globalObject();
auto scope = DECLARE_CATCH_SCOPE(vm);
JSC::JSFunction* getStdinStream = JSC::JSFunction::create(vm, globalObject, processObjectInternalsGetStdinStreamCodeGenerator(vm), globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
JSC::JSFunction* getStdioWriteStream = JSC::JSFunction::create(vm, globalObject, processObjectInternalsGetStdinStreamCodeGenerator(vm), globalObject);
JSC::MarkedArgumentBuffer args;
args.append(processObject);
args.append(JSC::jsNumber(STDIN_FILENO));
args.append(jsBoolean(bun_stdio_tty[STDIN_FILENO]));
BunProcessStdinFdType fdType = Bun__Process__getStdinFdType(Bun::vm(vm), STDIN_FILENO);
args.append(jsNumber(static_cast<int32_t>(fdType)));
JSC::CallData callData = JSC::getCallData(getStdinStream);
JSC::CallData callData = JSC::getCallData(getStdioWriteStream);
auto result = JSC::profiledCall(globalObject, ProfilingReason::API, getStdinStream, callData, globalObject, args);
if (auto* exception = scope.exception()) {
Zig::GlobalObject::reportUncaughtExceptionAtEventLoop(globalObject, exception);
scope.clearException();
return jsUndefined();
}
auto result = JSC::profiledCall(globalObject, ProfilingReason::API, getStdioWriteStream, callData, globalObject, args);
RETURN_IF_EXCEPTION(scope, {});
return result;
}

View File

@@ -2554,8 +2554,6 @@ pub const us_bun_socket_context_options_t = extern struct {
ca: ?[*]?[*:0]const u8 = null,
ca_count: u32 = 0,
secure_options: u32 = 0,
min_version: u32 = 0,
max_version: u32 = 0,
reject_unauthorized: i32 = 0,
request_cert: i32 = 0,
client_renegotiation_limit: u32 = 3,

View File

@@ -690,8 +690,6 @@ fn NewHTTPContext(comptime ssl: bool) type {
.ca_count = @intCast(init_opts.ca.len),
.ca_file_name = if (init_opts.abs_ca_file_name.len > 0) init_opts.abs_ca_file_name else null,
.request_cert = 1,
.min_version = 0,
.max_version = 0,
};
try this.initWithOpts(&opts);
@@ -704,8 +702,6 @@ fn NewHTTPContext(comptime ssl: bool) type {
.request_cert = 1,
// we manually abort the connection if the hostname doesn't match
.reject_unauthorized = 0,
.min_version = 0,
.max_version = 0,
};
var err: uws.create_bun_socket_error_t = .none;
this.us_socket_context = uws.us_create_bun_ssl_socket_context(http_thread.loop.loop, @sizeOf(usize), opts, &err).?;

View File

@@ -30,13 +30,8 @@ const enum BunProcessStdinFdType {
socket = 2,
}
export function getStdioWriteStream(
process: typeof globalThis.process,
fd: number,
isTTY: boolean,
_fdType: BunProcessStdinFdType,
) {
$assert(fd === 1 || fd === 2, `Expected fd to be 1 or 2, got ${fd}`);
export function getStdioWriteStream(fd, isTTY: boolean, _fdType: BunProcessStdinFdType) {
$assert(typeof fd === "number", `Expected fd to be a number, got ${typeof fd}`);
let stream;
if (isTTY) {
@@ -79,14 +74,9 @@ export function getStdioWriteStream(
return [stream, underlyingSink];
}
export function getStdinStream(
process: typeof globalThis.process,
fd: number,
isTTY: boolean,
fdType: BunProcessStdinFdType,
) {
$assert(fd === 0);
export function getStdinStream(fd, isTTY: boolean, fdType: BunProcessStdinFdType) {
const native = Bun.stdin.stream();
// @ts-expect-error
const source = native.$bunNativePtr;
var reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
@@ -256,12 +246,7 @@ export function getStdinStream(
return stream;
}
export function initializeNextTickQueue(
process: typeof globalThis.process,
nextTickQueue,
drainMicrotasksFn,
reportUncaughtExceptionFn,
) {
export function initializeNextTickQueue(process, nextTickQueue, drainMicrotasksFn, reportUncaughtExceptionFn) {
var queue;
var process;
var nextTickQueue = nextTickQueue;

View File

@@ -166,6 +166,9 @@ function callCloseCallback(self) {
}
function emitCloseNT(self) {
if (!self._closed) {
if (self._ended !== undefined) {
self._ended = true;
}
self.destroyed = true;
self._closed = true;
callCloseCallback(self);

View File

@@ -272,9 +272,7 @@ const ServerResponsePrototype = {
}
this.detachSocket(socket);
this.finished = true;
process.nextTick(self => {
self._ended = true;
}, this);
// Marking _ended happens on 'close' to align with Node.js behavior
this.emit("prefinish");
this._callPendingCallbacks();

View File

@@ -118,7 +118,11 @@ function endNT(socket, callback, err) {
callback(err);
}
function emitCloseNT(self, hasError) {
self.emit("close", hasError);
if (hasError) {
self.emit("close", hasError);
} else {
self.emit("close");
}
}
function detachSocket(self) {
if (!self) self = this;
@@ -229,7 +233,6 @@ const SocketHandlers: SocketHandler = {
self[kwriteCallback] = null;
callback(error);
}
self.emit("error", error);
},
open(socket) {
@@ -406,10 +409,6 @@ const ServerHandlers: SocketHandler = {
self[bunSocketServerConnections]++;
if (pauseOnConnect) {
_socket.pause();
}
if (typeof connectionListener === "function") {
this.pauseOnConnect = pauseOnConnect;
if (!isTLS) {
@@ -464,9 +463,7 @@ const ServerHandlers: SocketHandler = {
// after secureConnection event we emmit secure and secureConnect
self.emit("secure", self);
self.emit("secureConnect", verifyError);
if (server.pauseOnConnect) {
self.pause();
} else {
if (!server.pauseOnConnect) {
self.resume();
}
},
@@ -520,9 +517,6 @@ const SocketHandlers2: SocketHandler<SocketHandleData> = {
$debug("self[kupgraded]", String(self[kupgraded]));
if (!self[kupgraded]) req!.oncomplete(0, self._handle, req, true, true);
socket.data.req = undefined;
if (self.pauseOnConnect) {
self.pause();
}
if (self[kupgraded]) {
self.connecting = false;
const options = self[bunTLSConnectOptions];
@@ -730,8 +724,6 @@ function Socket(options?) {
this[kclosed] = false;
this[kended] = false;
this.connecting = false;
this._host = undefined;
this._port = undefined;
this[bunTLSConnectOptions] = null;
this.timeout = 0;
this[kwriteCallback] = undefined;
@@ -847,9 +839,7 @@ Object.defineProperty(Socket.prototype, "bytesWritten", {
else bytes += Buffer.byteLength(chunk.chunk, chunk.encoding);
}
} else if (data) {
// Writes are either a string or a Buffer.
if (typeof data !== "string") bytes += data.length;
else bytes += Buffer.byteLength(data, this._pendingEncoding || "utf8");
bytes += data.byteLength;
}
return bytes;
},
@@ -867,7 +857,7 @@ Socket.prototype[kAttach] = function (port, socket) {
}
if (this[kSetKeepAlive]) {
socket.setKeepAlive(true, this[kSetKeepAliveInitialDelay]);
socket.setKeepAlive(true, self[kSetKeepAliveInitialDelay]);
}
if (!this[kupgraded]) {
@@ -909,14 +899,12 @@ Socket.prototype.connect = function connect(...args) {
}).catch(error => {
if (!this.destroyed) {
this.emit("error", error);
this.emit("close", true);
this.emit("close");
}
});
}
this.pauseOnConnect = pauseOnConnect;
if (pauseOnConnect) {
this.pause();
} else {
if (!pauseOnConnect) {
process.nextTick(() => {
this.resume();
});
@@ -1163,7 +1151,7 @@ Socket.prototype._destroy = function _destroy(err, callback) {
callback(err);
} else {
callback(err);
process.nextTick(emitCloseNT, this, false);
process.nextTick(emitCloseNT, this);
}
};
@@ -1558,7 +1546,6 @@ function lookupAndConnect(self, options) {
$debug("connect: find host", host, addressType);
$debug("connect: dns options", dnsopts);
self._host = host;
self._port = port;
const lookup = options.lookup || dns.lookup;
if (dnsopts.family !== 4 && dnsopts.family !== 6 && !localAddress && autoSelectFamily) {
@@ -2198,7 +2185,6 @@ Server.prototype.getConnections = function getConnections(callback) {
};
Server.prototype.listen = function listen(port, hostname, onListen) {
const argsLength = arguments.length;
if (typeof port === "string") {
const numPort = Number(port);
if (!Number.isNaN(numPort)) port = numPort;
@@ -2226,15 +2212,9 @@ Server.prototype.listen = function listen(port, hostname, onListen) {
hostname = undefined;
port = undefined;
} else {
if (typeof hostname === "number") {
backlog = hostname;
hostname = undefined;
} else if (typeof hostname === "function") {
if (typeof hostname === "function") {
onListen = hostname;
hostname = undefined;
} else if (typeof hostname === "string" && typeof onListen === "number") {
backlog = onListen;
onListen = argsLength > 3 ? arguments[3] : undefined;
}
if (typeof port === "function") {
@@ -2251,7 +2231,6 @@ Server.prototype.listen = function listen(port, hostname, onListen) {
ipv6Only = options.ipv6Only;
allowHalfOpen = options.allowHalfOpen;
reusePort = options.reusePort;
backlog = options.backlog;
if (typeof options.fd === "number" && options.fd >= 0) {
fd = options.fd;
@@ -2445,7 +2424,7 @@ function emitErrorNextTick(self, error) {
function emitErrorAndCloseNextTick(self, error) {
self.emit("error", error);
self.emit("close", true);
self.emit("close");
}
function addServerAbortSignalOption(self, options) {

View File

@@ -202,8 +202,6 @@ var InternalSecureContext = class SecureContext {
passphrase;
servername;
secureOptions;
minVersion;
maxVersion;
constructor(options) {
const context = {};
@@ -246,9 +244,6 @@ var InternalSecureContext = class SecureContext {
this.secureOptions = secureOptions;
if (options.minVersion !== undefined) this.minVersion = options.minVersion;
if (options.maxVersion !== undefined) this.maxVersion = options.maxVersion;
if (!$isUndefinedOrNull(options.privateKeyIdentifier)) {
if ($isUndefinedOrNull(options.privateKeyEngine)) {
// prettier-ignore
@@ -316,8 +311,6 @@ function TLSSocket(socket?, options?) {
options = isNetSocketOrDuplex ? { ...options, allowHalfOpen: false } : options || socket || {};
applySecureProtocol(options);
NetSocket.$call(this, options);
this.ciphers = options.ciphers;
@@ -515,8 +508,6 @@ function Server(options, secureConnectionListener): void {
this.ca = undefined;
this.passphrase = undefined;
this.secureOptions = undefined;
this.minVersion = undefined;
this.maxVersion = undefined;
this._rejectUnauthorized = rejectUnauthorizedDefault;
this._requestCert = undefined;
this.servername = undefined;
@@ -544,7 +535,6 @@ function Server(options, secureConnectionListener): void {
options = options.context;
}
if (options) {
applySecureProtocol(options);
const { ALPNProtocols } = options;
if (ALPNProtocols) {
@@ -587,9 +577,6 @@ function Server(options, secureConnectionListener): void {
}
this.secureOptions = secureOptions;
if (options.minVersion !== undefined) this.minVersion = options.minVersion;
if (options.maxVersion !== undefined) this.maxVersion = options.maxVersion;
const requestCert = options.requestCert || false;
if (requestCert) this._requestCert = requestCert;
@@ -630,8 +617,6 @@ function Server(options, secureConnectionListener): void {
ca: this.ca,
passphrase: this.passphrase,
secureOptions: this.secureOptions,
minVersion: this.minVersion,
maxVersion: this.maxVersion,
rejectUnauthorized: this._rejectUnauthorized,
requestCert: isClient ? true : this._requestCert,
ALPNProtocols: this.ALPNProtocols,
@@ -655,32 +640,6 @@ const DEFAULT_ECDH_CURVE = "auto",
DEFAULT_MIN_VERSION = "TLSv1.2",
DEFAULT_MAX_VERSION = "TLSv1.3";
function applySecureProtocol(opts) {
const proto = opts && opts.secureProtocol;
if (typeof proto !== "string") return;
switch (proto) {
case "TLSv1_method":
opts.minVersion = "TLSv1";
opts.maxVersion = "TLSv1";
break;
case "TLSv1_1_method":
opts.minVersion = "TLSv1.1";
opts.maxVersion = "TLSv1.1";
break;
case "TLSv1_2_method":
opts.minVersion = "TLSv1.2";
opts.maxVersion = "TLSv1.2";
break;
case "TLSv1_3_method":
opts.minVersion = "TLSv1.3";
opts.maxVersion = "TLSv1.3";
break;
default:
// TLS_method or unknown methods fall back to defaults
break;
}
}
function normalizeConnectArgs(listArgs) {
const args = net._normalizeArgs(listArgs);
$assert($isObject(args[0]));

View File

@@ -7671,15 +7671,7 @@ fn NewParser_(
ifStmtScopeIndex = try p.pushScopeForParsePass(js_ast.Scope.Kind.block, loc);
}
var scopeIndex: usize = 0;
var pushedScopeForFunctionArgs = false;
// Push scope if the current lexer token is an open parenthesis token.
// That is, the parser is about parsing function arguments
if (p.lexer.token == .t_open_paren) {
scopeIndex = try p.pushScopeForParsePass(js_ast.Scope.Kind.function_args, p.lexer.loc());
pushedScopeForFunctionArgs = true;
}
const scopeIndex = try p.pushScopeForParsePass(js_ast.Scope.Kind.function_args, p.lexer.loc());
var func = try p.parseFn(name, FnOrArrowDataParse{
.needs_async_loc = loc,
.async_range = asyncRange orelse logger.Range.None,
@@ -7695,7 +7687,7 @@ fn NewParser_(
if (comptime is_typescript_enabled) {
// Don't output anything if it's just a forward declaration of a function
if ((opts.is_typescript_declare or func.flags.contains(.is_forward_declaration)) and pushedScopeForFunctionArgs) {
if (opts.is_typescript_declare or func.flags.contains(.is_forward_declaration)) {
p.popAndDiscardScope(scopeIndex);
// Balance the fake block scope introduced above
@@ -7711,9 +7703,7 @@ fn NewParser_(
}
}
if (pushedScopeForFunctionArgs) {
p.popScope();
}
p.popScope();
// Only declare the function after we know if it had a body or not. Otherwise
// TypeScript code such as this will double-declare the symbol:
@@ -12615,19 +12605,14 @@ fn NewParser_(
p.allow_in = true;
const loc = p.lexer.loc();
var pushedScopeForFunctionBody = false;
if (p.lexer.token == .t_open_brace) {
_ = try p.pushScopeForParsePass(Scope.Kind.function_body, p.lexer.loc());
pushedScopeForFunctionBody = true;
}
_ = try p.pushScopeForParsePass(Scope.Kind.function_body, p.lexer.loc());
defer p.popScope();
try p.lexer.expect(.t_open_brace);
var opts = ParseStatementOptions{};
const stmts = try p.parseStmtsUpTo(.t_close_brace, &opts);
try p.lexer.next();
if (pushedScopeForFunctionBody) p.popScope();
p.allow_in = oldAllowIn;
p.fn_or_arrow_data_parse = oldFnOrArrowData;
return G.FnBody{ .loc = loc, .stmts = stmts };

View File

@@ -543,7 +543,7 @@ pub const JSValkeyClient = struct {
vm.rareData().valkey_context.tls orelse brk_ctx: {
// TLS socket, default config
var err: uws.create_bun_socket_error_t = .none;
const ctx_ = uws.us_create_bun_ssl_socket_context(vm.uwsLoop(), @sizeOf(*JSValkeyClient), uws.us_bun_socket_context_options_t{ .min_version = 0, .max_version = 0 }, &err).?;
const ctx_ = uws.us_create_bun_ssl_socket_context(vm.uwsLoop(), @sizeOf(*JSValkeyClient), uws.us_bun_socket_context_options_t{}, &err).?;
uws.NewSocketHandler(true).configure(ctx_, true, *JSValkeyClient, SocketHandler(true));
vm.rareData().valkey_context.tls = ctx_;
break :brk_ctx ctx_;

View File

@@ -3462,18 +3462,6 @@ describe("await can only be used inside an async function message", () => {
});
});
describe("malformed function definition does not crash due to invalid scope initialization", () => {
it("fails with a parse error and exits cleanly", async () => {
const tests = ["function:", "function a() {function:}"];
for (const code of tests) {
for (const loader of ["js", "ts"]) {
const transpiler = new Bun.Transpiler({ loader });
expect(() => transpiler.transformSync(code)).toThrow("Parse error");
}
}
});
});
it("does not crash with 9 comments and typescript type skipping", () => {
const cmd = [bunExe(), "build", "--minify-identifiers", join(import.meta.dir, "fixtures", "9-comments.ts")];
const { stdout, stderr, exitCode } = Bun.spawnSync({

View File

@@ -1114,20 +1114,3 @@ it("should handle user assigned `default` properties", async () => {
await promise;
});
it.each(["stdin", "stdout", "stderr"])("%s stream accessor should handle exceptions without crashing", stream => {
expect([
/* js */ `
const old = process;
process = null;
try {
old.${stream};
} catch {}
if (typeof old.${stream} !== "undefined") {
console.log("wrong");
}
`,
"",
1,
]).toRunInlineFixture();
});

View File

@@ -0,0 +1,41 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { get, createServer } = require('http');
// res.writable should not be set to false after it has finished sending
// Ref: https://github.com/nodejs/node/issues/15029
let internal;
let external;
// Proxy server
const server = createServer(common.mustCall((req, res) => {
const listener = common.mustCall(() => {
assert.strictEqual(res.writable, true);
});
// on CentOS 5, 'finish' is emitted
res.on('finish', listener);
// Everywhere else, 'close' is emitted
res.on('close', listener);
get(`http://127.0.0.1:${internal.address().port}`, common.mustCall((inner) => {
inner.pipe(res);
}));
})).listen(0, () => {
// Http server
internal = createServer((req, res) => {
res.writeHead(200);
setImmediate(common.mustCall(() => {
external.abort();
res.end('Hello World\n');
}));
}).listen(0, () => {
external = get(`http://127.0.0.1:${server.address().port}`);
external.on('error', common.mustCall(() => {
server.close();
internal.close();
}));
});
});

View File

@@ -1,83 +0,0 @@
'use strict';
const common = require('../common');
const { createMockedLookup } = require('../common/dns');
const assert = require('assert');
const { createConnection, createServer, setDefaultAutoSelectFamily } = require('net');
const autoSelectFamilyAttemptTimeout = common.defaultAutoSelectFamilyAttemptTimeout;
// Test that IPV4 is reached by default if IPV6 is not reachable and the default is enabled
{
const ipv4Server = createServer((socket) => {
socket.on('data', common.mustCall(() => {
socket.write('response-ipv4');
socket.end();
}));
});
ipv4Server.listen(0, '127.0.0.1', common.mustCall(() => {
setDefaultAutoSelectFamily(true);
const connection = createConnection({
host: 'example.org',
port: ipv4Server.address().port,
lookup: createMockedLookup('::1', '127.0.0.1'),
autoSelectFamilyAttemptTimeout,
});
let response = '';
connection.setEncoding('utf-8');
connection.on('data', (chunk) => {
response += chunk;
});
connection.on('end', common.mustCall(() => {
assert.strictEqual(response, 'response-ipv4');
ipv4Server.close();
}));
connection.write('request');
}));
}
// Test that IPV4 is not reached by default if IPV6 is not reachable and the default is disabled
{
const ipv4Server = createServer((socket) => {
socket.on('data', common.mustCall(() => {
socket.write('response-ipv4');
socket.end();
}));
});
ipv4Server.listen(0, '127.0.0.1', common.mustCall(() => {
setDefaultAutoSelectFamily(false);
const port = ipv4Server.address().port;
const connection = createConnection({
host: 'example.org',
port,
lookup: createMockedLookup('::1', '127.0.0.1'),
});
connection.on('ready', common.mustNotCall());
connection.on('error', common.mustCall((error) => {
if (common.hasIPv6) {
assert.strictEqual(error.code, 'ECONNREFUSED');
assert.strictEqual(error.message, `connect ECONNREFUSED ::1:${port}`);
} else if (error.code === 'EAFNOSUPPORT') {
assert.strictEqual(error.message, `connect EAFNOSUPPORT ::1:${port} - Local (undefined:undefined)`);
} else if (error.code === 'EUNATCH') {
assert.strictEqual(error.message, `connect EUNATCH ::1:${port} - Local (:::0)`);
} else {
assert.strictEqual(error.code, 'EADDRNOTAVAIL');
assert.strictEqual(error.message, `connect EADDRNOTAVAIL ::1:${port} - Local (:::0)`);
}
ipv4Server.close();
}));
}));
}

View File

@@ -1,78 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const net = require('net');
let bytesRead = 0;
let bytesWritten = 0;
let count = 0;
const tcp = net.Server(function(s) {
console.log('tcp server connection');
// trigger old mode.
s.resume();
s.on('end', function() {
bytesRead += s.bytesRead;
console.log(`tcp socket disconnect #${count}`);
});
});
tcp.listen(0, function doTest() {
console.error('listening');
const socket = net.createConnection(this.address().port);
socket.on('connect', function() {
count++;
console.error('CLIENT connect #%d', count);
socket.write('foo', function() {
console.error('CLIENT: write cb');
socket.end('bar');
});
});
socket.on('finish', function() {
bytesWritten += socket.bytesWritten;
console.error('CLIENT end event #%d', count);
});
socket.on('close', function() {
console.error('CLIENT close event #%d', count);
console.log(`Bytes read: ${bytesRead}`);
console.log(`Bytes written: ${bytesWritten}`);
if (count < 2) {
console.error('RECONNECTING');
socket.connect(tcp.address().port);
} else {
tcp.close();
}
});
});
process.on('exit', function() {
assert.strictEqual(bytesRead, 12);
assert.strictEqual(bytesWritten, 12);
});

View File

@@ -1,77 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');
const tcp = net.Server(common.mustCall((s) => {
tcp.close();
let buf = '';
s.setEncoding('utf8');
s.on('data', function(d) {
buf += d;
});
s.on('end', common.mustCall(function() {
console.error('SERVER: end', buf);
assert.strictEqual(buf, "L'État, c'est moi");
s.end();
}));
}));
tcp.listen(0, common.mustCall(function() {
const socket = net.Stream({ highWaterMark: 0 });
let connected = false;
assert.strictEqual(socket.pending, true);
socket.connect(this.address().port, common.mustCall(() => connected = true));
assert.strictEqual(socket.pending, true);
assert.strictEqual(socket.connecting, true);
assert.strictEqual(socket.readyState, 'opening');
// Write a string that contains a multi-byte character sequence to test that
// `bytesWritten` is incremented with the # of bytes, not # of characters.
const a = "L'État, c'est ";
const b = 'moi';
// We're still connecting at this point so the datagram is first pushed onto
// the connect queue. Make sure that it's not added to `bytesWritten` again
// when the actual write happens.
const r = socket.write(a, common.mustCall((er) => {
console.error('write cb');
assert.ok(connected);
assert.strictEqual(socket.bytesWritten, Buffer.from(a + b).length);
assert.strictEqual(socket.pending, false);
}));
socket.on('close', common.mustCall(() => {
assert.strictEqual(socket.pending, true);
}));
assert.strictEqual(socket.bytesWritten, Buffer.from(a).length);
assert.strictEqual(r, false);
socket.end(b);
assert.strictEqual(socket.readyState, 'opening');
}));

View File

@@ -1,56 +0,0 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');
const tcp = net.Server(common.mustCall((s) => {
tcp.close();
let buf = '';
s.setEncoding('utf8');
s.on('data', function(d) {
buf += d;
});
s.on('end', common.mustCall(function() {
console.error('SERVER: end', buf);
assert.strictEqual(buf, "L'État, c'est moi");
s.end();
}));
}));
tcp.listen(0, common.mustCall(function() {
const socket = net.Stream({ highWaterMark: 0 });
let connected = false;
assert.strictEqual(socket.pending, true);
socket.connect(this.address().port, common.mustCall(() => connected = true));
assert.strictEqual(socket.pending, true);
assert.strictEqual(socket.connecting, true);
assert.strictEqual(socket.readyState, 'opening');
// Write a string that contains a multi-byte character sequence to test that
// `bytesWritten` is incremented with the # of bytes, not # of characters.
const a = "L'État, c'est ";
const b = 'moi';
// We're still connecting at this point so the datagram is first pushed onto
// the connect queue. Make sure that it's not added to `bytesWritten` again
// when the actual write happens.
const r = socket.write(a, common.mustCall((er) => {
console.error('write cb');
assert.ok(connected);
assert.strictEqual(socket.bytesWritten, Buffer.from(a + b).length);
assert.strictEqual(socket.pending, false);
}));
socket.on('close', common.mustCall(() => {
assert.strictEqual(socket.pending, true);
}));
assert.strictEqual(socket.bytesWritten, Buffer.from(a).length);
assert.strictEqual(r, false);
socket.end(b);
assert.strictEqual(socket.readyState, 'opening');
}));

View File

@@ -1,88 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const net = require('net');
const N = 50;
let client_recv_count = 0;
let client_end_count = 0;
let disconnect_count = 0;
const server = net.createServer(function(socket) {
console.error('SERVER: got socket connection');
socket.resume();
console.error('SERVER connect, writing');
socket.write('hello\r\n');
socket.on('end', () => {
console.error('SERVER socket end, calling end()');
socket.end();
});
socket.on('close', (had_error) => {
console.log(`SERVER had_error: ${JSON.stringify(had_error)}`);
assert.strictEqual(had_error, false);
});
});
server.listen(0, function() {
console.log('SERVER listening');
const client = net.createConnection(this.address().port);
client.setEncoding('UTF8');
client.on('connect', () => {
console.error('CLIENT connected', client._writableState);
});
client.on('data', function(chunk) {
client_recv_count += 1;
console.log(`client_recv_count ${client_recv_count}`);
assert.strictEqual(chunk, 'hello\r\n');
console.error('CLIENT: calling end', client._writableState);
client.end();
});
client.on('end', () => {
console.error('CLIENT end');
client_end_count++;
});
client.on('close', (had_error) => {
console.log('CLIENT disconnect');
assert.strictEqual(had_error, false);
if (disconnect_count++ < N)
client.connect(server.address().port); // reconnect
else
server.close();
});
});
process.on('exit', () => {
assert.strictEqual(disconnect_count, N + 1);
assert.strictEqual(client_recv_count, N + 1);
assert.strictEqual(client_end_count, N + 1);
});

View File

@@ -1,45 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');
const sockets = [];
const server = net.createServer(function(c) {
c.on('close', common.mustCall());
sockets.push(c);
if (sockets.length === 2) {
assert.strictEqual(server.close(), server);
sockets.forEach((c) => c.destroy());
}
});
server.on('close', common.mustCall());
assert.strictEqual(server, server.listen(0, () => {
net.createConnection(server.address().port);
net.createConnection(server.address().port);
}));

View File

@@ -1,49 +0,0 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');
const msg = 'test';
let stopped = true;
let server1Sock;
const server1ConnHandler = (socket) => {
socket.on('data', function(data) {
if (stopped) {
assert.fail('data event should not have happened yet');
}
assert.strictEqual(data.toString(), msg);
socket.end();
server1.close();
});
server1Sock = socket;
};
const server1 = net.createServer({ pauseOnConnect: true }, server1ConnHandler);
const server2ConnHandler = (socket) => {
socket.on('data', function(data) {
assert.strictEqual(data.toString(), msg);
socket.end();
server2.close();
assert.strictEqual(server1Sock.bytesRead, 0);
server1Sock.resume();
stopped = false;
});
};
const server2 = net.createServer({ pauseOnConnect: false }, server2ConnHandler);
server1.listen(0, function() {
const clientHandler = common.mustCall(function() {
server2.listen(0, function() {
net.createConnection({ port: this.address().port }).write(msg);
});
});
net.createConnection({ port: this.address().port }).write(msg, clientHandler);
});
process.on('exit', function() {
assert.strictEqual(stopped, false);
});

View File

@@ -1,41 +0,0 @@
'use strict';
const common = require('../common');
// Skip test in FreeBSD jails
if (common.inFreeBSDJail)
common.skip('In a FreeBSD jail');
const assert = require('assert');
const net = require('net');
let conns = 0;
const clientLocalPorts = [];
const serverRemotePorts = [];
const client = new net.Socket();
const server = net.createServer((socket) => {
serverRemotePorts.push(socket.remotePort);
socket.end();
});
server.on('close', common.mustCall(() => {
// Client and server should agree on the ports used
assert.deepStrictEqual(serverRemotePorts, clientLocalPorts);
assert.strictEqual(conns, 2);
}));
server.listen(0, common.localhostIPv4, connect);
function connect() {
if (conns === 2) {
server.close();
return;
}
conns++;
client.once('close', connect);
assert.strictEqual(
client,
client.connect(server.address().port, common.localhostIPv4, () => {
clientLocalPorts.push(client.localPort);
})
);
}

View File

@@ -1,60 +0,0 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const { hasOpenSSL } = require('../common/crypto');
// This test ensures that `getProtocol` returns the right protocol
// from a TLS connection
const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');
const clientConfigs = [
{
secureProtocol: 'TLSv1_method',
version: 'TLSv1',
ciphers: (hasOpenSSL(3, 1) ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT')
}, {
secureProtocol: 'TLSv1_1_method',
version: 'TLSv1.1',
ciphers: (hasOpenSSL(3, 1) ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT')
}, {
secureProtocol: 'TLSv1_2_method',
version: 'TLSv1.2'
},
];
const serverConfig = {
secureProtocol: 'TLS_method',
key: fixtures.readKey('agent2-key.pem'),
cert: fixtures.readKey('agent2-cert.pem')
};
if (!process.features.openssl_is_boringssl) {
serverConfig.ciphers = 'RSA@SECLEVEL=0';
}
const server = tls.createServer(serverConfig, common.mustCall(clientConfigs.length))
.listen(0, common.localhostIPv4, function() {
let connected = 0;
for (const v of clientConfigs) {
tls.connect({
host: common.localhostIPv4,
port: server.address().port,
ciphers: v.ciphers,
rejectUnauthorized: false,
secureProtocol: v.secureProtocol
}, common.mustCall(function() {
assert.strictEqual(this.getProtocol(), v.version);
this.on('end', common.mustCall());
this.on('close', common.mustCall(function() {
assert.strictEqual(this.getProtocol(), null);
})).end();
if (++connected === clientConfigs.length)
server.close();
}));
}
});

View File

@@ -1,17 +0,0 @@
'use strict';
const common = require('../common');
const net = require('net');
const assert = require('assert');
const c = net.createConnection(common.PORT);
c.on('connect', common.mustNotCall());
c.on('error', common.mustCall(function(error) {
// Family autoselection might be skipped if only a single address is returned by DNS.
const failedAttempt = Array.isArray(error.errors) ? error.errors[0] : error;
assert.strictEqual(failedAttempt.code, 'ECONNREFUSED');
assert.strictEqual(failedAttempt.port, common.PORT);
assert.match(failedAttempt.address, /^(127\.0\.0\.1|::1)$/);
}));

View File

@@ -1,32 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const common = require('../common');
const net = require('net');
const assert = require('assert');
const c = net.createConnection(common.PORT);
c.on('connect', common.mustNotCall());
c.on('error', common.mustCall((e) => {
assert.strictEqual(c.connecting, false);
assert.strictEqual(e.code, 'ECONNREFUSED');
}));

View File

@@ -1,64 +0,0 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');
// With only a callback, server should get a port assigned by the OS
{
const server = net.createServer(common.mustNotCall());
server.listen(common.mustCall(function() {
assert.ok(server.address().port > 100);
server.close();
}));
}
// No callback to listen(), assume we can bind in 100 ms
{
const server = net.createServer(common.mustNotCall());
server.listen(common.PORT);
setTimeout(function() {
const address = server.address();
assert.strictEqual(address.port, common.PORT);
if (address.family === 'IPv6')
assert.strictEqual(server._connectionKey, `6::::${address.port}`);
else
assert.strictEqual(server._connectionKey, `4:0.0.0.0:${address.port}`);
server.close();
}, 100);
}
// Callback to listen()
{
const server = net.createServer(common.mustNotCall());
server.listen(common.PORT + 1, common.mustCall(function() {
assert.strictEqual(server.address().port, common.PORT + 1);
server.close();
}));
}
// Backlog argument
{
const server = net.createServer(common.mustNotCall());
server.listen(common.PORT + 2, '0.0.0.0', 127, common.mustCall(function() {
assert.strictEqual(server.address().port, common.PORT + 2);
server.close();
}));
}
// Backlog argument without host argument
{
const server = net.createServer(common.mustNotCall());
server.listen(common.PORT + 3, 127, common.mustCall(function() {
assert.strictEqual(server.address().port, common.PORT + 3);
server.close();
}));
}

View File

@@ -1,27 +0,0 @@
const vm = require("vm");
const { describe, it, expect } = require("bun:test");
describe("vm.Script", () => {
it("shouldn't leak memory", () => {
const initialUsage = process.memoryUsage.rss();
{
const source = `/*\n${Buffer.alloc(10000, " * aaaaa\n").toString("utf8")}\n*/ Buffer.alloc(10, 'hello');`;
function go(i) {
const script = new vm.Script(source + "//" + i);
script.runInThisContext();
}
for (let i = 0; i < 10000; ++i) {
go(i);
}
}
Bun.gc(true);
const finalUsage = process.memoryUsage.rss();
const megabytes = Math.round(((finalUsage - initialUsage) / 1024 / 1024) * 100) / 100;
expect(megabytes).toBeLessThan(200);
});
});

View File

@@ -1,30 +0,0 @@
const vm = require("vm");
const { describe, it, expect } = require("bun:test");
describe("vm.SourceTextModule", () => {
it("shouldn't leak memory", async () => {
const initialUsage = process.memoryUsage.rss();
{
const source = `/*\n${Buffer.alloc(50_000, " * aaaaa\n").toString("utf8")}\n*/ Buffer.alloc(10, 'hello');`;
async function go(i) {
const mod = new vm.SourceTextModule(source + "//" + i, {
identifier: Buffer.alloc(64, i.toString()).toString("utf8"),
});
await mod.link(() => {});
await mod.evaluate();
}
for (let i = 0; i < 50_000; ++i) {
await go(i);
}
}
Bun.gc(true);
const finalUsage = process.memoryUsage.rss();
const megabytes = Math.round(((finalUsage - initialUsage) / 1024 / 1024) * 100) / 100;
expect(megabytes).toBeLessThan(3000);
});
});