chore: upgrade Node.js to v24.10.0 (#48613)

* chore: upgrade Node.js to v24.10.0

* chore: fixup crypto patch

* chore: fixup crypto test patch

* src: prepare for v8 sandboxing

https://github.com/nodejs/node/pull/58376

* esm: fix module.exports export on CJS modules

https://github.com/nodejs/node/pull/57366

* chore: fixup lazyload fs patch

* esm: Source Phase Imports for WebAssembly

https://github.com/nodejs/node/pull/56919

* module: remove --experimental-default-type

https://github.com/nodejs/node/pull/56092

* lib,src: refactor assert to load error source from memory

https://github.com/nodejs/node/pull/59751

* src: add source location to v8::TaskRunner

https://github.com/nodejs/node/pull/54077

* src: remove dependency on wrapper-descriptor-based CppHeap

https://github.com/nodejs/node/pull/54077

* src: do not use soon-to-be-deprecated V8 API

https://github.com/nodejs/node/pull/53174

* src: stop using deprecated fields of v8::FastApiCallbackOptions

https://github.com/nodejs/node/pull/54077

* test: update v8-stats test for V8 12.6

https://github.com/nodejs/node/pull/54077

* esm: unflag --experimental-wasm-modules

https://github.com/nodejs/node/pull/57038

* test: adapt assert tests to stack trace changes

https://github.com/nodejs/node/pull/58070

* src,test: unregister the isolate after disposal and before freeing

https://github.com/nodejs/node/pull/58070

* src: use cppgc to manage ContextifyContext

https://github.com/nodejs/node/pull/56522

* src: replace uses of FastApiTypedArray

https://github.com/nodejs/node/pull/58070

* module: integrate TypeScript into compile cache

https://github.com/nodejs/node/pull/56629

* deps: update ada to 3.2.7

https://github.com/nodejs/node/pull/59336

* src: make minor cleanups in encoding_binding.cc

https://github.com/nodejs/node/pull/57448

* src: switch from `Get/SetPrototype` to `Get/SetPrototypeV2`

https://github.com/nodejs/node/pull/55453

* src: use non-deprecated Get/SetPrototype methods

https://github.com/nodejs/node/pull/59671

* src: simplify string_bytes with views

https://github.com/nodejs/node/pull/54876

* src: improve utf8 string generation performance

https://github.com/nodejs/node/pull/54873

* src: use non-deprecated Utf8LengthV2() method

https://github.com/nodejs/node/pull/58070

* src: use non-deprecated WriteUtf8V2() method

https://github.com/nodejs/node/pull/58070

* src: refactor WriteUCS2 and remove flags argument

https://github.com/nodejs/node/pull/58163

* src: use String::WriteV2() in TwoByteValue

https://github.com/nodejs/node/pull/58164

* node-api: use WriteV2 in napi_get_value_string_utf16

https://github.com/nodejs/node/pull/58165

* node-api: use WriteOneByteV2 in napi_get_value_string_latin1

https://github.com/nodejs/node/pull/58325

* src: migrate WriteOneByte to WriteOneByteV2

https://github.com/nodejs/node/pull/59634

* fs: introduce dirent\.parentPath

https://github.com/nodejs/node/pull/50976

* src: avoid copy by using std::views::keys

https://github.com/nodejs/node/pull/56080

* chore: fixup patch indices

* fix: errant use of context->GetIsolate()

* fix: tweak BoringSSL compat patch for new changes

* fix: add back missing isolate dtor declaration

* fixup! esm: fix module.exports export on CJS modules

* cli: remove --no-experimental-fetch flag

https://github.com/nodejs/node/pull/52611/files

* esm: Source Phase Imports for WebAssembly

https://github.com/nodejs/node/pull/56919

* fixup! src: prepare for v8 sandboxing

* chore: bump @types/node to v24

* chore: fix const assignment in crypto test

* fix: sandbox pointer patch issues

* chore: rework source phase import patch

* src: add percentage support to --max-old-space-size

https://github.com/nodejs/node/pull/59082

* chore: fixup crypto tests

* chore: HostImportModuleWithPhaseDynamically todo

* fix: cjs esm failures

* fix: v8::Object::Wrappable issues

- b72a615754
- 490bac2496
- 4896a0dd69

* chore: remove deleted specs

* src: use v8::ExternalMemoryAccounter

https://github.com/nodejs/node/pull/58070

* fs: port SonicBoom module to fs module as FastUtf8Stream

https://github.com/nodejs/node/pull/58897

* chore: tweak sandboxed pr patch

* test: disable parallel/test-os-checked-function

* test: use WHATWG URL instead of url.parse

* fix: OPENSSL_secure_zalloc doesn't work in BoringSSL

* chore: fix accidental extra line

* 7017517: [defer-import-eval] Parse import defer syntax

https://chromium-review.googlesource.com/c/v8/v8/+/7017517
This commit is contained in:
Shelley Vohr
2025-10-30 19:16:48 +01:00
committed by GitHub
parent c5fe50be3b
commit 3345edd2bf
80 changed files with 2001 additions and 4067 deletions

2
DEPS
View File

@@ -4,7 +4,7 @@ vars = {
'chromium_version':
'143.0.7499.0',
'node_version':
'v22.20.0',
'v24.10.0',
'nan_version':
'675cefebca42410733da8a454c8d9391fcebfbc2',
'squirrel.mac_version':

View File

@@ -119,7 +119,10 @@ export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypa
p.reject(err);
});
if (!req.body?.pipeTo(Writable.toWeb(r as unknown as Writable)).then(() => r.end())) { r.end(); }
// pipeTo expects a WritableStream<Uint8Array>. Node.js' Writable.toWeb returns WritableStream<any>,
// which causes a TS structural mismatch.
const writable = Writable.toWeb(r as unknown as Writable) as unknown as WritableStream<Uint8Array>;
if (!req.body?.pipeTo(writable).then(() => r.end())) { r.end(); }
return p.promise;
}

View File

@@ -4,6 +4,8 @@ import { createReadStream } from 'fs';
import { Readable } from 'stream';
import { ReadableStream } from 'stream/web';
import type { ReadableStreamDefaultReader } from 'stream/web';
// Global protocol APIs.
const { registerSchemesAsPrivileged, getStandardSchemes, Protocol } = process._linkedBinding('electron_browser_protocol');
@@ -12,7 +14,7 @@ const ERR_UNEXPECTED = -9;
const isBuiltInScheme = (scheme: string) => ['http', 'https', 'file'].includes(scheme);
function makeStreamFromPipe (pipe: any): ReadableStream {
function makeStreamFromPipe (pipe: any): ReadableStream<Uint8Array> {
const buf = new Uint8Array(1024 * 1024 /* 1 MB */);
return new ReadableStream({
async pull (controller) {
@@ -38,21 +40,26 @@ function makeStreamFromFileInfo ({
filePath: string;
offset?: number;
length?: number;
}): ReadableStream {
}): ReadableStream<Uint8Array> {
// Node's Readable.toWeb produces a WHATWG ReadableStream whose chunks are Uint8Array.
return Readable.toWeb(createReadStream(filePath, {
start: offset,
end: length >= 0 ? offset + length : undefined
}));
})) as ReadableStream<Uint8Array>;
}
function convertToRequestBody (uploadData: ProtocolRequest['uploadData']): RequestInit['body'] {
if (!uploadData) return null;
// Optimization: skip creating a stream if the request is just a single buffer.
if (uploadData.length === 1 && (uploadData[0] as any).type === 'rawData') return uploadData[0].bytes;
if (uploadData.length === 1 && (uploadData[0] as any).type === 'rawData') {
return uploadData[0].bytes as any;
}
const chunks = [...uploadData] as any[]; // TODO: types are wrong
let current: ReadableStreamDefaultReader | null = null;
return new ReadableStream({
const chunks = [...uploadData] as any[]; // TODO: refine ProtocolRequest types
// Use Node's web stream types explicitly to avoid DOM lib vs Node lib structural mismatches.
// Generic <Uint8Array> ensures reader.read() returns value?: Uint8Array consistent with enqueue.
let current: ReadableStreamDefaultReader<Uint8Array> | null = null;
return new ReadableStream<Uint8Array>({
async pull (controller) {
if (current) {
const { done, value } = await current.read();
@@ -67,7 +74,7 @@ function convertToRequestBody (uploadData: ProtocolRequest['uploadData']): Reque
if (!chunks.length) { return controller.close(); }
const chunk = chunks.shift()!;
if (chunk.type === 'rawData') {
controller.enqueue(chunk.bytes);
controller.enqueue(chunk.bytes as Uint8Array);
} else if (chunk.type === 'file') {
current = makeStreamFromFileInfo(chunk).getReader();
return this.pull!(controller);

View File

@@ -40,7 +40,7 @@ process.on('uncaughtException', function (error) {
// Emit 'exit' event on quit.
const { app } = require('electron');
app.on('quit', (_event, exitCode) => {
app.on('quit', (_event: any, exitCode: number) => {
process.emit('exit', exitCode);
});

View File

@@ -746,7 +746,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
context.readdirResults.push(dirent);
if (dirent!.isDirectory() || stat === 1) {
context.pathsQueue.push(path.join(dirent!.path, dirent!.name));
context.pathsQueue.push(path.join(dirent!.parentPath, dirent!.name));
}
}
}

View File

@@ -9,7 +9,7 @@
},
"dependencies": {
"@electron/get": "^2.0.0",
"@types/node": "^22.7.7",
"@types/node": "^24.9.0",
"extract-zip": "^2.0.1"
},
"engines": {

View File

@@ -14,7 +14,7 @@
"@octokit/rest": "^20.1.2",
"@primer/octicons": "^10.0.0",
"@types/minimist": "^1.2.5",
"@types/node": "^22.7.7",
"@types/node": "^24.9.0",
"@types/semver": "^7.5.8",
"@types/stream-json": "^1.7.8",
"@types/temp": "^0.9.4",

View File

@@ -17,48 +17,25 @@ chore_expose_importmoduledynamically_and.patch
test_formally_mark_some_tests_as_flaky.patch
fix_do_not_resolve_electron_entrypoints.patch
ci_ensure_node_tests_set_electron_run_as_node.patch
fix_assert_module_in_the_renderer_process.patch
fix_allow_passing_fileexists_fn_to_legacymainresolve.patch
fix_remove_deprecated_errno_constants.patch
build_enable_perfetto.patch
fix_add_source_location_for_v8_task_runner.patch
src_remove_dependency_on_wrapper-descriptor-based_cppheap.patch
test_update_v8-stats_test_for_v8_12_6.patch
src_do_not_use_soon-to-be-deprecated_v8_api.patch
src_stop_using_deprecated_fields_of_fastapicallbackoptions.patch
build_compile_with_c_20_support.patch
add_v8_taskpirority_to_foreground_task_runner_signature.patch
cli_remove_deprecated_v8_flag.patch
build_restore_clang_as_default_compiler_on_macos.patch
fix_remove_outdated_v8_flags_from_node_cc.patch
chore_disable_deprecation_ftbfs_in_simdjson_header.patch
build_allow_unbundling_of_node_js_dependencies.patch
test_use_static_method_names_in_call_stacks.patch
fix_remove_fastapitypedarray_usage.patch
test_handle_explicit_resource_management_globals.patch
build_change_crdtp_protocoltypetraits_signatures_to_avoid_conflict.patch
fix_adjust_wpt_and_webidl_tests_for_enabled_float16array.patch
chore_add_createexternalizabletwobytestring_to_globals.patch
refactor_attach_cppgc_heap_on_v8_isolate_creation.patch
fix_ensure_traverseparent_bails_on_resource_path_exit.patch
cli_move_--trace-atomics-wait_to_eol.patch
fix_cppgc_initializing_twice.patch
fix_task_starvation_in_inspector_context_test.patch
fix_expose_readfilesync_override_for_modules.patch
fix_array_out-of-bounds_read_in_boyer-moore_search.patch
chore_add_missing_include_of_iterator.patch
test_accomodate_v8_thenable_stack_trace_change_in_snapshot.patch
chore_exclude_electron_node_folder_from_exit-time-destructors.patch
api_remove_deprecated_getisolate.patch
src_switch_from_get_setprototype_to_get_setprototypev2.patch
fix_replace_deprecated_setprototype.patch
fix_redefined_macos_sdk_header_symbols.patch
src_simplify_string_bytes_with_views.patch
src_improve_utf8_string_generation_performance.patch
src_use_non-deprecated_utf8lengthv2_method.patch
src_use_non-deprecated_writeutf8v2_method.patch
src_refactor_writeucs2_and_remove_flags_argument.patch
src_use_string_writev2_in_twobytevalue.patch
node-api_use_writev2_in_napi_get_value_string_utf16.patch
node-api_use_writeonebytev2_in_napi_get_value_string_latin1.patch
src_migrate_writeonebyte_to_writeonebytev2.patch
fix_allow_disabling_fetch_in_renderer_and_worker_processes.patch
feat_disable_js_source_phase_imports_by_default.patch
fix_avoid_external_memory_leak_on_invalid_tls_protocol_versions.patch
lib_check_sharedarraybuffer_existence_in_fast-utf8-stream.patch
chore_handle_support_for_import_defer_as_ns_and_import_defer.patch

View File

@@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Calvin Watford <cwatford@slack-corp.com>
Date: Wed, 18 Sep 2024 16:25:05 -0600
Subject: add v8::TaskPirority to foreground task runner signature
For now, we ignore the priority parameter. We expect this will be fixed
naturally upstream, and we will be able to remove this patch in a future
Node.js upgrade.
diff --git a/src/node_platform.cc b/src/node_platform.cc
index b24e170cb247261d4a16d77ad40df4dfd33709d9..5e31f984b5655ae2d1d7559b1bd550ba6dc90fb4 100644
--- a/src/node_platform.cc
+++ b/src/node_platform.cc
@@ -688,8 +688,8 @@ bool NodePlatform::IdleTasksEnabled(Isolate* isolate) {
return ForIsolate(isolate)->IdleTasksEnabled();
}
-std::shared_ptr<v8::TaskRunner>
-NodePlatform::GetForegroundTaskRunner(Isolate* isolate) {
+std::shared_ptr<v8::TaskRunner> NodePlatform::GetForegroundTaskRunner(
+ Isolate* isolate, v8::TaskPriority priority) {
return ForIsolate(isolate)->GetForegroundTaskRunner();
}
diff --git a/src/node_platform.h b/src/node_platform.h
index a0222b4a1b074c6708e390d58d04221717069ac1..8015ca1801573c3a7c4a5db6d0f10b4016a9267c 100644
--- a/src/node_platform.h
+++ b/src/node_platform.h
@@ -213,7 +213,7 @@ class NodePlatform : public MultiIsolatePlatform {
void (*callback)(void*), void* data) override;
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
- v8::Isolate* isolate) override;
+ v8::Isolate* isolate, v8::TaskPriority priority) override;
Platform::StackTracePrinter GetStackTracePrinter() override;
v8::PageAllocator* GetPageAllocator() override;

View File

@@ -6,10 +6,10 @@ Subject: Remove deprecated `GetIsolate`
https://chromium-review.googlesource.com/c/v8/v8/+/6905244
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7c630fddf 100644
index 072deb1fa70313e33397f6ff994e3f3548e86092..14be033113bfb13c64e5f99446afaf0cb2aa16a9 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -654,7 +654,7 @@ std::unique_ptr<MultiIsolatePlatform> MultiIsolatePlatform::Create(
@@ -669,7 +669,7 @@ std::unique_ptr<MultiIsolatePlatform> MultiIsolatePlatform::Create(
MaybeLocal<Object> GetPerContextExports(Local<Context> context,
IsolateData* isolate_data) {
@@ -18,7 +18,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
EscapableHandleScope handle_scope(isolate);
Local<Object> global = context->Global();
@@ -700,7 +700,7 @@ void ProtoThrower(const FunctionCallbackInfo<Value>& info) {
@@ -715,7 +715,7 @@ void ProtoThrower(const FunctionCallbackInfo<Value>& info) {
// This runs at runtime, regardless of whether the context
// is created from a snapshot.
Maybe<void> InitializeContextRuntime(Local<Context> context) {
@@ -27,7 +27,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
HandleScope handle_scope(isolate);
// When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path
@@ -779,7 +779,7 @@ Maybe<void> InitializeContextRuntime(Local<Context> context) {
@@ -794,7 +794,7 @@ Maybe<void> InitializeContextRuntime(Local<Context> context) {
}
Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
@@ -36,7 +36,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
HandleScope handle_scope(isolate);
// Delete `Intl.v8BreakIterator`
@@ -804,7 +804,7 @@ Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
@@ -819,7 +819,7 @@ Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
}
Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
@@ -45,7 +45,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
HandleScope handle_scope(isolate);
// Initialize the default values.
@@ -822,7 +822,7 @@ Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
@@ -837,7 +837,7 @@ Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
IsolateData* isolate_data) {
CHECK(isolate_data);
@@ -54,7 +54,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
EscapableHandleScope scope(isolate);
Context::Scope context_scope(context);
@@ -846,7 +846,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
@@ -861,7 +861,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
IsolateData* isolate_data) {
CHECK(isolate_data);
@@ -63,7 +63,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
EscapableHandleScope scope(isolate);
Context::Scope context_scope(context);
@@ -872,7 +872,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
@@ -887,7 +887,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
Maybe<void> InitializePrimordials(Local<Context> context,
IsolateData* isolate_data) {
// Run per-context JS files.
@@ -73,7 +73,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7
Local<Object> exports;
diff --git a/src/base_object-inl.h b/src/base_object-inl.h
index 6f731b17fe0b84dd3d2c9bc9cfef1f8062a2c5f7..71a1072ed2decbee08d40eda7c47456be5093bc2 100644
index cc60ddddb037e0279615bbe24821eb20fd8da677..37d83e41b618a07aca98118260abe9618f11256d 100644
--- a/src/base_object-inl.h
+++ b/src/base_object-inl.h
@@ -55,7 +55,6 @@ v8::Local<v8::Object> BaseObject::object() const {
@@ -85,10 +85,10 @@ index 6f731b17fe0b84dd3d2c9bc9cfef1f8062a2c5f7..71a1072ed2decbee08d40eda7c47456b
return handle;
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index a3d309d832c73ddc79564b9644d825bec7459e7f..580cbaf3858961f375ca2f53c48a07bcba82ef46 100644
index 20d3c1d9d17fde18fc09b6ee219137831eb08a45..8fbf4f25a91b953f3d2868889c7ee06932ee3c5f 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -967,7 +967,7 @@ bool ArrayOfStringsToX509s(Local<Context> context,
@@ -1022,7 +1022,7 @@ bool ArrayOfStringsToX509s(Local<Context> context,
Local<Array> cert_array,
std::vector<X509*>* certs) {
ClearErrorOnReturn clear_error_on_return;
@@ -98,11 +98,11 @@ index a3d309d832c73ddc79564b9644d825bec7459e7f..580cbaf3858961f375ca2f53c48a07bc
uint32_t array_length = cert_array->Length();
diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc
index eb6dad44a49d997097c8fb5009eeb60a7305da27..fd29d17de195017970856ce30d7a9c5785b0b8ee 100644
index 4c5427596d1c90d3a413cdd9ff4f1151e657073d..70135a6be65e41fcb3564ddf6d1e8083a59ef8bb 100644
--- a/src/crypto/crypto_x509.cc
+++ b/src/crypto/crypto_x509.cc
@@ -97,7 +97,7 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, BIOPointer&& bio) {
if (!bio) return {};
@@ -107,7 +107,7 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, BIOPointer&& bio) {
return {};
BUF_MEM* mem = bio;
Local<Value> ret;
- if (!String::NewFromUtf8(context->GetIsolate(),
@@ -110,32 +110,8 @@ index eb6dad44a49d997097c8fb5009eeb60a7305da27..fd29d17de195017970856ce30d7a9c57
mem->data,
NewStringType::kNormal,
mem->length)
@@ -121,7 +121,7 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, const ASN1_OBJECT* obj) {
}
Local<Value> result;
- if (!String::NewFromUtf8(context->GetIsolate(), str).ToLocal(&result)) {
+ if (!String::NewFromUtf8(Isolate::GetCurrent(), str).ToLocal(&result)) {
@@ -121,7 +121,7 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, const BIOPointer& bio) {
return {};
}
return result;
@@ -136,12 +136,12 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, const ASN1_STRING* str) {
unsigned char* value_str;
int value_str_size = ASN1_STRING_to_UTF8(&value_str, str);
if (value_str_size < 0) {
- return Undefined(context->GetIsolate());
+ return Undefined(Isolate::GetCurrent());
}
DataPointer free_value_str(value_str, value_str_size);
Local<Value> result;
- if (!String::NewFromUtf8(context->GetIsolate(),
+ if (!String::NewFromUtf8(Isolate::GetCurrent(),
reinterpret_cast<const char*>(value_str),
NewStringType::kNormal,
value_str_size)
@@ -155,7 +155,7 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, const BIOPointer& bio) {
if (!bio) return {};
BUF_MEM* mem = bio;
Local<Value> ret;
- if (!String::NewFromUtf8(context->GetIsolate(),
@@ -144,23 +120,23 @@ index eb6dad44a49d997097c8fb5009eeb60a7305da27..fd29d17de195017970856ce30d7a9c57
NewStringType::kNormal,
mem->length)
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
index 31ed995714bb99ab534f26ba9ebc6051c258a1c9..5ace688bb7ffc86eedf5aff11ab0ab487ad9440e 100644
index 266f640fb1c6503a424e77cc41fc15bc658bb6a5..877ae8a18f6b8f2c7e3474dfba060d99db88e6b9 100644
--- a/src/encoding_binding.cc
+++ b/src/encoding_binding.cc
@@ -73,7 +73,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -76,7 +76,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
- v8::HandleScope scope(context->GetIsolate());
+ v8::HandleScope scope(Isolate::GetCurrent());
- HandleScope scope(context->GetIsolate());
+ HandleScope scope(Isolate::GetCurrent());
Realm* realm = Realm::GetCurrent(context);
// Recreate the buffer in the constructor.
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
diff --git a/src/env.cc b/src/env.cc
index c6209cc7cf317de1bb9217e39dd760e5a83303e2..161d577e0ea6a251c83ba1903b1ec9a582a5317c 100644
index a78817467518245c4a190e870e0eb30658eafcdb..13dcf0e9c2c86486d1e43763033f43ac4e6b6feb 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -1748,10 +1748,10 @@ void AsyncHooks::Deserialize(Local<Context> context) {
@@ -1753,10 +1753,10 @@ void AsyncHooks::Deserialize(Local<Context> context) {
context->GetDataFromSnapshotOnce<Array>(
info_->js_execution_async_resources).ToLocalChecked();
} else {
@@ -173,7 +149,7 @@ index c6209cc7cf317de1bb9217e39dd760e5a83303e2..161d577e0ea6a251c83ba1903b1ec9a5
// The native_execution_async_resources_ field requires v8::Local<> instances
// for async calls whose resources were on the stack as JS objects when they
@@ -1791,7 +1791,7 @@ AsyncHooks::SerializeInfo AsyncHooks::Serialize(Local<Context> context,
@@ -1796,7 +1796,7 @@ AsyncHooks::SerializeInfo AsyncHooks::Serialize(Local<Context> context,
info.async_id_fields = async_id_fields_.Serialize(context, creator);
if (!js_execution_async_resources_.IsEmpty()) {
info.js_execution_async_resources = creator->AddData(
@@ -183,7 +159,7 @@ index c6209cc7cf317de1bb9217e39dd760e5a83303e2..161d577e0ea6a251c83ba1903b1ec9a5
} else {
info.js_execution_async_resources = 0;
diff --git a/src/inspector/network_agent.cc b/src/inspector/network_agent.cc
index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af20f4e2e89 100644
index d136b72e598d07f3c2fcc9c2c8ba84f5ff1aaad7..649008aafc8d68cfecb02c28ad1e26a9b749f7bd 100644
--- a/src/inspector/network_agent.cc
+++ b/src/inspector/network_agent.cc
@@ -29,31 +29,31 @@ using v8::Value;
@@ -296,6 +272,15 @@ index 3b5d9615021101ad03d9dfef83e0c56b462b59ad..823e7b8d3d07eb2afa1cc62d3d9e2af2
protocol::String url;
if (!ObjectGetProtocolString(context, response, "url").To(&url)) {
return {};
@@ -210,7 +210,7 @@ std::unique_ptr<protocol::Network::Response> createResponseFromObject(
std::unique_ptr<protocol::Network::WebSocketResponse> createWebSocketResponse(
v8::Local<v8::Context> context, Local<Object> response) {
- HandleScope handle_scope(context->GetIsolate());
+ HandleScope handle_scope(v8::Isolate::GetCurrent());
int status;
if (!ObjectGetInt(context, response, "status").To(&status)) {
return {};
diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h
index 27aeac589b19cd681923fb848ce5f36c66fc05e2..5f2900869763f40cac54e3cb3fe2e24eda615410 100644
--- a/src/js_native_api_v8.h
@@ -310,10 +295,37 @@ index 27aeac589b19cd681923fb848ce5f36c66fc05e2..5f2900869763f40cac54e3cb3fe2e24e
module_api_version(module_api_version) {
napi_clear_last_error(this);
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index cbb3e7f4df72f83cb8a1afc25a7429218792e964..ffccac5589bfe12eaf7861364cc6f2e403d26679 100644
index 8fed194cbae9ce75bd0805b4df30b4de64fbbefa..a584e3a80adb69d2028dc79450349823ab973a58 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -865,7 +865,7 @@ MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
@@ -99,7 +99,7 @@ ModuleCacheKey ModuleCacheKey::From(Local<Context> context,
Local<String> specifier,
Local<FixedArray> import_attributes) {
CHECK_EQ(import_attributes->Length() % elements_per_attribute, 0);
- Isolate* isolate = context->GetIsolate();
+ Isolate* isolate = Isolate::GetCurrent();
std::size_t h1 = specifier->GetIdentityHash();
size_t num_attributes = import_attributes->Length() / elements_per_attribute;
ImportAttributeVector attributes;
@@ -1022,7 +1022,7 @@ MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
return {};
}
DCHECK_NOT_NULL(resolved_module);
- return resolved_module->module_.Get(context->GetIsolate());
+ return resolved_module->module_.Get(Isolate::GetCurrent());
}
// static
@@ -1046,7 +1046,7 @@ MaybeLocal<Object> ModuleWrap::ResolveSourceCallback(
Local<String> url = resolved_module->object()
->GetInternalField(ModuleWrap::kURLSlot)
.As<String>();
- THROW_ERR_SOURCE_PHASE_NOT_DEFINED(context->GetIsolate(), url);
+ THROW_ERR_SOURCE_PHASE_NOT_DEFINED(Isolate::GetCurrent(), url);
return {};
}
CHECK(module_source_object->IsObject());
@@ -1059,7 +1059,7 @@ Maybe<ModuleWrap*> ModuleWrap::ResolveModule(
Local<String> specifier,
Local<FixedArray> import_attributes,
Local<Module> referrer) {
@@ -322,16 +334,16 @@ index cbb3e7f4df72f83cb8a1afc25a7429218792e964..ffccac5589bfe12eaf7861364cc6f2e4
Environment* env = Environment::GetCurrent(context);
if (env == nullptr) {
THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
@@ -907,7 +907,7 @@ MaybeLocal<Promise> ImportModuleDynamically(
Local<Value> resource_name,
@@ -1104,7 +1104,7 @@ MaybeLocal<Promise> ImportModuleDynamicallyWithPhase(
Local<String> specifier,
ModuleImportPhase phase,
Local<FixedArray> import_attributes) {
- Isolate* isolate = context->GetIsolate();
+ Isolate* isolate = Isolate::GetCurrent();
Environment* env = Environment::GetCurrent(context);
if (env == nullptr) {
THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
@@ -1131,7 +1131,7 @@ MaybeLocal<Module> LinkRequireFacadeWithOriginal(
@@ -1346,7 +1346,7 @@ MaybeLocal<Module> LinkRequireFacadeWithOriginal(
Local<FixedArray> import_attributes,
Local<Module> referrer) {
Environment* env = Environment::GetCurrent(context);
@@ -341,10 +353,10 @@ index cbb3e7f4df72f83cb8a1afc25a7429218792e964..ffccac5589bfe12eaf7861364cc6f2e4
CHECK(!env->temporary_required_module_facade_original.IsEmpty());
return env->temporary_required_module_facade_original.Get(isolate);
diff --git a/src/node.h b/src/node.h
index 16a0c71aef949b0ddd27def9dc843298f9a6b75f..28fa4cb3e7a621480a5ff11c48666c0de1363375 100644
index 7fae281a6e0f3c1a9f0eb97536883bb26c16d94d..fb37310f44c8d06d1ab2697ed64a0b539776a411 100644
--- a/src/node.h
+++ b/src/node.h
@@ -1050,7 +1050,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
@@ -1064,7 +1064,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
#define NODE_DEFINE_CONSTANT(target, constant) \
do { \
@@ -353,7 +365,7 @@ index 16a0c71aef949b0ddd27def9dc843298f9a6b75f..28fa4cb3e7a621480a5ff11c48666c0d
v8::Local<v8::Context> context = isolate->GetCurrentContext(); \
v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \
isolate, #constant, v8::NewStringType::kInternalized); \
@@ -1066,7 +1066,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
@@ -1080,7 +1080,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \
do { \
@@ -363,7 +375,7 @@ index 16a0c71aef949b0ddd27def9dc843298f9a6b75f..28fa4cb3e7a621480a5ff11c48666c0d
v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \
isolate, #constant, v8::NewStringType::kInternalized); \
diff --git a/src/node_blob.cc b/src/node_blob.cc
index 9b9956f5ee3150a80f040cd0dbb9ef6589295600..14de0dad25fbf854ea23eb25abd6f9f2179e0dad 100644
index d278a32c9934c15bc721da164efccca7bc7e7111..ab862bf93a411e6ae6da7c9f9706cee279a0ad70 100644
--- a/src/node_blob.cc
+++ b/src/node_blob.cc
@@ -554,7 +554,7 @@ void BlobBindingData::Deserialize(Local<Context> context,
@@ -376,10 +388,10 @@ index 9b9956f5ee3150a80f040cd0dbb9ef6589295600..14de0dad25fbf854ea23eb25abd6f9f2
BlobBindingData* binding = realm->AddBindingData<BlobBindingData>(holder);
CHECK_NOT_NULL(binding);
diff --git a/src/node_builtins.cc b/src/node_builtins.cc
index 4b288e0f89e0156cb5b0555c0259b2c1150770db..bc87057c8473d4731de55b909c58106217b32d1b 100644
index e69eb280050cae0c0f394b2f956eef947e628904..9bb4576fcf4f07550e7d6f4ff2310cedc8093c5f 100644
--- a/src/node_builtins.cc
+++ b/src/node_builtins.cc
@@ -275,7 +275,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
@@ -274,7 +274,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
const char* id,
LocalVector<String>* parameters,
Realm* optional_realm) {
@@ -388,7 +400,7 @@ index 4b288e0f89e0156cb5b0555c0259b2c1150770db..bc87057c8473d4731de55b909c581062
EscapableHandleScope scope(isolate);
Local<String> source;
@@ -397,7 +397,7 @@ void BuiltinLoader::SaveCodeCache(const char* id, Local<Function> fun) {
@@ -396,7 +396,7 @@ void BuiltinLoader::SaveCodeCache(const char* id, Local<Function> fun) {
MaybeLocal<Function> BuiltinLoader::LookupAndCompile(Local<Context> context,
const char* id,
Realm* optional_realm) {
@@ -397,7 +409,7 @@ index 4b288e0f89e0156cb5b0555c0259b2c1150770db..bc87057c8473d4731de55b909c581062
LocalVector<String> parameters(isolate);
// Detects parameters of the scripts based on module ids.
// internal/bootstrap/realm: process, getLinkedBinding,
@@ -451,7 +451,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(Local<Context> context,
@@ -450,7 +450,7 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(Local<Context> context,
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
const char* id,
Realm* realm) {
@@ -406,7 +418,7 @@ index 4b288e0f89e0156cb5b0555c0259b2c1150770db..bc87057c8473d4731de55b909c581062
// Detects parameters of the scripts based on module ids.
// internal/bootstrap/realm: process, getLinkedBinding,
// getInternalBinding, primordials
@@ -507,7 +507,7 @@ MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
@@ -506,7 +506,7 @@ MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
if (!maybe_fn.ToLocal(&fn)) {
return MaybeLocal<Value>();
}
@@ -415,12 +427,12 @@ index 4b288e0f89e0156cb5b0555c0259b2c1150770db..bc87057c8473d4731de55b909c581062
return fn->Call(context, undefined, argc, argv);
}
@@ -546,14 +546,14 @@ bool BuiltinLoader::CompileAllBuiltinsAndCopyCodeCache(
@@ -544,14 +544,14 @@ bool BuiltinLoader::CompileAllBuiltinsAndCopyCodeCache(
to_eager_compile_.emplace(id);
}
- v8::TryCatch bootstrapCatch(context->GetIsolate());
+ v8::TryCatch bootstrapCatch(Isolate::GetCurrent());
- TryCatch bootstrapCatch(context->GetIsolate());
+ TryCatch bootstrapCatch(Isolate::GetCurrent());
auto fn = LookupAndCompile(context, id.data(), nullptr);
if (bootstrapCatch.HasCaught()) {
per_process::Debug(DebugCategory::CODE_CACHE,
@@ -433,10 +445,10 @@ index 4b288e0f89e0156cb5b0555c0259b2c1150770db..bc87057c8473d4731de55b909c581062
// This is used by the snapshot builder, so save the code cache
// unconditionally.
diff --git a/src/node_constants.cc b/src/node_constants.cc
index cbcecfba33070b820aca0e2814982160a97a6378..b1ee513fc0873a51b4885f612dbf7b950b5cf2ca 100644
index fea0426496978c0003fe1481afcf93fc9c23edca..c9588880d05435ab9f4e23fcff74c93309664270 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -1264,7 +1264,7 @@ void CreatePerContextProperties(Local<Object> target,
@@ -1265,7 +1265,7 @@ void CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
@@ -444,12 +456,12 @@ index cbcecfba33070b820aca0e2814982160a97a6378..b1ee513fc0873a51b4885f612dbf7b95
+ Isolate* isolate = Isolate::GetCurrent();
Environment* env = Environment::GetCurrent(context);
CHECK(target->SetPrototype(env->context(), Null(env->isolate())).FromJust());
CHECK(
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index 21a08a738e5c3506d27e402762a4a267e9278588..475b5628f9b82a2b9b86343f25759c1e6814f816 100644
index 3c234205e89be7e976dae5c3fcc73ca67953e034..e66d4fcb0c064f96cdb819c783027d864fe88d12 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -111,7 +111,7 @@ namespace {
@@ -113,7 +113,7 @@ namespace {
// Convert an int to a V8 Name (String or Symbol).
MaybeLocal<String> Uint32ToName(Local<Context> context, uint32_t index) {
@@ -458,7 +470,7 @@ index 21a08a738e5c3506d27e402762a4a267e9278588..475b5628f9b82a2b9b86343f25759c1e
}
} // anonymous namespace
@@ -682,7 +682,7 @@ Intercepted ContextifyContext::PropertyDefinerCallback(
@@ -677,7 +677,7 @@ Intercepted ContextifyContext::PropertyDefinerCallback(
}
Local<Context> context = ctx->context();
@@ -467,7 +479,7 @@ index 21a08a738e5c3506d27e402762a4a267e9278588..475b5628f9b82a2b9b86343f25759c1e
PropertyAttribute attributes = PropertyAttribute::None;
bool is_declared =
@@ -1657,7 +1657,7 @@ static MaybeLocal<Function> CompileFunctionForCJSLoader(
@@ -1666,7 +1666,7 @@ static MaybeLocal<Function> CompileFunctionForCJSLoader(
bool* cache_rejected,
bool is_cjs_scope,
ScriptCompiler::CachedData* cached_data) {
@@ -477,10 +489,10 @@ index 21a08a738e5c3506d27e402762a4a267e9278588..475b5628f9b82a2b9b86343f25759c1e
Local<Symbol> symbol = env->vm_dynamic_import_default_internal();
diff --git a/src/node_env_var.cc b/src/node_env_var.cc
index 492d5f455f45a5c8a957ecdabed38709a633f640..48f9917113555c7ed87e37750c45d152fa4b68f8 100644
index 6aad252eb5681bb9ab9890812602b43c418e7a7f..5f7ef8cc58f589ba30a44abaaaaaf1514458c3f0 100644
--- a/src/node_env_var.cc
+++ b/src/node_env_var.cc
@@ -295,7 +295,7 @@ std::shared_ptr<KVStore> KVStore::CreateMapKVStore() {
@@ -311,7 +311,7 @@ std::shared_ptr<KVStore> KVStore::CreateMapKVStore() {
Maybe<void> KVStore::AssignFromObject(Local<Context> context,
Local<Object> entries) {
@@ -490,7 +502,7 @@ index 492d5f455f45a5c8a957ecdabed38709a633f640..48f9917113555c7ed87e37750c45d152
Local<Array> keys;
if (!entries->GetOwnPropertyNames(context).ToLocal(&keys))
diff --git a/src/node_errors.cc b/src/node_errors.cc
index befb642f1effa3c4139e4cd99ff64d9c5175fd72..9c068afd1c4c3fadeee4ba035e67ec4ae72c7f73 100644
index 4386a1bc5678e351ce084cd2c47202561619b164..8d51201ad24999ed8f54e16c7878432d41841cf2 100644
--- a/src/node_errors.cc
+++ b/src/node_errors.cc
@@ -633,7 +633,7 @@ v8::ModifyCodeGenerationFromStringsResult ModifyCodeGenerationFromStrings(
@@ -511,9 +523,9 @@ index befb642f1effa3c4139e4cd99ff64d9c5175fd72..9c068afd1c4c3fadeee4ba035e67ec4a
switch (message->ErrorLevel()) {
case Isolate::MessageErrorLevel::kMessageWarning: {
Environment* env = Environment::GetCurrent(isolate);
@@ -1118,7 +1118,7 @@ void Initialize(Local<Object> target,
@@ -1161,7 +1161,7 @@ void Initialize(Local<Object> target,
SetMethod(
context, target, "triggerUncaughtException", TriggerUncaughtException);
context, target, "getErrorSourcePositions", GetErrorSourcePositions);
- Isolate* isolate = context->GetIsolate();
+ Isolate* isolate = Isolate::GetCurrent();
@@ -521,10 +533,10 @@ index befb642f1effa3c4139e4cd99ff64d9c5175fd72..9c068afd1c4c3fadeee4ba035e67ec4a
READONLY_PROPERTY(target, "exitCodes", exit_codes);
diff --git a/src/node_file.cc b/src/node_file.cc
index d7009937b31729f33d9c45cbda7f5440fbdac2aa..e57a3140cd90d7e7852a0c6892091e50b850ae64 100644
index d73dac2ee3f1cf1cac6845fae0f702c9fba8fcef..969e7d08086f8442bed476feaf15599b8c79db7c 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -3753,7 +3753,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -3874,7 +3874,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -534,10 +546,10 @@ index d7009937b31729f33d9c45cbda7f5440fbdac2aa..e57a3140cd90d7e7852a0c6892091e50
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
BindingData* binding =
diff --git a/src/node_messaging.cc b/src/node_messaging.cc
index 1eff9399ff87510164390a1dfea84158a8856b86..e912562d768308906286890b7015cf2c462bac49 100644
index 57e068ae249d618c2658638f9f3b03e1fedb6524..8c51ae4e0a435971c6d0288af87810877dd31a49 100644
--- a/src/node_messaging.cc
+++ b/src/node_messaging.cc
@@ -253,7 +253,7 @@ namespace {
@@ -254,7 +254,7 @@ namespace {
MaybeLocal<Function> GetEmitMessageFunction(Local<Context> context,
IsolateData* isolate_data) {
@@ -546,7 +558,7 @@ index 1eff9399ff87510164390a1dfea84158a8856b86..e912562d768308906286890b7015cf2c
Local<Object> per_context_bindings;
Local<Value> emit_message_val;
if (!GetPerContextExports(context, isolate_data)
@@ -268,7 +268,7 @@ MaybeLocal<Function> GetEmitMessageFunction(Local<Context> context,
@@ -269,7 +269,7 @@ MaybeLocal<Function> GetEmitMessageFunction(Local<Context> context,
}
MaybeLocal<Function> GetDOMException(Local<Context> context) {
@@ -555,7 +567,7 @@ index 1eff9399ff87510164390a1dfea84158a8856b86..e912562d768308906286890b7015cf2c
Local<Object> per_context_bindings;
Local<Value> domexception_ctor_val;
if (!GetPerContextExports(context).ToLocal(&per_context_bindings) ||
@@ -283,7 +283,7 @@ MaybeLocal<Function> GetDOMException(Local<Context> context) {
@@ -284,7 +284,7 @@ MaybeLocal<Function> GetDOMException(Local<Context> context) {
}
void ThrowDataCloneException(Local<Context> context, Local<String> message) {
@@ -564,7 +576,7 @@ index 1eff9399ff87510164390a1dfea84158a8856b86..e912562d768308906286890b7015cf2c
Local<Value> argv[] = {message,
FIXED_ONE_BYTE_STRING(isolate, "DataCloneError")};
Local<Value> exception;
@@ -1464,7 +1464,7 @@ BaseObjectPtr<BaseObject> JSTransferable::Data::Deserialize(
@@ -1477,7 +1477,7 @@ BaseObjectPtr<BaseObject> JSTransferable::Data::Deserialize(
Maybe<bool> JSTransferable::Data::FinalizeTransferWrite(
Local<Context> context, ValueSerializer* serializer) {
@@ -574,10 +586,10 @@ index 1eff9399ff87510164390a1dfea84158a8856b86..e912562d768308906286890b7015cf2c
data_.Reset();
return ret;
diff --git a/src/node_modules.cc b/src/node_modules.cc
index 6204986dc97686a248d6ae483f3a413ee5c51e47..c0108310df81c9bd1756a6fb92466a7f84e53f7c 100644
index bdbc511ef3f680bbac6770b89f47acaee95d56a2..d8477191efafba3c41c06d765f4b03bd00b8573c 100644
--- a/src/node_modules.cc
+++ b/src/node_modules.cc
@@ -64,7 +64,7 @@ void BindingData::Deserialize(v8::Local<v8::Context> context,
@@ -69,7 +69,7 @@ void BindingData::Deserialize(v8::Local<v8::Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -586,7 +598,7 @@ index 6204986dc97686a248d6ae483f3a413ee5c51e47..c0108310df81c9bd1756a6fb92466a7f
Realm* realm = Realm::GetCurrent(context);
BindingData* binding = realm->AddBindingData<BindingData>(holder);
CHECK_NOT_NULL(binding);
@@ -706,7 +706,7 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
@@ -735,7 +735,7 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(target);
@@ -596,10 +608,10 @@ index 6204986dc97686a248d6ae483f3a413ee5c51e47..c0108310df81c9bd1756a6fb92466a7f
#define V(status) \
diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc
index 1cb08b715865f8337e0292fc8e2a26488ba21694..2bd20fc173d4110282ee736e49b49ce0859088f3 100644
index e453bacc3e5247493a3582c24174bfe6e590825d..fe4aad63bc877be105830a80aa6be10ce3f8fda4 100644
--- a/src/node_process_methods.cc
+++ b/src/node_process_methods.cc
@@ -736,7 +736,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -737,7 +737,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -609,10 +621,10 @@ index 1cb08b715865f8337e0292fc8e2a26488ba21694..2bd20fc173d4110282ee736e49b49ce0
// Recreate the buffer in the constructor.
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
diff --git a/src/node_realm.cc b/src/node_realm.cc
index cd2b4c0107594a8ba9bf671669e4c82326719908..d18945085ff1860bbe3796e0b47904210aafd941 100644
index 2a5fe9fe501d1fd9356eeb7d044a872fa5a55f38..39f6f142044c42904d234da20a266315346c135a 100644
--- a/src/node_realm.cc
+++ b/src/node_realm.cc
@@ -19,7 +19,7 @@ using v8::String;
@@ -22,7 +22,7 @@ using v8::String;
using v8::Value;
Realm::Realm(Environment* env, v8::Local<v8::Context> context, Kind kind)
@@ -620,12 +632,12 @@ index cd2b4c0107594a8ba9bf671669e4c82326719908..d18945085ff1860bbe3796e0b4790421
+ : env_(env), isolate_(v8::Isolate::GetCurrent()), kind_(kind) {
context_.Reset(isolate_, context);
env->AssignToContext(context, this, ContextInfo(""));
}
// The environment can also purge empty wrappers in the check callback,
diff --git a/src/node_report.cc b/src/node_report.cc
index df73a8204bc0917073a70ca68d019ceab3159b08..d7bb94db78b3a729f25ceaf66d193032056b36ff 100644
index c82c6bcc083ba60137e83b3c291130636db3162f..0d06f61d7fb2472a3d7a66854040dc493406b79e 100644
--- a/src/node_report.cc
+++ b/src/node_report.cc
@@ -399,7 +399,7 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
@@ -400,7 +400,7 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
if (!error.IsEmpty() && error->IsObject()) {
TryCatch try_catch(isolate);
Local<Object> error_obj = error.As<Object>();
@@ -635,10 +647,10 @@ index df73a8204bc0917073a70ca68d019ceab3159b08..d7bb94db78b3a729f25ceaf66d193032
if (!error_obj->GetOwnPropertyNames(context).ToLocal(&keys)) {
return writer->json_objectend(); // the end of 'errorProperties'
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
index 69d8d15d8989ed31a19489e68588e730760c8ffb..d342a5ff91bbd9cb73c02c26ae3a36b9d0dc7b47 100644
index c2e24b4645e7903e08c80aead1c18c7bcff1bd89..e34d24d51d5c090b560d06f727043f20924e6f46 100644
--- a/src/node_snapshotable.cc
+++ b/src/node_snapshotable.cc
@@ -1613,7 +1613,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -1614,7 +1614,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -648,10 +660,10 @@ index 69d8d15d8989ed31a19489e68588e730760c8ffb..d342a5ff91bbd9cb73c02c26ae3a36b9
// Recreate the buffer in the constructor.
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
index 8b6fe36e1fece112269ebf193d6322a4d1dacc0a..96101167016573e80fff520256ebb78c71d83302 100644
index 7bb4d4108c8326d69da5236c7ea7f00ddb68cea9..cf9ce6686cffca7e700a0e20cb9f776a5f0f7c4a 100644
--- a/src/node_sqlite.cc
+++ b/src/node_sqlite.cc
@@ -1858,7 +1858,7 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
@@ -2020,7 +2020,7 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
if (args[0]->IsObject() && !args[0]->IsArrayBufferView()) {
Local<Object> obj = args[0].As<Object>();
@@ -661,7 +673,7 @@ index 8b6fe36e1fece112269ebf193d6322a4d1dacc0a..96101167016573e80fff520256ebb78c
if (!obj->GetOwnPropertyNames(context).ToLocal(&keys)) {
return false;
diff --git a/src/node_task_queue.cc b/src/node_task_queue.cc
index c4257110d8b52017fccd8e1e746b557a0b7084df..6f00da0b515397d300e387f03f4a2bf71155cfe0 100644
index d33ee3c26c111e53edf27e6368ca8f64ff30a349..f1c53c44f201b295888e7932c5e3e2b19cb9c319 100644
--- a/src/node_task_queue.cc
+++ b/src/node_task_queue.cc
@@ -48,7 +48,7 @@ void PromiseRejectCallback(PromiseRejectMessage message) {
@@ -674,10 +686,10 @@ index c4257110d8b52017fccd8e1e746b557a0b7084df..6f00da0b515397d300e387f03f4a2bf7
Environment* env = Environment::GetCurrent(isolate);
diff --git a/src/node_url.cc b/src/node_url.cc
index 09589e85e8bc131811204833d9a76f98c7b2a102..1154b452151b6b597aed67effbb3796c635d236b 100644
index 9d1e8ec05161570db11f7b662395509774668d78..9b91f83d879ea02fd3d61913c8dfd35b3bf1ac31 100644
--- a/src/node_url.cc
+++ b/src/node_url.cc
@@ -69,7 +69,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -70,7 +70,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -687,10 +699,10 @@ index 09589e85e8bc131811204833d9a76f98c7b2a102..1154b452151b6b597aed67effbb3796c
BindingData* binding = realm->AddBindingData<BindingData>(holder);
CHECK_NOT_NULL(binding);
diff --git a/src/node_v8.cc b/src/node_v8.cc
index 430d5dd4f808af7b1790bd62f06d47b86100d4e9..08a741216d88c95d580e9281e174550001ff2b21 100644
index 98e392f6d7118bee8a3d0bce4de1ded76a293001..152b030198c6b36efd2be6c06f5c6e8bbc7cfadb 100644
--- a/src/node_v8.cc
+++ b/src/node_v8.cc
@@ -157,7 +157,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -158,7 +158,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -700,10 +712,10 @@ index 430d5dd4f808af7b1790bd62f06d47b86100d4e9..08a741216d88c95d580e9281e1745500
// Recreate the buffer in the constructor.
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
diff --git a/src/node_wasi.cc b/src/node_wasi.cc
index 3f91b651b83a20e70d5b368e012f5ee4b9d16092..40c601acd752b559f7ffbc00c15728fbb5275ac5 100644
index 370221d3cddc201180260ecb3a222bc831c91093..f5aff2f65fe6b9f48cf970ab3e7c57cfe4885f85 100644
--- a/src/node_wasi.cc
+++ b/src/node_wasi.cc
@@ -49,7 +49,7 @@ using v8::WasmMemoryObject;
@@ -50,7 +50,7 @@ using v8::WasmMemoryObject;
static MaybeLocal<Value> WASIException(Local<Context> context,
int errorno,
const char* syscall) {
@@ -712,20 +724,22 @@ index 3f91b651b83a20e70d5b368e012f5ee4b9d16092..40c601acd752b559f7ffbc00c15728fb
Environment* env = Environment::GetCurrent(context);
CHECK_NOT_NULL(env);
const char* err_name = uvwasi_embedder_err_code_to_string(errorno);
@@ -275,7 +275,7 @@ R WASI::WasiFunction<FT, F, R, Args...>::FastCallback(
@@ -275,8 +275,8 @@ R WASI::WasiFunction<FT, F, R, Args...>::FastCallback(
return EinvalError<R>();
}
- v8::Isolate* isolate = receiver->GetIsolate();
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
- Isolate* isolate = receiver->GetIsolate();
- HandleScope scope(isolate);
+ Isolate* isolate = Isolate::GetCurrent();
+ HandleScope handle_scope(isolate);
if (wasi->memory_.IsEmpty()) {
THROW_ERR_WASI_NOT_STARTED(isolate);
return EinvalError<R>();
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
index 74ece724e207a69e2457598a199c12f1cebcfd4a..1705e430099c5a363e02010f83d729b0aa54f8e5 100644
index cc90af827a3fbd14fb4cbfbfd39cc661f22cf6e1..5819d9bca845e0eed6d4d93564469d8f3c36200b 100644
--- a/src/node_webstorage.cc
+++ b/src/node_webstorage.cc
@@ -58,7 +58,7 @@ using v8::Value;
@@ -57,7 +57,7 @@ using v8::Value;
} while (0)
static void ThrowQuotaExceededException(Local<Context> context) {
@@ -734,7 +748,7 @@ index 74ece724e207a69e2457598a199c12f1cebcfd4a..1705e430099c5a363e02010f83d729b0
auto dom_exception_str = FIXED_ONE_BYTE_STRING(isolate, "DOMException");
auto err_name = FIXED_ONE_BYTE_STRING(isolate, "QuotaExceededError");
auto err_message =
@@ -434,7 +434,7 @@ Maybe<void> Storage::Store(Local<Name> key, Local<Value> value) {
@@ -433,7 +433,7 @@ Maybe<void> Storage::Store(Local<Name> key, Local<Value> value) {
}
static MaybeLocal<String> Uint32ToName(Local<Context> context, uint32_t index) {
@@ -744,10 +758,10 @@ index 74ece724e207a69e2457598a199c12f1cebcfd4a..1705e430099c5a363e02010f83d729b0
static void Clear(const FunctionCallbackInfo<Value>& info) {
diff --git a/src/node_worker.cc b/src/node_worker.cc
index 8555ab556b5b74a1cf9cf30747f1f417bfe4e4d9..1a2532337504444d59098304b87e0d65f16e838c 100644
index 62c53368d1173edb7eb42e3337049c46fd7cdda9..7d08d8af7f6d99f7bd41cb7eb91063c630b3f87b 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -1289,8 +1289,6 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
@@ -1466,8 +1466,6 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
Local<Object> port = env->message_port();
CHECK_IMPLIES(!env->is_main_thread(), !port.IsEmpty());
if (!port.IsEmpty()) {
@@ -757,10 +771,10 @@ index 8555ab556b5b74a1cf9cf30747f1f417bfe4e4d9..1a2532337504444d59098304b87e0d65
}
}
diff --git a/src/timers.cc b/src/timers.cc
index bf90e68479da141265f748775acacab513b8d437..5f0d07b4ac1d9b8df6c8bb059e5d07ac1a882b36 100644
index da4206187f7c7d2becb8a101c1ff5346a10e13f4..03f0910926f3d403121e227cee32a546b2394e04 100644
--- a/src/timers.cc
+++ b/src/timers.cc
@@ -117,7 +117,7 @@ void BindingData::Deserialize(Local<Context> context,
@@ -114,7 +114,7 @@ void BindingData::Deserialize(Local<Context> context,
int index,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -770,10 +784,10 @@ index bf90e68479da141265f748775acacab513b8d437..5f0d07b4ac1d9b8df6c8bb059e5d07ac
// Recreate the buffer in the constructor.
BindingData* binding = realm->AddBindingData<BindingData>(holder);
diff --git a/src/util-inl.h b/src/util-inl.h
index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330cb47c1a7 100644
index 9d4db311024c5f526fc3c00764fff686af044026..da9268dcf2ff432ddeec7c0f61a147b73f3130e2 100644
--- a/src/util-inl.h
+++ b/src/util-inl.h
@@ -326,14 +326,14 @@ v8::Maybe<void> FromV8Array(v8::Local<v8::Context> context,
@@ -336,14 +336,14 @@ v8::Maybe<void> FromV8Array(v8::Local<v8::Context> context,
std::vector<v8::Global<v8::Value>>* out) {
uint32_t count = js_array->Length();
out->reserve(count);
@@ -790,7 +804,7 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
if (str.size() >= static_cast<size_t>(v8::String::kMaxLength)) [[unlikely]] {
// V8 only has a TODO comment about adding an exception when the maximum
// string size is exceeded.
@@ -349,7 +349,7 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
@@ -359,7 +359,7 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
v8_inspector::StringView str,
v8::Isolate* isolate) {
@@ -799,7 +813,7 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
if (str.length() >= static_cast<size_t>(v8::String::kMaxLength))
[[unlikely]] {
// V8 only has a TODO comment about adding an exception when the maximum
@@ -376,7 +376,7 @@ template <typename T>
@@ -386,7 +386,7 @@ template <typename T>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::vector<T>& vec,
v8::Isolate* isolate) {
@@ -808,7 +822,7 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
v8::EscapableHandleScope handle_scope(isolate);
MaybeStackBuffer<v8::Local<v8::Value>, 128> arr(vec.size());
@@ -393,7 +393,7 @@ template <typename T>
@@ -403,7 +403,7 @@ template <typename T>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::set<T>& set,
v8::Isolate* isolate) {
@@ -817,7 +831,16 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
v8::Local<v8::Set> set_js = v8::Set::New(isolate);
v8::HandleScope handle_scope(isolate);
@@ -412,7 +412,7 @@ template <typename T, typename U>
@@ -422,7 +422,7 @@ template <typename T, std::size_t U>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::ranges::elements_view<T, U>& vec,
v8::Isolate* isolate) {
- if (isolate == nullptr) isolate = context->GetIsolate();
+ if (isolate == nullptr) isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope handle_scope(isolate);
MaybeStackBuffer<v8::Local<v8::Value>, 128> arr(vec.size());
@@ -441,7 +441,7 @@ template <typename T, typename U>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::unordered_map<T, U>& map,
v8::Isolate* isolate) {
@@ -826,7 +849,7 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
v8::EscapableHandleScope handle_scope(isolate);
v8::Local<v8::Map> ret = v8::Map::New(isolate);
@@ -455,7 +455,7 @@ template <typename T, typename>
@@ -484,7 +484,7 @@ template <typename T, typename>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const T& number,
v8::Isolate* isolate) {
@@ -835,7 +858,7 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
return ConvertNumberToV8Value(isolate, number);
}
@@ -468,7 +468,7 @@ v8::Local<v8::Array> ToV8ValuePrimitiveArray(v8::Local<v8::Context> context,
@@ -497,7 +497,7 @@ v8::Local<v8::Array> ToV8ValuePrimitiveArray(v8::Local<v8::Context> context,
std::is_floating_point_v<T>,
"Only primitive types (bool, integral, floating-point) are supported.");
@@ -844,11 +867,20 @@ index b21f7a8260ca6a4701f8904b9cb641428db80772..16fe55f3054fd20544babd63ff204330
v8::EscapableHandleScope handle_scope(isolate);
v8::LocalVector<v8::Value> elements(isolate);
@@ -731,7 +731,7 @@ inline v8::MaybeLocal<v8::Object> NewDictionaryInstanceNullProto(
if (value.IsEmpty()) return v8::MaybeLocal<v8::Object>();
}
v8::Local<v8::Object> obj = tmpl->NewInstance(context, property_values);
- if (obj->SetPrototypeV2(context, v8::Null(context->GetIsolate()))
+ if (obj->SetPrototypeV2(context, v8::Null(v8::Isolate::GetCurrent()))
.IsNothing()) {
return v8::MaybeLocal<v8::Object>();
}
diff --git a/src/util.cc b/src/util.cc
index 5ca32f026f9f001ddadc14965705fe005600eddd..1b38f22b930b77d80aa53f9b12299d3cc469a46d 100644
index 660cfff6b8a0c583be843e555e7a06cd09e0d279..c4b39450c5b7f91c46f7027db367c30db34927bb 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -393,7 +393,7 @@ void SetMethod(Local<v8::Context> context,
@@ -391,7 +391,7 @@ void SetMethod(Local<v8::Context> context,
Local<v8::Object> that,
const std::string_view name,
v8::FunctionCallback callback) {
@@ -857,7 +889,7 @@ index 5ca32f026f9f001ddadc14965705fe005600eddd..1b38f22b930b77d80aa53f9b12299d3c
Local<v8::Function> function =
NewFunctionTemplate(isolate,
callback,
@@ -454,7 +454,7 @@ void SetFastMethod(Local<v8::Context> context,
@@ -452,7 +452,7 @@ void SetFastMethod(Local<v8::Context> context,
const std::string_view name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function) {
@@ -866,7 +898,7 @@ index 5ca32f026f9f001ddadc14965705fe005600eddd..1b38f22b930b77d80aa53f9b12299d3c
Local<v8::Function> function =
NewFunctionTemplate(isolate,
slow_callback,
@@ -476,7 +476,7 @@ void SetFastMethodNoSideEffect(Local<v8::Context> context,
@@ -474,7 +474,7 @@ void SetFastMethodNoSideEffect(Local<v8::Context> context,
const std::string_view name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function) {
@@ -875,7 +907,7 @@ index 5ca32f026f9f001ddadc14965705fe005600eddd..1b38f22b930b77d80aa53f9b12299d3c
Local<v8::Function> function =
NewFunctionTemplate(isolate,
slow_callback,
@@ -564,7 +564,7 @@ void SetMethodNoSideEffect(Local<v8::Context> context,
@@ -562,7 +562,7 @@ void SetMethodNoSideEffect(Local<v8::Context> context,
Local<v8::Object> that,
const std::string_view name,
v8::FunctionCallback callback) {
@@ -884,7 +916,7 @@ index 5ca32f026f9f001ddadc14965705fe005600eddd..1b38f22b930b77d80aa53f9b12299d3c
Local<v8::Function> function =
NewFunctionTemplate(isolate,
callback,
@@ -665,7 +665,7 @@ void SetConstructorFunction(Local<v8::Context> context,
@@ -689,7 +689,7 @@ void SetConstructorFunction(Local<v8::Context> context,
const char* name,
Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
@@ -894,10 +926,10 @@ index 5ca32f026f9f001ddadc14965705fe005600eddd..1b38f22b930b77d80aa53f9b12299d3c
context, that, OneByteString(isolate, name), tmpl, flag);
}
diff --git a/src/util.h b/src/util.h
index 7c98de621ca4d53cbaaa5bd4488aab20c7b033a7..329d2397c87ac37d157e3325e2ab62907d7286b4 100644
index 2b351235cf7f32c9fad25367cc912d187466f1e0..6da57f95165bbdedb65dab6eaae8c39b815ee4e5 100644
--- a/src/util.h
+++ b/src/util.h
@@ -756,7 +756,7 @@ inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
@@ -739,7 +739,7 @@ inline v8::MaybeLocal<v8::Value> ToV8Value(
// Variation on NODE_DEFINE_CONSTANT that sets a String value.
#define NODE_DEFINE_STRING_CONSTANT(target, name, constant) \
do { \

View File

@@ -11,10 +11,10 @@ really in 20/21. We have to wait until 22 is released to be able to
build with upstream GN files.
diff --git a/configure.py b/configure.py
index 91283ca577f580dbf1e0c4e2dbf851a9ceaa38ed..e8eaff30ec947677db2d45425f9180759d0c55de 100755
index 7f73f084ef1a8336089e6a16423c2eb310c0b9f2..96eedd5d9ae05ee6704724290973251059d5dd78 100755
--- a/configure.py
+++ b/configure.py
@@ -1728,7 +1728,7 @@ def configure_v8(o, configs):
@@ -1730,7 +1730,7 @@ def configure_v8(o, configs):
# Until we manage to get rid of all those, v8_enable_sandbox cannot be used.
# Note that enabling pointer compression without enabling sandbox is unsupported by V8,
# so this can be broken at any time.
@@ -68,10 +68,10 @@ index d4438f7fd61598afac2c1e3184721a759d22b10c..e2407027ab05e59b2f0f1c213b98ea46
assert(!node_enable_inspector || node_use_openssl,
diff --git a/src/node_builtins.cc b/src/node_builtins.cc
index b83aa87c969fb4e71cb202816713af869bb76283..c54df6fee333ddfe59b9df7e0ddd2935b4dcb33f 100644
index 581b9886ded52f294b7cc6b080b2269b7617c85e..e43e2559aaf48add88aad342b1c96fd34f26c87f 100644
--- a/src/node_builtins.cc
+++ b/src/node_builtins.cc
@@ -789,6 +789,7 @@ void BuiltinLoader::RegisterExternalReferences(
@@ -774,6 +774,7 @@ void BuiltinLoader::RegisterExternalReferences(
registry->Register(GetNatives);
RegisterExternalReferencesForInternalizedBuiltinCode(registry);
@@ -80,10 +80,10 @@ index b83aa87c969fb4e71cb202816713af869bb76283..c54df6fee333ddfe59b9df7e0ddd2935
} // namespace builtins
diff --git a/src/node_builtins.h b/src/node_builtins.h
index f9426599f2d5dc6ad061407f0c4eb2c9203a4433..302030f610965f07dd6998d282275c1bdf738009 100644
index 7a7b84337feb67960819472e43192dbdc151e299..bcdd50f635757f41287c87df1db9cd3b55c4b6b9 100644
--- a/src/node_builtins.h
+++ b/src/node_builtins.h
@@ -74,6 +74,8 @@ using BuiltinCodeCacheMap =
@@ -75,6 +75,8 @@ using BuiltinCodeCacheMap =
// Generated by tools/js2c.cc as node_javascript.cc
void RegisterExternalReferencesForInternalizedBuiltinCode(
ExternalReferenceRegistry* registry);
@@ -92,26 +92,6 @@ index f9426599f2d5dc6ad061407f0c4eb2c9203a4433..302030f610965f07dd6998d282275c1b
// Handles compilation and caching of built-in JavaScript modules and
// bootstrap scripts, whose source are bundled into the binary as static data.
diff --git a/tools/install.py b/tools/install.py
index 8797b59e59c85a8877b977fa3281e50165e6f6b2..0af01e075616195f38fb242626dcab770ec1eb57 100755
--- a/tools/install.py
+++ b/tools/install.py
@@ -222,6 +222,7 @@ def headers(options, action):
'include/cppgc/internal/caged-heap-local-data.h',
'include/cppgc/internal/caged-heap.h',
'include/cppgc/internal/compiler-specific.h',
+ 'include/cppgc/internal/conditional-stack-allocated.h',
'include/cppgc/internal/finalizer-trait.h',
'include/cppgc/internal/gc-info.h',
'include/cppgc/internal/logging.h',
@@ -301,6 +302,7 @@ def headers(options, action):
'include/v8-promise.h',
'include/v8-proxy.h',
'include/v8-regexp.h',
+ 'include/v8-sandbox.h',
'include/v8-script.h',
'include/v8-snapshot.h',
'include/v8-source-location.h',
diff --git a/tools/js2c.cc b/tools/js2c.cc
old mode 100644
new mode 100755
@@ -271,7 +251,7 @@ index 856878c33681a73d41016729dabe48b0a6a80589..91a11852d206b65485fe90fd037a0bd1
if sys.platform == 'win32':
files = [ x.replace('\\', '/') for x in files ]
diff --git a/unofficial.gni b/unofficial.gni
index 865a0d5ce9c6792e57f4216bcaa594ca6fc7b1c8..26ebc811272ef2990f8d090c54e7f5294aab9d37 100644
index c742b62c484e9dd205eff63dcffad78c76828375..20d2483bb16e297ab5b12aab6f56948d6d25cb03 100644
--- a/unofficial.gni
+++ b/unofficial.gni
@@ -147,31 +147,41 @@ template("node_gn_build") {
@@ -339,7 +319,7 @@ index 865a0d5ce9c6792e57f4216bcaa594ca6fc7b1c8..26ebc811272ef2990f8d090c54e7f529
executable(target_name) {
forward_variables_from(invoker, "*")
@@ -297,6 +311,7 @@ template("node_gn_build") {
@@ -314,6 +328,7 @@ template("node_gn_build") {
}
executable("node_js2c") {
@@ -347,7 +327,7 @@ index 865a0d5ce9c6792e57f4216bcaa594ca6fc7b1c8..26ebc811272ef2990f8d090c54e7f529
deps = [
"deps/uv",
"$node_simdutf_path",
@@ -307,26 +322,75 @@ template("node_gn_build") {
@@ -324,26 +339,75 @@ template("node_gn_build") {
"src/embedded_data.cc",
"src/embedded_data.h",
]
@@ -433,7 +413,7 @@ index 865a0d5ce9c6792e57f4216bcaa594ca6fc7b1c8..26ebc811272ef2990f8d090c54e7f529
outputs = [ "$target_gen_dir/node_javascript.cc" ]
# Get the path to node_js2c executable of the host toolchain.
@@ -340,11 +404,11 @@ template("node_gn_build") {
@@ -357,11 +421,11 @@ template("node_gn_build") {
get_label_info(":node_js2c($host_toolchain)", "name") +
host_executable_suffix

View File

@@ -14,7 +14,7 @@ We don't need to do this for zlib, as the existing gn workflow uses the same
Upstreamed at https://github.com/nodejs/node/pull/55903
diff --git a/unofficial.gni b/unofficial.gni
index 26ebc811272ef2990f8d090c54e7f5294aab9d37..8886f2a79ae77614789d6ae0defd4f18fc756456 100644
index 20d2483bb16e297ab5b12aab6f56948d6d25cb03..253226009faf563f6db285d4b2908f308c1f96ea 100644
--- a/unofficial.gni
+++ b/unofficial.gni
@@ -160,7 +160,6 @@ template("node_gn_build") {

View File

@@ -14,7 +14,7 @@ error: duplicate symbol: crdtp::ProtocolTypeTraits<std::__Cr::basic_string<char,
Some distinguishing change should be upstreamed to Node.js.
diff --git a/src/inspector/node_string.cc b/src/inspector/node_string.cc
index 8521730bd03cdfce47e9b5d0f5d68a568bc3de8c..28f4598aa7ea0e93350f79566c06d0f08313be9f 100644
index e2148e954217b9b999e9713e95f1a115ccf7d657..7ec7464cdc0ef00e6600fb897ae99e44ed0f4ad8 100644
--- a/src/inspector/node_string.cc
+++ b/src/inspector/node_string.cc
@@ -7,7 +7,8 @@

View File

@@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 4 Sep 2024 16:39:23 +0200
Subject: build: compile with C++20 support
Refs https://github.com/nodejs/node/pull/45427
V8 requires C++20 support as of https://chromium-review.googlesource.com/c/v8/v8/+/5587859.
This can be removed when Electron upgrades to a version of Node.js containing the required V8 version.
diff --git a/common.gypi b/common.gypi
index c28d6f5fe2c922f0b1e3f7e56289c78e7b91c294..95c56305926fc3e0e46e4cf99ec86d3d1b5576a7 100644
--- a/common.gypi
+++ b/common.gypi
@@ -539,7 +539,7 @@
'-fno-rtti',
'-fno-exceptions',
'-fno-strict-aliasing',
- '-std=gnu++17',
+ '-std=gnu++20',
],
'defines': [ '__STDC_FORMAT_MACROS' ],
'ldflags': [ '-rdynamic' ],
@@ -719,7 +719,7 @@
['clang==1', {
'xcode_settings': {
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
- 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++17', # -std=gnu++17
+ 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++20', # -std=gnu++20
'CLANG_CXX_LIBRARY': 'libc++',
},
}],

View File

@@ -33,10 +33,10 @@ index 8d7204f6cb48f783adc4d1c1eb2de0c83b7fffe2..a154559a56bf383d3c26af523c9bb07b
// Non-alphabetic chars.
diff --git a/lib/internal/http.js b/lib/internal/http.js
index 251f51ec454f9cba4023b8b6729241ee753aac13..1de8cac6e3953ce9cab9db03530da327199acfd5 100644
index 9bf929f7f3360f13058d3f446c18a36cd15bea58..abf9a06d891488288bccd98c437746c1ce48bf83 100644
--- a/lib/internal/http.js
+++ b/lib/internal/http.js
@@ -8,8 +8,8 @@ const {
@@ -11,8 +11,8 @@ const {
const { setUnrefTimeout } = require('internal/timers');
const { getCategoryEnabledBuffer, trace } = internalBinding('trace_events');
const {
@@ -46,8 +46,8 @@ index 251f51ec454f9cba4023b8b6729241ee753aac13..1de8cac6e3953ce9cab9db03530da327
+ CHAR_UPPERCASE_E,
} = require('internal/constants');
let utcCache;
@@ -44,11 +44,13 @@ function isTraceHTTPEnabled() {
const { URL } = require('internal/url');
@@ -51,11 +51,13 @@ function isTraceHTTPEnabled() {
const traceEventCategory = 'node,node.http';
function traceBegin(...args) {
@@ -62,12 +62,12 @@ index 251f51ec454f9cba4023b8b6729241ee753aac13..1de8cac6e3953ce9cab9db03530da327
+ trace(CHAR_UPPERCASE_E, traceEventCategory, ...args);
}
module.exports = {
function ipToInt(ip) {
diff --git a/node.gyp b/node.gyp
index 0e0071b508f605bb9b7722f8304814dc176d907e..bcb9f371c4e4d8c665058115dc39eaa65125d679 100644
index 420d57135f48df59b2cbd33497ef90b6148017e6..eefb1e0577b881da7a1570fd7ac465fe8b06747c 100644
--- a/node.gyp
+++ b/node.gyp
@@ -174,7 +174,6 @@
@@ -176,7 +176,6 @@
'src/timers.cc',
'src/timer_wrap.cc',
'src/tracing/agent.cc',
@@ -75,7 +75,7 @@ index 0e0071b508f605bb9b7722f8304814dc176d907e..bcb9f371c4e4d8c665058115dc39eaa6
'src/tracing/node_trace_writer.cc',
'src/tracing/trace_event.cc',
'src/tracing/traced_value.cc',
@@ -302,7 +301,6 @@
@@ -308,7 +307,6 @@
'src/tcp_wrap.h',
'src/timers.h',
'src/tracing/agent.h',

View File

@@ -7,7 +7,7 @@ Subject: build: ensure native module compilation fails if not using a new
This should not be upstreamed, it is a quality-of-life patch for downstream module builders.
diff --git a/common.gypi b/common.gypi
index 6b79de07be3f839af5b0644f19bfef9c33de590e..c28d6f5fe2c922f0b1e3f7e56289c78e7b91c294 100644
index 29a912f58e7b522ae21fddac510946cbcbaaa4cc..aea3a882c338eb757bef9e85fabab3fc7e7495f7 100644
--- a/common.gypi
+++ b/common.gypi
@@ -89,6 +89,8 @@
@@ -42,10 +42,10 @@ index 6b79de07be3f839af5b0644f19bfef9c33de590e..c28d6f5fe2c922f0b1e3f7e56289c78e
# list in v8/BUILD.gn.
['v8_enable_v8_checks == 1', {
diff --git a/configure.py b/configure.py
index e8eaff30ec947677db2d45425f9180759d0c55de..dc2d9d80059e845b33444f8bdc29e82d0fe0e26b 100755
index 96eedd5d9ae05ee6704724290973251059d5dd78..52060f9c6dc1bcec67a0fd4710e01e73a6cf276c 100755
--- a/configure.py
+++ b/configure.py
@@ -1710,6 +1710,7 @@ def configure_library(lib, output, pkgname=None):
@@ -1711,6 +1711,7 @@ def configure_library(lib, output, pkgname=None):
def configure_v8(o, configs):
set_configuration_variable(configs, 'v8_enable_v8_checks', release=1, debug=0)
@@ -54,7 +54,7 @@ index e8eaff30ec947677db2d45425f9180759d0c55de..dc2d9d80059e845b33444f8bdc29e82d
o['variables']['v8_enable_javascript_promise_hooks'] = 1
o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
diff --git a/src/node.h b/src/node.h
index a336f44dc1e785ea237865077216d41ab032c0af..96c599aa6448e2aa8e57e84f811564a5281c139a 100644
index c5ade4bd30456cde33379c6202b65709650d3ec0..f7b3f90b0c2cfbeacc5bc50112dd711df8d3c364 100644
--- a/src/node.h
+++ b/src/node.h
@@ -22,6 +22,12 @@

View File

@@ -10,7 +10,7 @@ JS errors and ensures embedder JS is loaded via LoadEmbedderJavaScriptSource.
That method is generated by our modifications to js2c.cc in the BUILD.gn patch
diff --git a/lib/internal/fs/watchers.js b/lib/internal/fs/watchers.js
index 0244a214b187e67e0cb89f26cd019855963ec93a..b65a3be6bcb0e28f7f43367d0fa9da533db9d0d1 100644
index 605dee28cace56f2366fec9d7f18894559044ae4..15dcabb3b1682438eb6d5a681363b7ea8602b9e7 100644
--- a/lib/internal/fs/watchers.js
+++ b/lib/internal/fs/watchers.js
@@ -299,12 +299,13 @@ function emitCloseNT(self) {
@@ -34,10 +34,10 @@ index 0244a214b187e67e0cb89f26cd019855963ec93a..b65a3be6bcb0e28f7f43367d0fa9da53
let kResistStopPropagation;
diff --git a/src/node_builtins.cc b/src/node_builtins.cc
index c54df6fee333ddfe59b9df7e0ddd2935b4dcb33f..4b288e0f89e0156cb5b0555c0259b2c1150770db 100644
index e43e2559aaf48add88aad342b1c96fd34f26c87f..e69eb280050cae0c0f394b2f956eef947e628904 100644
--- a/src/node_builtins.cc
+++ b/src/node_builtins.cc
@@ -35,6 +35,7 @@ using v8::Value;
@@ -39,6 +39,7 @@ using v8::Value;
BuiltinLoader::BuiltinLoader()
: config_(GetConfig()), code_cache_(std::make_shared<BuiltinCodeCache>()) {
LoadJavaScriptSource();
@@ -46,10 +46,10 @@ index c54df6fee333ddfe59b9df7e0ddd2935b4dcb33f..4b288e0f89e0156cb5b0555c0259b2c1
AddExternalizedBuiltin(
"internal/deps/cjs-module-lexer/lexer",
diff --git a/src/node_builtins.h b/src/node_builtins.h
index 302030f610965f07dd6998d282275c1bdf738009..35cb7766eeccc62dd2f0ce9484a2f1ec7beccc05 100644
index bcdd50f635757f41287c87df1db9cd3b55c4b6b9..e908f3c0e314b90ff7b6c599940ea8f4e657c709 100644
--- a/src/node_builtins.h
+++ b/src/node_builtins.h
@@ -138,6 +138,7 @@ class NODE_EXTERN_PRIVATE BuiltinLoader {
@@ -141,6 +141,7 @@ class NODE_EXTERN_PRIVATE BuiltinLoader {
// Generated by tools/js2c.cc as node_javascript.cc
void LoadJavaScriptSource(); // Loads data into source_

View File

@@ -11,7 +11,7 @@ node-gyp will use the result of `process.config` that reflects the environment
in which the binary got built.
diff --git a/common.gypi b/common.gypi
index 95c56305926fc3e0e46e4cf99ec86d3d1b5576a7..45bb2c4ff94ceac377c9117da4497cdc5ac41171 100644
index aea3a882c338eb757bef9e85fabab3fc7e7495f7..9303217fb05190c734e410a524a6921723d665d5 100644
--- a/common.gypi
+++ b/common.gypi
@@ -128,6 +128,7 @@

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Kleinschmidt <jkleinsc@electronjs.org>
Date: Fri, 28 Feb 2025 11:24:53 -0500
Subject: chore: add createExternalizableTwoByteString to globals
https://chromium-review.googlesource.com/c/v8/v8/+/6304942 added
createExternalizableTwoByteString, so make sure it is handled
as a global in the parallel/test-fs-write test.
diff --git a/test/parallel/test-fs-write.js b/test/parallel/test-fs-write.js
index 82f3425de2aa162aa97047098806a08d0f8be4bd..31ab5b833db94fec6f2e976f53f650bc6318e794 100644
--- a/test/parallel/test-fs-write.js
+++ b/test/parallel/test-fs-write.js
@@ -48,6 +48,7 @@ assert.notStrictEqual(isOneByteString, undefined);
// Account for extra globals exposed by --expose_externalize_string.
common.allowGlobals(
createExternalizableString,
+ createExternalizableTwoByteString,
externalizeString,
isOneByteString,
globalThis.x,

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Sanders <dsanders11@ucsbalum.com>
Date: Mon, 21 Jul 2025 16:58:56 -0700
Subject: chore: add missing include of <iterator>
This has been upstreamed at https://github.com/ada-url/ada/pull/982
diff --git a/deps/ada/ada.cpp b/deps/ada/ada.cpp
index d7f9b3a92c5330dad1cbd9f6f0bdd96908a4ad13..68fe0701bced5db86834ebd8232d4fe5ae7ed308 100644
--- a/deps/ada/ada.cpp
+++ b/deps/ada/ada.cpp
@@ -11217,6 +11217,7 @@ ada_warn_unused std::string to_string(ada::state state) {
#include <numeric>
#include <algorithm>
+#include <iterator>
#include <string>
namespace ada {
@@ -13067,6 +13068,7 @@ template url_aggregator parse_url<url_aggregator>(
/* end file src/parser.cpp */
/* begin file src/url_components.cpp */
+#include <iterator>
#include <numeric>
#include <string>
@@ -13192,6 +13194,7 @@ namespace ada {
/* end file src/url_components.cpp */
/* begin file src/url_aggregator.cpp */
+#include <iterator>
#include <string>
#include <string_view>

View File

@@ -8,10 +8,10 @@ they use themselves as the entry point. We should try to upstream some form
of this.
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 98ed40e3076f6628b1771dade63ac51600e8e447..1eba13caf1e00a8b41b2cf8afc4168c8f98be69f 100644
index c7f86098bdb00b6be84d547a0ac41919fa1bbb0f..35b43990c8f24f0888f89173f5662050a11b26ed 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -245,12 +245,14 @@ function patchProcessObject(expandArgv1) {
@@ -243,12 +243,14 @@ function patchProcessObject(expandArgv1) {
// the entry point.
if (expandArgv1 && process.argv[1] && process.argv[1][0] !== '-') {
// Expand process.argv[1] into a full path.

View File

@@ -20,7 +20,7 @@ index ab7dc27de3e304f6d912d5834da47e3b4eb25495..b6c0fd4ceee989dac55c7d54e52fef18
}
}
diff --git a/unofficial.gni b/unofficial.gni
index 8886f2a79ae77614789d6ae0defd4f18fc756456..a64d2e4ac475abc049fff7ea62ec76de565a747d 100644
index 253226009faf563f6db285d4b2908f308c1f96ea..dd686d2f7c8d2f6e8d6bd13a7bf2b4b140556ba9 100644
--- a/unofficial.gni
+++ b/unofficial.gni
@@ -143,7 +143,10 @@ template("node_gn_build") {
@@ -35,7 +35,7 @@ index 8886f2a79ae77614789d6ae0defd4f18fc756456..a64d2e4ac475abc049fff7ea62ec76de
public_configs = [
":node_external_config",
"deps/googletest:googletest_config",
@@ -345,6 +348,7 @@ template("node_gn_build") {
@@ -362,6 +365,7 @@ template("node_gn_build") {
"src/embedded_data.h",
]
include_dirs = [ "src", "tools" ]

View File

@@ -11,10 +11,10 @@ its own blended handler between Node and Blink.
Not upstreamable.
diff --git a/lib/internal/modules/esm/utils.js b/lib/internal/modules/esm/utils.js
index 9b41db8b0714b7408f79cbd5b4c460d9bc08f239..35ecfb9bbaf2c8e7351e1c69da84c82a4a7cb049 100644
index 4a4279459341e87784ee8efa832dc74371c4a708..88d84786e72cf8712e0b9bda16c418d4087fe549 100644
--- a/lib/internal/modules/esm/utils.js
+++ b/lib/internal/modules/esm/utils.js
@@ -30,7 +30,7 @@ const {
@@ -34,7 +34,7 @@ const {
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
ERR_INVALID_ARG_VALUE,
} = require('internal/errors').codes;
@@ -23,8 +23,8 @@ index 9b41db8b0714b7408f79cbd5b4c460d9bc08f239..35ecfb9bbaf2c8e7351e1c69da84c82a
const {
loadPreloadModules,
initializeFrozenIntrinsics,
@@ -281,12 +281,13 @@ let _forceDefaultLoader = false;
* @param {boolean} [forceDefaultLoader=false] - A boolean indicating disabling custom loaders.
@@ -291,12 +291,13 @@ let _forceDefaultLoader = false;
* @param {boolean} [forceDefaultLoader] - A boolean indicating disabling custom loaders.
*/
function initializeESM(forceDefaultLoader = false) {
+ const shouldSetOnIsolate = !getEmbedderOptions().shouldNotRegisterESMLoader;
@@ -40,19 +40,19 @@ index 9b41db8b0714b7408f79cbd5b4c460d9bc08f239..35ecfb9bbaf2c8e7351e1c69da84c82a
/**
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index c52e20d742942667f43ea3e151fc6702260b176b..cbb3e7f4df72f83cb8a1afc25a7429218792e964 100644
index 5783728da2894270f902f47b210008df0e911bde..8fed194cbae9ce75bd0805b4df30b4de64fbbefa 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -901,7 +901,7 @@ MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
return module->module_.Get(isolate);
@@ -1097,7 +1097,7 @@ Maybe<ModuleWrap*> ModuleWrap::ResolveModule(
return Just(module_wrap);
}
-static MaybeLocal<Promise> ImportModuleDynamically(
+MaybeLocal<Promise> ImportModuleDynamically(
-static MaybeLocal<Promise> ImportModuleDynamicallyWithPhase(
+MaybeLocal<Promise> ImportModuleDynamicallyWithPhase(
Local<Context> context,
Local<Data> host_defined_options,
Local<Value> resource_name,
@@ -973,12 +973,13 @@ void ModuleWrap::SetImportModuleDynamicallyCallback(
@@ -1185,14 +1185,16 @@ void ModuleWrap::SetImportModuleDynamicallyCallback(
Realm* realm = Realm::GetCurrent(args);
HandleScope handle_scope(isolate);
@@ -63,12 +63,16 @@ index c52e20d742942667f43ea3e151fc6702260b176b..cbb3e7f4df72f83cb8a1afc25a742921
realm->set_host_import_module_dynamically_callback(import_callback);
- isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
+ if (args[1]->IsBoolean() && args[1]->BooleanValue(isolate))
- isolate->SetHostImportModuleWithPhaseDynamicallyCallback(
+ if (args[1]->IsBoolean() && args[1]->BooleanValue(isolate)) {
+ isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
+ isolate->SetHostImportModuleWithPhaseDynamicallyCallback(
ImportModuleDynamicallyWithPhase);
+ }
}
void ModuleWrap::HostInitializeImportMetaObjectCallback(
@@ -1020,13 +1021,14 @@ void ModuleWrap::SetInitializeImportMetaObjectCallback(
@@ -1234,13 +1236,14 @@ void ModuleWrap::SetInitializeImportMetaObjectCallback(
Realm* realm = Realm::GetCurrent(args);
Isolate* isolate = realm->isolate();
@@ -87,7 +91,7 @@ index c52e20d742942667f43ea3e151fc6702260b176b..cbb3e7f4df72f83cb8a1afc25a742921
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
diff --git a/src/module_wrap.h b/src/module_wrap.h
index 9363ce73e51cde3d3a94f9912f072d532d0f8560..c0e972ed293157726efc5fa76dfa62d3da51c22a 100644
index 03cf8d0e91d795aad6db9b11956d296ff4999f7e..45264c2ad58e37a73fd62addac7fb671eed6d502 100644
--- a/src/module_wrap.h
+++ b/src/module_wrap.h
@@ -8,6 +8,7 @@
@@ -98,23 +102,24 @@ index 9363ce73e51cde3d3a94f9912f072d532d0f8560..c0e972ed293157726efc5fa76dfa62d3
#include "v8-script.h"
namespace node {
@@ -33,7 +34,14 @@ enum HostDefinedOptions : int {
kLength = 9,
@@ -92,7 +93,15 @@ struct ModuleCacheKey : public MemoryRetainer {
hash(hash) {}
};
-class ModuleWrap : public BaseObject {
+NODE_EXTERN v8::MaybeLocal<v8::Promise> ImportModuleDynamically(
+NODE_EXTERN v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyWithPhase(
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Data> host_defined_options,
+ v8::Local<v8::Value> resource_name,
+ v8::Local<v8::String> specifier,
+ v8::Local<v8::FixedArray> import_assertions);
+ v8::ModuleImportPhase phase,
+ v8::Local<v8::FixedArray> import_attributes);
+
+class NODE_EXTERN ModuleWrap : public BaseObject {
public:
enum InternalFields {
kModuleSlot = BaseObject::kInternalFieldCount,
@@ -92,6 +100,8 @@ class ModuleWrap : public BaseObject {
using ResolveCache =
std::unordered_map<ModuleCacheKey, uint32_t, ModuleCacheKey::Hash>;
@@ -157,6 +166,8 @@ class ModuleWrap : public BaseObject {
static void CreateRequiredModuleFacade(
const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -123,11 +128,11 @@ index 9363ce73e51cde3d3a94f9912f072d532d0f8560..c0e972ed293157726efc5fa76dfa62d3
private:
ModuleWrap(Realm* realm,
v8::Local<v8::Object> object,
@@ -131,7 +141,6 @@ class ModuleWrap : public BaseObject {
@@ -205,7 +216,6 @@ class ModuleWrap : public BaseObject {
v8::Local<v8::String> specifier,
v8::Local<v8::FixedArray> import_attributes,
v8::Local<v8::Module> referrer);
- static ModuleWrap* GetFromModule(node::Environment*, v8::Local<v8::Module>);
v8::Global<v8::Module> module_;
std::unordered_map<std::string, v8::Global<v8::Object>> resolve_cache_;
// This method may throw a JavaScript exception, so the return type is
// wrapped in a Maybe.

View File

@@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 29 Oct 2025 11:45:23 +0000
Subject: chore: handle support for `import defer * as ns` and `import.defer`
syntax
V8 added support for the above syntax https://chromium-review.googlesource.com/c/v8/v8/+/7017517
by adding a new `ModuleImportPhase::kDefer` phase.
This patch can be removed when Electron updates to a version of Node.js containing
the above CL.
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index a584e3a80adb69d2028dc79450349823ab973a58..6f010fa2e014b2d13b1f89a691d09e2ffdf690b6 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -563,8 +563,10 @@ ModulePhase to_phase_constant(ModuleImportPhase phase) {
return kEvaluationPhase;
case ModuleImportPhase::kSource:
return kSourcePhase;
+ case ModuleImportPhase::kDefer:
+ default:
+ UNREACHABLE();
}
- UNREACHABLE();
}
static Local<Object> createImportAttributesContainer(
@@ -1471,6 +1473,7 @@ void ModuleWrap::CreatePerContextProperties(Local<Object> target,
V(ModulePhase, kEvaluationPhase);
V(ModulePhase, kSourcePhase);
+ V(ModulePhase, kDeferPhase);
#undef V
}
diff --git a/src/module_wrap.h b/src/module_wrap.h
index 45264c2ad58e37a73fd62addac7fb671eed6d502..fb32fbc5c1cfa4aef4a7822dbc6195429299da3e 100644
--- a/src/module_wrap.h
+++ b/src/module_wrap.h
@@ -37,6 +37,7 @@ enum HostDefinedOptions : int {
enum ModulePhase : int {
kSourcePhase = 1,
kEvaluationPhase = 2,
+ kDeferPhase = 3,
};
/**

View File

@@ -1,305 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marco Ippolito <marcoippolito54@gmail.com>
Date: Wed, 1 May 2024 14:24:48 +0200
Subject: cli: move --trace-atomics-wait to eol
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PR-URL: https://github.com/nodejs/node/pull/52747
Fixes: https://github.com/nodejs/node/issues/42982
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
diff --git a/doc/api/cli.md b/doc/api/cli.md
index 9a0e83b95a72486ab9751b3b8818f4beeb527041..1da7126b9d51238e9b89ee6bed602df3f5598a9e 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -2727,39 +2727,6 @@ added: v12.0.0
Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.3'. Use to disable support
for TLSv1.2, which is not as secure as TLSv1.3.
-### `--trace-atomics-wait`
-
-<!-- YAML
-added: v14.3.0
-deprecated:
- - v18.8.0
- - v16.18.0
--->
-
-> Stability: 0 - Deprecated
-
-Print short summaries of calls to [`Atomics.wait()`][] to stderr.
-The output could look like this:
-
-```text
-(node:15701) [Thread 0] Atomics.wait(&lt;address> + 0, 1, inf) started
-(node:15701) [Thread 0] Atomics.wait(&lt;address> + 0, 1, inf) did not wait because the values mismatched
-(node:15701) [Thread 0] Atomics.wait(&lt;address> + 0, 0, 10) started
-(node:15701) [Thread 0] Atomics.wait(&lt;address> + 0, 0, 10) timed out
-(node:15701) [Thread 0] Atomics.wait(&lt;address> + 4, 0, inf) started
-(node:15701) [Thread 1] Atomics.wait(&lt;address> + 4, -1, inf) started
-(node:15701) [Thread 0] Atomics.wait(&lt;address> + 4, 0, inf) was woken up by another thread
-(node:15701) [Thread 1] Atomics.wait(&lt;address> + 4, -1, inf) was woken up by another thread
-```
-
-The fields here correspond to:
-
-* The thread id as given by [`worker_threads.threadId`][]
-* The base address of the `SharedArrayBuffer` in question, as well as the
- byte offset corresponding to the index passed to `Atomics.wait()`
-* The expected value that was passed to `Atomics.wait()`
-* The timeout passed to `Atomics.wait`
-
### `--trace-deprecation`
<!-- YAML
@@ -3445,7 +3412,6 @@ one is included in the list below.
* `--tls-min-v1.1`
* `--tls-min-v1.2`
* `--tls-min-v1.3`
-* `--trace-atomics-wait`
* `--trace-deprecation`
* `--trace-env-js-stack`
* `--trace-env-native-stack`
diff --git a/doc/node.1 b/doc/node.1
index e3b2c45af01b2e9b9522964da2572988edd2b9e9..64e975546285a1042dda6fdb54fdd502f338a929 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -542,11 +542,6 @@ but the option is supported for compatibility with older Node.js versions.
Set default minVersion to 'TLSv1.3'. Use to disable support for TLSv1.2 in
favour of TLSv1.3, which is more secure.
.
-.It Fl -trace-atomics-wait
-Print short summaries of calls to
-.Sy Atomics.wait() .
-.
-This flag is deprecated.
.It Fl -trace-deprecation
Print stack traces for deprecations.
.
diff --git a/src/node.cc b/src/node.cc
index 0725cc97510375bc616534ddf3de4b231bae6bf5..f21687ad9dfd69c829aaaf8f3ed66b6bf6713765 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -232,44 +232,6 @@ void Environment::WaitForInspectorFrontendByOptions() {
}
#endif // HAVE_INSPECTOR
-#define ATOMIC_WAIT_EVENTS(V) \
- V(kStartWait, "started") \
- V(kWokenUp, "was woken up by another thread") \
- V(kTimedOut, "timed out") \
- V(kTerminatedExecution, "was stopped by terminated execution") \
- V(kAPIStopped, "was stopped through the embedder API") \
- V(kNotEqual, "did not wait because the values mismatched") \
-
-static void AtomicsWaitCallback(Isolate::AtomicsWaitEvent event,
- Local<v8::SharedArrayBuffer> array_buffer,
- size_t offset_in_bytes, int64_t value,
- double timeout_in_ms,
- Isolate::AtomicsWaitWakeHandle* stop_handle,
- void* data) {
- Environment* env = static_cast<Environment*>(data);
-
- const char* message = "(unknown event)";
- switch (event) {
-#define V(key, msg) \
- case Isolate::AtomicsWaitEvent::key: \
- message = msg; \
- break;
- ATOMIC_WAIT_EVENTS(V)
-#undef V
- }
-
- fprintf(stderr,
- "(node:%d) [Thread %" PRIu64 "] Atomics.wait(%p + %zx, %" PRId64
- ", %.f) %s\n",
- static_cast<int>(uv_os_getpid()),
- env->thread_id(),
- array_buffer->Data(),
- offset_in_bytes,
- value,
- timeout_in_ms,
- message);
-}
-
void Environment::InitializeDiagnostics() {
isolate_->GetHeapProfiler()->AddBuildEmbedderGraphCallback(
Environment::BuildEmbedderGraph, this);
@@ -278,17 +240,6 @@ void Environment::InitializeDiagnostics() {
}
if (options_->trace_uncaught)
isolate_->SetCaptureStackTraceForUncaughtExceptions(true);
- if (options_->trace_atomics_wait) {
- ProcessEmitDeprecationWarning(
- Environment::GetCurrent(isolate_),
- "The flag --trace-atomics-wait is deprecated.",
- "DEP0165");
- isolate_->SetAtomicsWaitCallback(AtomicsWaitCallback, this);
- AddCleanupHook([](void* data) {
- Environment* env = static_cast<Environment*>(data);
- env->isolate()->SetAtomicsWaitCallback(nullptr, nullptr);
- }, this);
- }
if (options_->trace_promises) {
isolate_->SetPromiseHook(TracePromises);
}
diff --git a/src/node_options.cc b/src/node_options.cc
index e8424d7539db191a55edebb7d33a3c1dc37e2403..556776b79282d953fdc371d1901f21ca301bec1a 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -773,10 +773,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"throw an exception on deprecations",
&EnvironmentOptions::throw_deprecation,
kAllowedInEnvvar);
- AddOption("--trace-atomics-wait",
- "(deprecated) trace Atomics.wait() operations",
- &EnvironmentOptions::trace_atomics_wait,
- kAllowedInEnvvar);
AddOption("--trace-deprecation",
"show stack traces on deprecations",
&EnvironmentOptions::trace_deprecation,
diff --git a/src/node_options.h b/src/node_options.h
index 418dee360f867c363f1576012b32213a51c4fdd0..7078d2493ed696bc5bd92df9c629b714c1a8fbfb 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -205,7 +205,6 @@ class EnvironmentOptions : public Options {
std::vector<std::string> coverage_include_pattern;
std::vector<std::string> coverage_exclude_pattern;
bool throw_deprecation = false;
- bool trace_atomics_wait = false;
bool trace_deprecation = false;
bool trace_exit = false;
bool trace_sync_io = false;
diff --git a/test/parallel/test-trace-atomic-deprecation.js b/test/parallel/test-trace-atomic-deprecation.js
deleted file mode 100644
index 8aeddb28e938d23e646d882cfe24b2e2311f9ab2..0000000000000000000000000000000000000000
--- a/test/parallel/test-trace-atomic-deprecation.js
+++ /dev/null
@@ -1,14 +0,0 @@
-'use strict';
-
-const common = require('../common');
-const assert = require('node:assert');
-const { test } = require('node:test');
-
-test('should emit deprecation warning DEP0165', async () => {
- const { code, stdout, stderr } = await common.spawnPromisified(
- process.execPath, ['--trace-atomics-wait', '-e', '{}']
- );
- assert.match(stderr, /\[DEP0165\] DeprecationWarning:/);
- assert.strictEqual(stdout, '');
- assert.strictEqual(code, 0);
-});
diff --git a/test/parallel/test-trace-atomics-wait.js b/test/parallel/test-trace-atomics-wait.js
deleted file mode 100644
index 6449a2be2b47e0758090dc13d136877b1874c635..0000000000000000000000000000000000000000
--- a/test/parallel/test-trace-atomics-wait.js
+++ /dev/null
@@ -1,101 +0,0 @@
-'use strict';
-require('../common');
-const assert = require('assert');
-const child_process = require('child_process');
-const { Worker } = require('worker_threads');
-
-if (process.argv[2] === 'child') {
- const i32arr = new Int32Array(new SharedArrayBuffer(8));
- assert.strictEqual(Atomics.wait(i32arr, 0, 1), 'not-equal');
- assert.strictEqual(Atomics.wait(i32arr, 0, 0, 10), 'timed-out');
-
- new Worker(`
- const i32arr = require('worker_threads').workerData;
- Atomics.store(i32arr, 1, -1);
- Atomics.notify(i32arr, 1);
- Atomics.wait(i32arr, 1, -1);
- `, { eval: true, workerData: i32arr });
-
- Atomics.wait(i32arr, 1, 0);
- assert.strictEqual(Atomics.load(i32arr, 1), -1);
- Atomics.store(i32arr, 1, 0);
- Atomics.notify(i32arr, 1);
- return;
-}
-
-const proc = child_process.spawnSync(
- process.execPath,
- [ '--disable-warning=DEP0165', '--trace-atomics-wait', __filename, 'child' ],
- { encoding: 'utf8', stdio: [ 'inherit', 'inherit', 'pipe' ] });
-
-if (proc.status !== 0) console.log(proc);
-assert.strictEqual(proc.status, 0);
-
-const SABAddress = proc.stderr.match(/Atomics\.wait\((?<SAB>.+) \+/).groups.SAB;
-const actualTimeline = proc.stderr
- .replace(new RegExp(SABAddress, 'g'), '<address>')
- .replace(new RegExp(`\\(node:${proc.pid}\\) `, 'g'), '')
- .replace(/\binf(inity)?\b/gi, 'inf')
- .replace(/\r/g, '')
- .trim();
-console.log('+++ normalized stdout +++');
-console.log(actualTimeline);
-console.log('--- normalized stdout ---');
-
-const begin =
-`[Thread 0] Atomics.wait(<address> + 0, 1, inf) started
-[Thread 0] Atomics.wait(<address> + 0, 1, inf) did not wait because the \
-values mismatched
-[Thread 0] Atomics.wait(<address> + 0, 0, 10) started
-[Thread 0] Atomics.wait(<address> + 0, 0, 10) timed out`;
-
-const expectedTimelines = [
- `${begin}
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) was woken up by another thread
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) was woken up by another thread`,
- `${begin}
-[Thread 1] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 0] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) was woken up by another thread
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) was woken up by another thread`,
- `${begin}
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) was woken up by another thread
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) was woken up by another thread`,
- `${begin}
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) was woken up by another thread
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) did not wait because the \
-values mismatched`,
- `${begin}
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) was woken up by another thread
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) did not wait because the \
-values mismatched`,
- `${begin}
-[Thread 1] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 0] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) was woken up by another thread
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) did not wait because the \
-values mismatched`,
- `${begin}
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) did not wait because the \
-values mismatched
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) did not wait because the \
-values mismatched`,
- `${begin}
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) started
-[Thread 0] Atomics.wait(<address> + 4, 0, inf) did not wait because the \
-values mismatched
-[Thread 1] Atomics.wait(<address> + 4, -1, inf) was woken up by another thread`,
-];
-
-assert(expectedTimelines.includes(actualTimeline));

View File

@@ -1,59 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Omer Katz <omerkatz@chromium.org>
Date: Thu, 19 Sep 2024 10:50:09 +0200
Subject: cli: remove deprecated V8 flag
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Remove the `--huge-max-old-generation-size` V8 flag from the
`NODE_OPTIONS` allowlist. That flag was recently deprecated (it
currently remains as nop, see crrev.com/c/5831467) and will soon be
completely removed.
PR-URL: https://github.com/nodejs/node/pull/54761
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
diff --git a/doc/api/cli.md b/doc/api/cli.md
index b8f9fb49fcb45602828e79bd79902233b5987dda..9a0e83b95a72486ab9751b3b8818f4beeb527041 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -3483,7 +3483,6 @@ V8 options that are allowed are:
* `--disallow-code-generation-from-strings`
* `--enable-etw-stack-walking`
* `--expose-gc`
-* `--huge-max-old-generation-size`
* `--interpreted-frames-native-stack`
* `--jitless`
* `--max-old-space-size`
diff --git a/src/node_options.cc b/src/node_options.cc
index 8afded658c3f569de7b329ea9dddc11010748cf9..e8424d7539db191a55edebb7d33a3c1dc37e2403 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1001,11 +1001,6 @@ PerIsolateOptionsParser::PerIsolateOptionsParser(
"disallow eval and friends",
V8Option{},
kAllowedInEnvvar);
- AddOption("--huge-max-old-generation-size",
- "increase default maximum heap size on machines with 16GB memory "
- "or more",
- V8Option{},
- kAllowedInEnvvar);
AddOption("--jitless",
"disable runtime allocation of executable memory",
V8Option{},
diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js
index c5d74f40e7894980b45713c77cc36f836be73528..53bca572c3405c0357f868aae71fc2c82d973c04 100644
--- a/test/parallel/test-cli-node-options.js
+++ b/test/parallel/test-cli-node-options.js
@@ -76,7 +76,6 @@ if (common.hasCrypto) {
expect('--abort_on-uncaught_exception', 'B\n');
expect('--disallow-code-generation-from-strings', 'B\n');
expect('--expose-gc', 'B\n');
-expect('--huge-max-old-generation-size', 'B\n');
expect('--jitless', 'B\n');
expect('--max-old-space-size=0', 'B\n');
expect('--max-semi-space-size=0', 'B\n');

View File

@@ -8,7 +8,7 @@ to child processes spawned with `ELECTRON_RUN_AS_NODE` which is used
by the crashpad client to connect with the handler process.
diff --git a/lib/child_process.js b/lib/child_process.js
index 960ecd25ebb5b2aba0b92b869a2332a3a69011e1..ced0a5d792c63662c577a41c88b52cae076e7d08 100644
index 17c6b69c118a759f9fcf254a035f1a07fcc4059f..c8576fbf889d13f951a9ad2ffeb93389cfe2445b 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -62,6 +62,7 @@ let debug = require('internal/util/debuglog').debuglog(
@@ -27,7 +27,7 @@ index 960ecd25ebb5b2aba0b92b869a2332a3a69011e1..ced0a5d792c63662c577a41c88b52cae
args = [...execArgv, modulePath, ...args];
if (typeof options.stdio === 'string') {
@@ -637,6 +637,22 @@ function normalizeSpawnArguments(file, args, options) {
@@ -638,6 +638,22 @@ function normalizeSpawnArguments(file, args, options) {
'options.windowsVerbatimArguments');
}
@@ -49,8 +49,8 @@ index 960ecd25ebb5b2aba0b92b869a2332a3a69011e1..ced0a5d792c63662c577a41c88b52cae
+
if (options.shell) {
validateArgumentNullCheck(options.shell, 'options.shell');
@@ -671,8 +687,6 @@ function normalizeSpawnArguments(file, args, options) {
if (args.length > 0 && !emittedDEP0190Already) {
@@ -680,8 +696,6 @@ function normalizeSpawnArguments(file, args, options) {
ArrayPrototypeUnshift(args, file);
}

View File

@@ -9,10 +9,10 @@ modules to sandboxed renderers.
TODO(codebytere): remove and replace with a public facing API.
diff --git a/src/node_binding.cc b/src/node_binding.cc
index aa4213c3622eab077fa8d764775c1f95c6313e34..11f722d2d7c21079cbc65033429086231a786ca7 100644
index 5bd07e5253ae64b02ae1874226ab70c1972cf9e0..768d81a63a42d9016a42b7cdce7b6be86c59afdf 100644
--- a/src/node_binding.cc
+++ b/src/node_binding.cc
@@ -652,6 +652,10 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
@@ -655,6 +655,10 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(exports);
}
@@ -24,10 +24,10 @@ index aa4213c3622eab077fa8d764775c1f95c6313e34..11f722d2d7c21079cbc6503342908623
Environment* env = Environment::GetCurrent(args);
diff --git a/src/node_binding.h b/src/node_binding.h
index 611f38ef5e21cc303127326d50c648fbb557b4da..3d95ad2733dc83d0b7d37d57c337732c8a0e83d7 100644
index 813204dc473960e63896b6d3609a882b52ac59fa..2fe91a28460973b543f5dde7a78fdedb05ac98b3 100644
--- a/src/node_binding.h
+++ b/src/node_binding.h
@@ -154,6 +154,8 @@ void GetInternalBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -155,6 +155,8 @@ void GetInternalBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetLinkedBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
void DLOpen(const v8::FunctionCallbackInfo<v8::Value>& args);

View File

@@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 22 Oct 2025 11:03:57 +0200
Subject: feat: disable js source phase imports by default.
Refs:
- https://chromium-review.googlesource.com/c/v8/v8/+/7003082
- https://chromium-review.googlesource.com/c/chromium/src/+/6336964
- https://github.com/nodejs/node/pull/56919
We need to disable source phase imports in renderer and worker processes - Chromium
disables them in content/renderer/render_process_impl.cc via and the process will
hard crash otherwise.
They shouldn't be enabled by default in Node.js either as they are still not yet
Stage 3.
Upstreamed in https://github.com/nodejs/node/pull/60364
diff --git a/src/node.cc b/src/node.cc
index 5713d49d859e1161e1d6703c0b6f3d717a5a9a34..829634c084cb91eb7f488dbdd48175a093dd6e12 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -780,7 +780,7 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
env_opts->abort_on_uncaught_exception = true;
}
- v8_args.emplace_back("--js-source-phase-imports");
+ // v8_args.emplace_back("--js-source-phase-imports");
#ifdef __POSIX__
// Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the

View File

@@ -7,7 +7,7 @@ common.gypi is a file that's included in the node header bundle, despite
the fact that we do not build node with gyp.
diff --git a/common.gypi b/common.gypi
index ae31b372b96358a156761ec7e9c39c9530d1abd1..6b79de07be3f839af5b0644f19bfef9c33de590e 100644
index 7727dfc4c62100cbd873ee4b34c6089ab4b638b1..29a912f58e7b522ae21fddac510946cbcbaaa4cc 100644
--- a/common.gypi
+++ b/common.gypi
@@ -91,6 +91,23 @@

View File

@@ -1,101 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: VerteDinde <vertedinde@electronjs.org>
Date: Mon, 29 Apr 2024 02:56:27 -0700
Subject: fix: add source location for v8::Task Runner
This patch corresponds with an upstream change which adds
Post*TaskImpl variants of v8::TaskRunner::Post*Task methods,
which take a v8::SourceLocation argument, and makes Post*Task
methods non-virtual. In the original CL, embedders are asked
to override the Post*TaskImpl methods.
This patch can be removed when node's upstream makes a
corresponding change.
CL: https://chromium-review.googlesource.com/c/v8/v8/+/5300826
diff --git a/src/node_platform.cc b/src/node_platform.cc
index 0ffebd1dcb693dcddbedff5d259cf65c115f1dc2..b24e170cb247261d4a16d77ad40df4dfd33709d9 100644
--- a/src/node_platform.cc
+++ b/src/node_platform.cc
@@ -308,11 +308,13 @@ void PerIsolatePlatformData::FlushTasks(uv_async_t* handle) {
platform_data->FlushForegroundTasksInternal();
}
-void PerIsolatePlatformData::PostIdleTask(std::unique_ptr<v8::IdleTask> task) {
+void PerIsolatePlatformData::PostIdleTaskImpl(std::unique_ptr<v8::IdleTask> task,
+ const v8::SourceLocation& location) {
UNREACHABLE();
}
-void PerIsolatePlatformData::PostTask(std::unique_ptr<Task> task) {
+void PerIsolatePlatformData::PostTaskImpl(std::unique_ptr<Task> task,
+ const v8::SourceLocation& location) {
// The task can be posted from any V8 background worker thread, even when
// the foreground task runner is being cleaned up by Shutdown(). In that
// case, make sure we wait until the shutdown is completed (which leads
@@ -331,8 +333,10 @@ void PerIsolatePlatformData::PostTask(std::unique_ptr<Task> task) {
uv_async_send(flush_tasks_);
}
-void PerIsolatePlatformData::PostDelayedTask(
- std::unique_ptr<Task> task, double delay_in_seconds) {
+void PerIsolatePlatformData::PostDelayedTaskImpl(
+ std::unique_ptr<Task> task,
+ double delay_in_seconds,
+ const v8::SourceLocation& location) {
if (debug_log_level_ != PlatformDebugLogLevel::kNone) {
fprintf(stderr,
"\nPerIsolatePlatformData::PostDelayedTaskImpl %p %f",
@@ -354,13 +358,15 @@ void PerIsolatePlatformData::PostDelayedTask(
uv_async_send(flush_tasks_);
}
-void PerIsolatePlatformData::PostNonNestableTask(std::unique_ptr<Task> task) {
+void PerIsolatePlatformData::PostNonNestableTaskImpl(std::unique_ptr<Task> task,
+ const v8::SourceLocation& location) {
PostTask(std::move(task));
}
-void PerIsolatePlatformData::PostNonNestableDelayedTask(
+void PerIsolatePlatformData::PostNonNestableDelayedTaskImpl(
std::unique_ptr<Task> task,
- double delay_in_seconds) {
+ double delay_in_seconds,
+ const v8::SourceLocation& location) {
PostDelayedTask(std::move(task), delay_in_seconds);
}
diff --git a/src/node_platform.h b/src/node_platform.h
index af30ebeb0c8629ab86d1a55fd63610165abfbabf..a0222b4a1b074c6708e390d58d04221717069ac1 100644
--- a/src/node_platform.h
+++ b/src/node_platform.h
@@ -80,18 +80,21 @@ class PerIsolatePlatformData :
~PerIsolatePlatformData() override;
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner() override;
- void PostTask(std::unique_ptr<v8::Task> task) override;
- void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
- void PostDelayedTask(std::unique_ptr<v8::Task> task,
- double delay_in_seconds) override;
+ void PostTaskImpl(std::unique_ptr<v8::Task> task, const v8::SourceLocation&) override;
+ void PostIdleTaskImpl(std::unique_ptr<v8::IdleTask> task, const v8::SourceLocation&) override;
+ void PostDelayedTaskImpl(std::unique_ptr<v8::Task> task,
+ double delay_in_seconds,
+ const v8::SourceLocation&) override;
bool IdleTasksEnabled() override { return false; }
// Non-nestable tasks are treated like regular tasks.
bool NonNestableTasksEnabled() const override { return true; }
bool NonNestableDelayedTasksEnabled() const override { return true; }
- void PostNonNestableTask(std::unique_ptr<v8::Task> task) override;
- void PostNonNestableDelayedTask(std::unique_ptr<v8::Task> task,
- double delay_in_seconds) override;
+ void PostNonNestableTaskImpl(std::unique_ptr<v8::Task> task,
+ const v8::SourceLocation&) override;
+ void PostNonNestableDelayedTaskImpl(std::unique_ptr<v8::Task> task,
+ double delay_in_seconds,
+ const v8::SourceLocation&) override;
void AddShutdownCallback(void (*callback)(void*), void* data);
void Shutdown();

View File

@@ -11,31 +11,14 @@ Node.js upgrades to a version of V8 that has Float16Array enabled by
default.
diff --git a/test/common/globals.js b/test/common/globals.js
index 2c1dac019ba2aa0a23c2434997e2007dd2eacde8..152d9afa8f8ef6b76fceb0ac4481d1df719b872b 100644
index 1641c4df36b92dbe29b06817d87130a94ae1b22f..34563b304f0e708ae066f8303a09e37b6bf123d6 100644
--- a/test/common/globals.js
+++ b/test/common/globals.js
@@ -35,6 +35,7 @@ const intrinsics = new Set([
'Int16Array',
@@ -36,6 +36,7 @@ const intrinsics = new Set([
'Float16Array',
'Uint32Array',
'Int32Array',
+ 'Float16Array',
'Float32Array',
'Float64Array',
'Uint8ClampedArray',
diff --git a/test/wpt/status/encoding.json b/test/wpt/status/encoding.json
index f9378d7195a2a77eb89ae696ab26747fd8bf65b8..c258031e48556480d500a02925a8d9c29dfb2a18 100644
--- a/test/wpt/status/encoding.json
+++ b/test/wpt/status/encoding.json
@@ -70,12 +70,6 @@
"requires": ["full-icu"]
},
"encodeInto.any.js": {
- "fail": {
- "expected": [
- "Invalid encodeInto() destination: Float16Array, backed by: ArrayBuffer",
- "Invalid encodeInto() destination: Float16Array, backed by: SharedArrayBuffer"
- ]
- },
"requires": ["small-icu"]
},
"textdecoder-copy.any.js": {

View File

@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 21 Oct 2025 20:00:06 +0200
Subject: fix: allow disabling fetch in renderer and worker processes
We need to disable Node.js' fetch implementation to prevent
conflict with Blink's in renderer and worker processes.
We should try to upstream some version of this.
diff --git a/doc/api/cli.md b/doc/api/cli.md
index cc990c01704484cbaa314320b3b3b72acffb6940..6b985c9fce6ec607df0e04f93b3cd5b84233d0b9 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -1767,6 +1767,14 @@ changes:
Disable using [syntax detection][] to determine module type.
+### `--no-experimental-fetch`
+
+<!-- YAML
+added: v18.0.0
+-->
+
+Disable exposition of Fetch API on the global scope.
+
### `--no-experimental-global-navigator`
<!-- YAML
@@ -3436,6 +3444,7 @@ one is included in the list below.
* `--no-addons`
* `--no-async-context-frame`
* `--no-deprecation`
+* `--no-experimental-fetch`
* `--no-experimental-global-navigator`
* `--no-experimental-repl-await`
* `--no-experimental-sqlite`
diff --git a/doc/node.1 b/doc/node.1
index 6210cbf42b26d4673f67aac43874ea28c8955fd5..565068cc3aca0eb03642e1160b814b48cb0c3c45 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -198,6 +198,9 @@ Enable transformation of TypeScript-only syntax into JavaScript code.
.It Fl -experimental-eventsource
Enable experimental support for the EventSource Web API.
.
+.It Fl -no-experimental-fetch
+Disable experimental support for the Fetch API.
+.
.It Fl -no-experimental-websocket
Disable experimental support for the WebSocket API.
.
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 35b43990c8f24f0888f89173f5662050a11b26ed..2c0d12c0fa9c85ac7ffb41dabda83760ed1ae3ee 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -110,6 +110,7 @@ function prepareExecution(options) {
setupSQLite();
setupQuic();
setupWebStorage();
+ setupFetch();
setupWebsocket();
setupEventsource();
setupCodeCoverage();
@@ -312,6 +313,16 @@ function setupWarningHandler() {
}
}
+function setupFetch() {
+ if (getOptionValue('--no-experimental-fetch')) {
+ delete globalThis.fetch;
+ delete globalThis.FormData;
+ delete globalThis.Headers;
+ delete globalThis.Request;
+ delete globalThis.Response;
+ }
+}
+
// https://websockets.spec.whatwg.org/
function setupWebsocket() {
if (getOptionValue('--no-experimental-websocket')) {
diff --git a/src/node_options.cc b/src/node_options.cc
index 2a3ab5e73cdb98bde9df1465d5fb5e40ad7799f7..9317191d22f51fd75157e849eb67678d1ee6a2a1 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -537,7 +537,11 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
&EnvironmentOptions::experimental_eventsource,
kAllowedInEnvvar,
false);
- AddOption("--experimental-fetch", "", NoOp{}, kAllowedInEnvvar);
+ AddOption("--experimental-fetch",
+ "experimental Fetch API",
+ &EnvironmentOptions::experimental_fetch,
+ kAllowedInEnvvar,
+ true);
AddOption("--experimental-websocket",
"experimental WebSocket API",
&EnvironmentOptions::experimental_websocket,
diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js
index f09bf0940dad2068f0aa5dce783dd422773d4bbb..ccf4ffcacf9bd9965978738656b8fe091fee4d6a 100644
--- a/test/parallel/test-process-env-allowed-flags-are-documented.js
+++ b/test/parallel/test-process-env-allowed-flags-are-documented.js
@@ -122,7 +122,6 @@ const undocumented = difference(process.allowedNodeEnvironmentFlags,
assert(undocumented.delete('--debug-arraybuffer-allocations'));
assert(undocumented.delete('--no-debug-arraybuffer-allocations'));
assert(undocumented.delete('--es-module-specifier-resolution'));
-assert(undocumented.delete('--experimental-fetch'));
assert(undocumented.delete('--experimental-wasm-modules'));
assert(undocumented.delete('--experimental-global-customevent'));
assert(undocumented.delete('--experimental-global-webcrypto'));

View File

@@ -11,7 +11,7 @@ We can fix this by allowing the C++ implementation of legacyMainResolve to use
a fileExists function that does take Asar into account.
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index e3afd30ba1f591d0298793bc42fd7166a4219bce..408dc96307d7f52f92db41004b358051a81c627c 100644
index 72cc9444ca93ef7a1526e23314693aeaf5f173b0..79684dd7e8d1629b19be01ebf97e43e503dec581 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -28,14 +28,13 @@ const { BuiltinModule } = require('internal/bootstrap/realm');
@@ -53,10 +53,10 @@ index e3afd30ba1f591d0298793bc42fd7166a4219bce..408dc96307d7f52f92db41004b358051
const maybeMain = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ?
packageConfig.main || './' : '';
diff --git a/src/node_file.cc b/src/node_file.cc
index e78326ed0de805a8bf4f621cad9158635eb44aa2..d7009937b31729f33d9c45cbda7f5440fbdac2aa 100644
index 00f369e9691e184f9e5f226ce4216bd5b1d353ae..d73dac2ee3f1cf1cac6845fae0f702c9fba8fcef 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -3502,13 +3502,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
@@ -3623,13 +3623,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
}
BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile(
@@ -83,7 +83,7 @@ index e78326ed0de805a8bf4f621cad9158635eb44aa2..d7009937b31729f33d9c45cbda7f5440
uv_fs_t req;
int rc = uv_fs_stat(env->event_loop(), &req, file_path.c_str(), nullptr);
@@ -3566,6 +3578,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
@@ -3687,6 +3699,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
std::optional<std::string> initial_file_path;
std::string file_path;
@@ -95,7 +95,7 @@ index e78326ed0de805a8bf4f621cad9158635eb44aa2..d7009937b31729f33d9c45cbda7f5440
if (args.Length() >= 2 && args[1]->IsString()) {
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
@@ -3586,7 +3603,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
@@ -3707,7 +3724,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
BufferValue buff_file_path(isolate, local_file_path);
ToNamespacedPath(env, &buff_file_path);
@@ -104,7 +104,7 @@ index e78326ed0de805a8bf4f621cad9158635eb44aa2..d7009937b31729f33d9c45cbda7f5440
case BindingData::FilePathIsFileReturnType::kIsFile:
return args.GetReturnValue().Set(i);
case BindingData::FilePathIsFileReturnType::kIsNotFile:
@@ -3623,7 +3640,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
@@ -3744,7 +3761,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
BufferValue buff_file_path(isolate, local_file_path);
ToNamespacedPath(env, &buff_file_path);
@@ -114,7 +114,7 @@ index e78326ed0de805a8bf4f621cad9158635eb44aa2..d7009937b31729f33d9c45cbda7f5440
return args.GetReturnValue().Set(i);
case BindingData::FilePathIsFileReturnType::kIsNotFile:
diff --git a/src/node_file.h b/src/node_file.h
index bdad1ae25f4892cbbfd8cc30c4d8b4a6f600edbc..099488319f53bc7718313d6e30df2237cad6771d 100644
index 224fa6f7ade375cb673c8adcc95927fa04f9c248..343c6bec67e6cf70ffb91b87e7837dbaf6071cee 100644
--- a/src/node_file.h
+++ b/src/node_file.h
@@ -101,7 +101,8 @@ class BindingData : public SnapshotableObject {

View File

@@ -1,67 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 16 Aug 2023 19:15:29 +0200
Subject: fix: assert module in the renderer process
When creating a Node.js Environment, embedders have the option to disable Node.js'
default overriding of Error.prepareStackTrace. However, the assert module depends on
a WeakMap that is populated with the error stacktraces in the overridden function.
This adds handling to fall back to the default implementation if Error.prepareStackTrace
if the override has been disabled.
This will be upstreamed.
diff --git a/lib/internal/assert/utils.js b/lib/internal/assert/utils.js
index 13e41d67c635c27bd5e69eb4960eace34beaef0d..9a99c9ca93907630f9f3ba7ba24577a11465661c 100644
--- a/lib/internal/assert/utils.js
+++ b/lib/internal/assert/utils.js
@@ -24,6 +24,7 @@ const AssertionError = require('internal/assert/assertion_error');
const { openSync, closeSync, readSync } = require('fs');
const { EOL } = require('internal/constants');
const { BuiltinModule } = require('internal/bootstrap/realm');
+const { getEmbedderOptions } = require('internal/options');
const { isError } = require('internal/util');
const errorCache = new SafeMap();
@@ -166,8 +167,16 @@ function getErrMessage(message, fn) {
ErrorCaptureStackTrace(err, fn);
if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit;
- overrideStackTrace.set(err, (_, stack) => stack);
- const call = err.stack[0];
+ let call;
+ if (getEmbedderOptions().hasPrepareStackTraceCallback) {
+ overrideStackTrace.set(err, (_, stack) => stack);
+ call = err.stack[0];
+ } else {
+ const tmpPrepare = Error.prepareStackTrace;
+ Error.prepareStackTrace = (_, stack) => stack;
+ call = err.stack[0];
+ Error.prepareStackTrace = tmpPrepare;
+ }
let filename = call.getFileName();
const line = call.getLineNumber() - 1;
diff --git a/src/node_options.cc b/src/node_options.cc
index e3509abbc3bf84ac0edcd495eb3dde6219dbfc2d..8afded658c3f569de7b329ea9dddc11010748cf9 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1566,14 +1566,16 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
}
Isolate* isolate = args.GetIsolate();
- constexpr size_t kOptionsSize = 4;
+ constexpr size_t kOptionsSize = 5;
std::array<Local<Name>, kOptionsSize> names = {
+ FIXED_ONE_BYTE_STRING(env->isolate(), "hasPrepareStackTraceCallback"),
FIXED_ONE_BYTE_STRING(env->isolate(), "shouldNotRegisterESMLoader"),
FIXED_ONE_BYTE_STRING(env->isolate(), "noGlobalSearchPaths"),
FIXED_ONE_BYTE_STRING(env->isolate(), "noBrowserGlobals"),
FIXED_ONE_BYTE_STRING(env->isolate(), "hasEmbedderPreload")};
std::array<Local<Value>, kOptionsSize> values = {
+ Boolean::New(isolate, env->prepare_stack_trace_callback().IsEmpty()),
Boolean::New(isolate, env->should_not_register_esm_loader()),
Boolean::New(isolate, env->no_global_search_paths()),
Boolean::New(isolate, env->no_browser_globals()),

View File

@@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Fri, 24 Oct 2025 15:32:50 +0200
Subject: fix: avoid external memory leak on invalid TLS protocol versions
Fixes a crash caused by unbalanced external memory accounting when
tls.createSecureContext() is called with invalid minVersion/maxVersion values:
Prior to this change, _tls_common.js instantiated a native SecureContext
which incremented V8 external memory via
env->external_memory_accounter()->Increase(kExternalSize) in crypto_context.cc
before protocol version validation ran in toV(), so an early
ERR_TLS_INVALID_PROTOCOL_VERSION throw left the +1024 bytes un-decremented
and V8 asserted in ExternalMemoryAccounter::~ExternalMemoryAccounter
during Environment teardown.
Fix this by reordering the constructor to validate minVersion/maxVersion first and
only allocate the native SecureContext on success.
This should be upstreamed to Node.js.
diff --git a/lib/_tls_common.js b/lib/_tls_common.js
index 66331d2d9999e93e59cbce9e153affb942b79946..0f7fd0747ea779f76a9e64ed37d195bd735ea2a8 100644
--- a/lib/_tls_common.js
+++ b/lib/_tls_common.js
@@ -82,10 +82,11 @@ function SecureContext(secureProtocol, secureOptions, minVersion, maxVersion) {
throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(maxVersion, secureProtocol);
}
+ const minV = toV('minimum', minVersion, tls.DEFAULT_MIN_VERSION);
+ const maxV = toV('maximum', maxVersion, tls.DEFAULT_MAX_VERSION);
+
this.context = new NativeSecureContext();
- this.context.init(secureProtocol,
- toV('minimum', minVersion, tls.DEFAULT_MIN_VERSION),
- toV('maximum', maxVersion, tls.DEFAULT_MAX_VERSION));
+ this.context.init(secureProtocol, minV, maxV);
if (secureOptions) {
validateInteger(secureOptions, 'secureOptions');
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index 8fbf4f25a91b953f3d2868889c7ee06932ee3c5f..96f6ea29525bc2c60297e7be5bc1d0b74cd568e1 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -1355,10 +1355,8 @@ SecureContext::SecureContext(Environment* env, Local<Object> wrap)
}
inline void SecureContext::Reset() {
- if (ctx_ != nullptr) {
- env()->external_memory_accounter()->Decrease(env()->isolate(),
- kExternalSize);
- }
+ env()->external_memory_accounter()->Decrease(env()->isolate(),
+ kExternalSize);
ctx_.reset();
cert_.reset();
issuer_.reset();

View File

@@ -12,10 +12,10 @@ This can be removed/refactored once Node.js upgrades to a version of V8
containing the above CL.
diff --git a/src/node.cc b/src/node.cc
index f21687ad9dfd69c829aaaf8f3ed66b6bf6713765..17c29c759d4fa1a3b709c0844a80fbf509124d73 100644
index c70bec82a28b166afa785d458d3f6c820d7b8565..5713d49d859e1161e1d6703c0b6f3d717a5a9a34 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1246,7 +1246,7 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
@@ -1245,7 +1245,7 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
result->platform_ = per_process::v8_platform.Platform();
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,10 +6,10 @@ Subject: fix: do not resolve electron entrypoints
This wastes fs cycles and can result in strange behavior if this path actually exists on disk
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index 2c33fd44b9a251682de78a8bcdad9ee5a0d3e5e8..ae3ef0e853ae19fca649704854d4bda84a5bd287 100644
index 1f967df42128a05e49acfa6d409737c06a3372e3..c9b0dae3378f556c453f4fa31208eb6f57c433a9 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -355,6 +355,10 @@ function cjsPreparseModuleExports(filename, source, format) {
@@ -408,6 +408,10 @@ function cjsPreparseModuleExports(filename, source, format) {
return { module, exportNames: module[kModuleExportNames] };
}
@@ -21,7 +21,7 @@ index 2c33fd44b9a251682de78a8bcdad9ee5a0d3e5e8..ae3ef0e853ae19fca649704854d4bda8
({ source } = loadSourceForCJSWithHooks(module, filename, format));
}
diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js
index 02ba43adc2c8e92a78942bbb04023a16f5870ee9..bbf1ab69b884a9325bebdd07b2c4fd354eee946b 100644
index 2a9ef56d1568080d19d4b6e68a14c752e48c3822..fb45f3dc66a49a554df1c06431197392c0a199b7 100644
--- a/lib/internal/modules/run_main.js
+++ b/lib/internal/modules/run_main.js
@@ -2,6 +2,7 @@
@@ -32,8 +32,8 @@ index 02ba43adc2c8e92a78942bbb04023a16f5870ee9..bbf1ab69b884a9325bebdd07b2c4fd35
globalThis,
} = primordials;
@@ -26,6 +27,13 @@ const {
* @param {string} main - Entry point path
@@ -27,6 +28,13 @@ const {
* @returns {string|undefined}
*/
function resolveMainPath(main) {
+ // For built-in modules used as the main entry point we _never_
@@ -43,11 +43,11 @@ index 02ba43adc2c8e92a78942bbb04023a16f5870ee9..bbf1ab69b884a9325bebdd07b2c4fd35
+ return main;
+ }
+
const defaultType = getOptionValue('--experimental-default-type');
/** @type {string} */
let mainPath;
@@ -62,6 +70,13 @@ function resolveMainPath(main) {
* @param {string} mainPath - Absolute path to the main entry point
// Extension searching for the main entry point is supported for backward compatibility.
@@ -50,6 +58,13 @@ function resolveMainPath(main) {
* @returns {boolean}
*/
function shouldUseESMLoader(mainPath) {
+ // For built-in modules used as the main entry point we _never_
@@ -57,6 +57,6 @@ index 02ba43adc2c8e92a78942bbb04023a16f5870ee9..bbf1ab69b884a9325bebdd07b2c4fd35
+ return false;
+ }
+
if (getOptionValue('--experimental-default-type') === 'module') { return true; }
/**
* @type {string[]} userLoaders A list of custom loaders registered by the user
* (or an empty list when none have been registered).

View File

@@ -8,10 +8,10 @@ resource path. This commit ensures that the TraverseParent function
bails out if the parent path is outside of the resource path.
diff --git a/src/node_modules.cc b/src/node_modules.cc
index 55d628f0c5e7f330e548878807de26d51ef025b5..c06779dea471b6f6a8dd29d4657162ef0faec043 100644
index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..b93ccedaf703f86ae2092c304785394c471d520c 100644
--- a/src/node_modules.cc
+++ b/src/node_modules.cc
@@ -291,8 +291,41 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
@@ -284,8 +284,41 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
Realm* realm, const std::filesystem::path& check_path) {
std::filesystem::path current_path = check_path;
auto env = realm->env();
@@ -53,7 +53,7 @@ index 55d628f0c5e7f330e548878807de26d51ef025b5..c06779dea471b6f6a8dd29d4657162ef
do {
current_path = current_path.parent_path();
@@ -311,6 +344,12 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
@@ -304,6 +337,12 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
return nullptr;
}

View File

@@ -8,10 +8,10 @@ an API override to replace the native `ReadFileSync` in the `modules`
binding.
diff --git a/src/env_properties.h b/src/env_properties.h
index 82225b0a53dd828750991a4e15a060b736b6ea2b..4b0d31356a2496a7fc67876a22da2453efc54f53 100644
index 2884149d82d180e0d2ecfa7ac8fd92f201f1cb55..dded4bf3d7106d127efbad81087f0c375b2b2c95 100644
--- a/src/env_properties.h
+++ b/src/env_properties.h
@@ -508,6 +508,7 @@
@@ -490,6 +490,7 @@
V(maybe_cache_generated_source_map, v8::Function) \
V(messaging_deserialize_create_object, v8::Function) \
V(message_port, v8::Object) \
@@ -20,18 +20,18 @@ index 82225b0a53dd828750991a4e15a060b736b6ea2b..4b0d31356a2496a7fc67876a22da2453
V(performance_entry_callback, v8::Function) \
V(prepare_stack_trace_callback, v8::Function) \
diff --git a/src/node_modules.cc b/src/node_modules.cc
index c06779dea471b6f6a8dd29d4657162ef0faec043..6204986dc97686a248d6ae483f3a413ee5c51e47 100644
index b93ccedaf703f86ae2092c304785394c471d520c..bdbc511ef3f680bbac6770b89f47acaee95d56a2 100644
--- a/src/node_modules.cc
+++ b/src/node_modules.cc
@@ -21,6 +21,7 @@ namespace modules {
@@ -23,6 +23,7 @@ namespace modules {
using v8::Array;
using v8::Context;
using v8::External;
+using v8::Function;
using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Isolate;
@@ -89,6 +90,7 @@ Local<Array> BindingData::PackageConfig::Serialize(Realm* realm) const {
using v8::Integer;
@@ -94,6 +95,7 @@ Local<Array> BindingData::PackageConfig::Serialize(Realm* realm) const {
const BindingData::PackageConfig* BindingData::GetPackageJSON(
Realm* realm, std::string_view path, ErrorContext* error_context) {
@@ -39,7 +39,7 @@ index c06779dea471b6f6a8dd29d4657162ef0faec043..6204986dc97686a248d6ae483f3a413e
auto binding_data = realm->GetBindingData<BindingData>();
auto cache_entry = binding_data->package_configs_.find(path.data());
@@ -98,8 +100,36 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
@@ -103,8 +105,36 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
PackageConfig package_config{};
package_config.file_path = path;
@@ -76,8 +76,8 @@ index c06779dea471b6f6a8dd29d4657162ef0faec043..6204986dc97686a248d6ae483f3a413e
+ if (read_err < 0) {
return nullptr;
}
// In some systems, std::string is annotated to generate an
@@ -249,6 +279,12 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
simdjson::ondemand::document document;
@@ -242,6 +272,12 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
return &cached.first->second;
}
@@ -90,7 +90,7 @@ index c06779dea471b6f6a8dd29d4657162ef0faec043..6204986dc97686a248d6ae483f3a413e
void BindingData::ReadPackageJSON(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1); // path, [is_esm, base, specifier]
CHECK(args[0]->IsString()); // path
@@ -643,6 +679,8 @@ void InitImportMetaPathHelpers(const FunctionCallbackInfo<Value>& args) {
@@ -674,6 +710,8 @@ void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();
@@ -99,7 +99,7 @@ index c06779dea471b6f6a8dd29d4657162ef0faec043..6204986dc97686a248d6ae483f3a413e
SetMethod(isolate, target, "readPackageJSON", ReadPackageJSON);
SetMethod(isolate,
target,
@@ -685,6 +723,8 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
@@ -733,6 +771,8 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
void BindingData::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
@@ -107,9 +107,9 @@ index c06779dea471b6f6a8dd29d4657162ef0faec043..6204986dc97686a248d6ae483f3a413e
+
registry->Register(ReadPackageJSON);
registry->Register(GetNearestParentPackageJSONType);
registry->Register(GetNearestParentPackageJSON);
registry->Register(GetPackageScopeConfig<false>);
diff --git a/src/node_modules.h b/src/node_modules.h
index eb2900d8f8385238f89a6dcc972a28e5fcb1d288..e28f38d98f4f8749048af135f0dcbe55aa69c4fe 100644
index e4ba6b75bc86d14deada835903ba68a4cb0eccc5..ae77f9ec81b358bd356993617cd07671d382e8ca 100644
--- a/src/node_modules.h
+++ b/src/node_modules.h
@@ -54,6 +54,8 @@ class BindingData : public SnapshotableObject {
@@ -119,5 +119,5 @@ index eb2900d8f8385238f89a6dcc972a28e5fcb1d288..e28f38d98f4f8749048af135f0dcbe55
+ static void OverrideReadFileSync(
+ const v8::FunctionCallbackInfo<v8::Value>& args);
static void ReadPackageJSON(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetNearestParentPackageJSON(
static void GetNearestParentPackageJSONType(
const v8::FunctionCallbackInfo<v8::Value>& args);

View File

@@ -6,7 +6,7 @@ Subject: fix: expose the built-in electron module via the ESM loader
This allows usage of `import { app } from 'electron'` and `import('electron')` natively in the browser + non-sandboxed renderer
diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js
index 9519f947b8dfdc69808839948c9cb8434a0acf0e..23ce72d479f638c33edffcea7c35f5da6cab7cae 100644
index 01584983c16a2ab6eec2fbb01208504f2771148b..6afbbca6c95103f3ecad29485581c94735bac0d3 100644
--- a/lib/internal/modules/esm/get_format.js
+++ b/lib/internal/modules/esm/get_format.js
@@ -26,6 +26,7 @@ const protocolHandlers = {
@@ -18,10 +18,10 @@ index 9519f947b8dfdc69808839948c9cb8434a0acf0e..23ce72d479f638c33edffcea7c35f5da
/**
diff --git a/lib/internal/modules/esm/load.js b/lib/internal/modules/esm/load.js
index 307c35980551470b65128bebf5efe94df4e56892..3676a9852bcd42de0a3a380de117de58035f757b 100644
index 8414d303c078d51a93c9127a1fd8d6f24961b104..e8a2326e158550786620439fa4039c2b449624cc 100644
--- a/lib/internal/modules/esm/load.js
+++ b/lib/internal/modules/esm/load.js
@@ -81,7 +81,7 @@ function defaultLoad(url, context = kEmptyObject) {
@@ -77,7 +77,7 @@ function defaultLoad(url, context = kEmptyObject) {
throwIfUnsupportedURLScheme(urlInstance);
@@ -30,7 +30,7 @@ index 307c35980551470b65128bebf5efe94df4e56892..3676a9852bcd42de0a3a380de117de58
source = null;
format ??= 'builtin';
} else if (format === 'addon') {
@@ -97,7 +97,7 @@ function defaultLoad(url, context = kEmptyObject) {
@@ -93,7 +93,7 @@ function defaultLoad(url, context = kEmptyObject) {
// Now that we have the source for the module, run `defaultGetFormat` to detect its format.
format = defaultGetFormat(urlInstance, context);
@@ -39,7 +39,7 @@ index 307c35980551470b65128bebf5efe94df4e56892..3676a9852bcd42de0a3a380de117de58
// For backward compatibility reasons, we need to discard the source in
// order for the CJS loader to re-fetch it.
source = null;
@@ -145,7 +145,7 @@ function defaultLoadSync(url, context = kEmptyObject) {
@@ -141,7 +141,7 @@ function defaultLoadSync(url, context = kEmptyObject) {
throwIfUnsupportedURLScheme(urlInstance, false);
@@ -48,7 +48,7 @@ index 307c35980551470b65128bebf5efe94df4e56892..3676a9852bcd42de0a3a380de117de58
source = null;
} else if (source == null) {
({ responseURL, source } = getSourceSync(urlInstance, context));
@@ -178,12 +178,13 @@ function throwIfUnsupportedURLScheme(parsed) {
@@ -174,12 +174,13 @@ function throwIfUnsupportedURLScheme(parsed) {
protocol !== 'file:' &&
protocol !== 'data:' &&
protocol !== 'node:' &&
@@ -64,10 +64,10 @@ index 307c35980551470b65128bebf5efe94df4e56892..3676a9852bcd42de0a3a380de117de58
}
}
diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js
index 78985575beb3df7722ba90968e8f085574b5afdf..e032c016efe227c26364e81804ad183cd2c0d17f 100644
index 300da51afe6185f5f9799a88fc75ba3b8f0cf5fb..4c7e2dc8c00c7a38a27169d1cc08e27f89e74fbb 100644
--- a/lib/internal/modules/esm/loader.js
+++ b/lib/internal/modules/esm/loader.js
@@ -504,7 +504,7 @@ class ModuleLoader {
@@ -522,7 +522,7 @@ class ModuleLoader {
}
const cjsModule = wrap[imported_cjs_symbol];
@@ -77,10 +77,10 @@ index 78985575beb3df7722ba90968e8f085574b5afdf..e032c016efe227c26364e81804ad183c
// Check if the ESM initiating import CJS is being required by the same CJS module.
if (cjsModule?.[kIsExecuting]) {
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index 859b6bfedac4bbee2df054f9ebca7cbaaed45f18..5aa946f66c71beff0b7a43c30638ab28a1a5dfc0 100644
index c27ee4c6612c6a7ea0b6355f03563e8724fd0e40..5f03cf14e948d449d303b22ab6710b5508fb83b2 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -750,6 +750,9 @@ function packageImportsResolve(name, base, conditions) {
@@ -751,6 +751,9 @@ function packageImportsResolve(name, base, conditions) {
throw importNotDefined(name, packageJSONUrl, base);
}
@@ -90,7 +90,7 @@ index 859b6bfedac4bbee2df054f9ebca7cbaaed45f18..5aa946f66c71beff0b7a43c30638ab28
/**
* Resolves a package specifier to a URL.
@@ -764,6 +767,11 @@ function packageResolve(specifier, base, conditions) {
@@ -765,6 +768,11 @@ function packageResolve(specifier, base, conditions) {
return new URL('node:' + specifier);
}
@@ -103,30 +103,21 @@ index 859b6bfedac4bbee2df054f9ebca7cbaaed45f18..5aa946f66c71beff0b7a43c30638ab28
const packageConfig = packageJsonReader.read(packageJSONPath, { __proto__: null, specifier, base, isESM: true });
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index 757f093becd112002f3422302f4c29bb464f1a6c..c8cea2117080930105b33e4e50586a2c88ef7352 100644
index 147d96bda8098fe16e5d0053e36eab05fb489c22..3c82913ca381eba30596f22a734b49dcba9b6f5b 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -188,7 +188,7 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul
@@ -215,7 +215,9 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul
const { exportNames, module } = cjsPreparseModuleExports(filename, source, format);
cjsCache.set(url, module);
- const namesWithDefault = exportNames.has('default') ?
+ const namesWithDefault = filename === 'electron' ? ['default', ...Object.keys(module.exports)] : exportNames.has('default') ?
[...exportNames] : ['default', ...exportNames];
if (isMain) {
@@ -210,8 +210,8 @@ function createCJSModuleWrap(url, source, isMain, format, loadCJS = loadCJSModul
({ exports } = module);
}
for (const exportName of exportNames) {
- if (!ObjectPrototypeHasOwnProperty(exports, exportName) ||
- exportName === 'default') {
+ if (exportName === 'default' ||
+ !ObjectPrototypeHasOwnProperty(exports, exportName)) {
continue;
}
// We might trigger a getter -> dont fail.
@@ -286,6 +286,10 @@ translators.set('require-commonjs', (url, source, isMain) => {
- const wrapperNames = [...exportNames];
+ const wrapperNames = filename === 'electron' ?
+ ['default', ...Object.keys(module.exports)] :
+ [...exportNames];
if (!exportNames.has('default')) {
ArrayPrototypePush(wrapperNames, 'default');
}
@@ -319,6 +321,10 @@ translators.set('require-commonjs', (url, source, isMain) => {
return createCJSModuleWrap(url, source, isMain, 'commonjs');
});
@@ -138,10 +129,10 @@ index 757f093becd112002f3422302f4c29bb464f1a6c..c8cea2117080930105b33e4e50586a2c
// This translator function must be sync, as `require` is sync.
translators.set('require-commonjs-typescript', (url, source, isMain) => {
diff --git a/lib/internal/url.js b/lib/internal/url.js
index d0c04be7c6ebc352d5958a987f3a4ba538e0d23a..00f9f3b73ed84c04ae712f6057b68737bd416333 100644
index a1473fdac8aba3be541df3b6688a05c0dfbe403f..0a87d997856ea227f8f21393909ffc4634043f24 100644
--- a/lib/internal/url.js
+++ b/lib/internal/url.js
@@ -1605,6 +1605,8 @@ function fileURLToPath(path, options = kEmptyObject) {
@@ -1609,6 +1609,8 @@ function fileURLToPath(path, options = kEmptyObject) {
path = new URL(path);
else if (!isURL(path))
throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);

View File

@@ -17,160 +17,82 @@ Upstreams:
- https://github.com/nodejs/node/pull/39136
diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc
index 6f9406eecacb7411a2e84a7b51e60b726d1961f3..a0cfb0bc3776dc3682cdb332ed418286d3243bd1 100644
index e1c2da6969a1ce937d397735e844930f3234bba7..0bed152014949c22b6c610198df39a2522890279 100644
--- a/deps/ncrypto/ncrypto.cc
+++ b/deps/ncrypto/ncrypto.cc
@@ -786,7 +786,7 @@ bool SafeX509SubjectAltNamePrint(const BIOPointer& out, X509_EXTENSION* ext) {
bool ok = true;
- for (int i = 0; i < sk_GENERAL_NAME_num(names); i++) {
+ for (size_t i = 0; i < sk_GENERAL_NAME_num(names); i++) {
GENERAL_NAME* gen = sk_GENERAL_NAME_value(names, i);
if (i != 0) BIO_write(out.get(), ", ", 2);
@@ -810,7 +810,7 @@ bool SafeX509InfoAccessPrint(const BIOPointer& out, X509_EXTENSION* ext) {
bool ok = true;
- for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(descs); i++) {
+ for (size_t i = 0; i < sk_ACCESS_DESCRIPTION_num(descs); i++) {
ACCESS_DESCRIPTION* desc = sk_ACCESS_DESCRIPTION_value(descs, i);
if (i != 0) BIO_write(out.get(), "\n", 1);
@@ -952,13 +952,17 @@ BIOPointer X509View::getValidTo() const {
int64_t X509View::getValidToTime() const {
@@ -11,6 +11,7 @@
#include <array>
#include <cstring>
#include <string_view>
+#include <vector>
#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/core_names.h>
#include <openssl/params.h>
@@ -1130,7 +1131,9 @@ int64_t X509View::getValidToTime() const {
return tp;
#else
struct tm tp;
- ASN1_TIME_to_tm(X509_get0_notAfter(cert_), &tp);
+#ifndef OPENSSL_IS_BORINGSSL
+ ASN1_TIME_to_tm(X509_get0_notAfter(cert_), &tp);
+#endif
return PortableTimeGM(&tp);
#endif
}
int64_t X509View::getValidFromTime() const {
@@ -1142,7 +1145,9 @@ int64_t X509View::getValidFromTime() const {
return tp;
#else
struct tm tp;
+#ifndef OPENSSL_IS_BORINGSSL
ASN1_TIME_to_tm(X509_get0_notBefore(cert_), &tp);
+#endif
return PortableTimeGM(&tp);
#endif
}
@@ -1233,7 +1237,11 @@ BIOPointer BIOPointer::NewMem() {
}
BIOPointer BIOPointer::NewSecMem() {
- return BIOPointer(BIO_new(BIO_s_secmem()));
+#ifdef OPENSSL_IS_BORINGSSL
+ return BIOPointer(BIO_new(BIO_s_mem()));
+#else
+ return BIOPointer(BIO_new(BIO_s_secmem()));
+#endif
}
BIOPointer BIOPointer::New(const BIO_METHOD* method) {
@@ -1303,8 +1311,10 @@ BignumPointer DHPointer::FindGroup(const std::string_view name,
#define V(n, p) \
if (EqualNoCase(name, n)) return BignumPointer(p(nullptr));
if (option != FindGroupOption::NO_SMALL_PRIMES) {
+#ifndef OPENSSL_IS_BORINGSSL
V("modp1", BN_get_rfc2409_prime_768);
V("modp2", BN_get_rfc2409_prime_1024);
+#endif
V("modp5", BN_get_rfc3526_prime_1536);
}
V("modp14", BN_get_rfc3526_prime_2048);
@@ -1380,11 +1390,13 @@ DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey(
int codes = 0;
if (DH_check_pub_key(dh_.get(), pub_key.get(), &codes) != 1)
return DHPointer::CheckPublicKeyResult::CHECK_FAILED;
+#ifndef OPENSSL_IS_BORINGSSL
if (codes & DH_CHECK_PUBKEY_TOO_SMALL) {
return DHPointer::CheckPublicKeyResult::TOO_SMALL;
} else if (codes & DH_CHECK_PUBKEY_TOO_SMALL) {
return DHPointer::CheckPublicKeyResult::TOO_LARGE;
- } else if (codes != 0) {
+#endif
+ if (codes != 0) {
return DHPointer::CheckPublicKeyResult::INVALID;
}
return CheckPublicKeyResult::NONE;
@@ -2327,7 +2339,7 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
const unsigned char* buf;
size_t len;
size_t rem;
@@ -2886,10 +2891,6 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
const char* SSLPointer::getClientHelloAlpn() const {
if (ssl_ == nullptr) return {};
#ifndef OPENSSL_IS_BORINGSSL
- const unsigned char* buf;
- size_t len;
- size_t rem;
-
+#ifndef OPENSSL_IS_BORINGSSL
if (!SSL_client_hello_get0_ext(
get(),
TLSEXT_TYPE_application_layer_protocol_negotiation,
@@ -2340,6 +2352,8 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
len = (buf[0] << 8) | buf[1];
if (len + 2 != rem) return {};
return reinterpret_cast<const char*>(buf + 3);
+#endif
+ return {};
}
const std::string_view SSLPointer::getClientHelloServerName() const {
@@ -2347,7 +2361,7 @@ const std::string_view SSLPointer::getClientHelloServerName() const {
const unsigned char* buf;
size_t len;
size_t rem;
-
@@ -3090,9 +3091,11 @@ const Cipher Cipher::AES_256_GCM = Cipher::FromNid(NID_aes_256_gcm);
const Cipher Cipher::AES_128_KW = Cipher::FromNid(NID_id_aes128_wrap);
const Cipher Cipher::AES_192_KW = Cipher::FromNid(NID_id_aes192_wrap);
const Cipher Cipher::AES_256_KW = Cipher::FromNid(NID_id_aes256_wrap);
+#ifndef OPENSSL_IS_BORINGSSL
if (!SSL_client_hello_get0_ext(get(), TLSEXT_TYPE_server_name, &buf, &rem) ||
rem <= 2) {
return {};
@@ -2363,6 +2377,8 @@ const std::string_view SSLPointer::getClientHelloServerName() const {
len = (*(buf + 3) << 8) | *(buf + 4);
if (len + 2 > rem) return {};
return reinterpret_cast<const char*>(buf + 5);
const Cipher Cipher::AES_128_OCB = Cipher::FromNid(NID_aes_128_ocb);
const Cipher Cipher::AES_192_OCB = Cipher::FromNid(NID_aes_192_ocb);
const Cipher Cipher::AES_256_OCB = Cipher::FromNid(NID_aes_256_ocb);
+#endif
+ return {};
}
const Cipher Cipher::CHACHA20_POLY1305 = Cipher::FromNid(NID_chacha20_poly1305);
std::optional<const std::string_view> SSLPointer::GetServerName(
@@ -2396,8 +2412,11 @@ bool SSLPointer::isServer() const {
EVPKeyPointer SSLPointer::getPeerTempKey() const {
if (!ssl_) return {};
EVP_PKEY* raw_key = nullptr;
+#ifndef OPENSSL_IS_BORINGSSL
if (!SSL_get_peer_tmp_key(get(), &raw_key)) return {};
return EVPKeyPointer(raw_key);
+#endif
+ return {};
}
SSLCtxPointer::SSLCtxPointer(SSL_CTX* ctx) : ctx_(ctx) {}
bool Cipher::isGcmMode() const {
diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h
index e5bf2b529bf23914677e25d7468aad58a4684557..9a3c6029ff3319cce58c79782a7bd5d1fcd467f9 100644
index 175ec8ba0f2a908ffad2ce48434aeed573b09c90..3218590ddce1e92c2a9d776f20f9fb016612061d 100644
--- a/deps/ncrypto/ncrypto.h
+++ b/deps/ncrypto/ncrypto.h
@@ -623,17 +623,21 @@ class DHPointer final {
UNABLE_TO_CHECK_GENERATOR = DH_UNABLE_TO_CHECK_GENERATOR,
NOT_SUITABLE_GENERATOR = DH_NOT_SUITABLE_GENERATOR,
Q_NOT_PRIME = DH_CHECK_Q_NOT_PRIME,
@@ -306,9 +306,13 @@ class Cipher final {
#else
static constexpr size_t MAX_AUTH_TAG_LENGTH = 16;
#endif
- static_assert(EVP_GCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH &&
- EVP_CCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH &&
- EVP_CHACHAPOLY_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH);
+ static_assert(EVP_GCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH
+#ifndef OPENSSL_IS_BORINGSSL
INVALID_Q = DH_CHECK_INVALID_Q_VALUE,
INVALID_J = DH_CHECK_INVALID_J_VALUE,
+ && EVP_CCM_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH
+ && EVP_CHACHAPOLY_TLS_TAG_LEN <= MAX_AUTH_TAG_LENGTH);
+#else
+ );
+#endif
CHECK_FAILED = 512,
};
CheckResult check();
enum class CheckPublicKeyResult {
NONE,
+#ifndef OPENSSL_IS_BORINGSSL
TOO_SMALL = DH_R_CHECK_PUBKEY_TOO_SMALL,
TOO_LARGE = DH_R_CHECK_PUBKEY_TOO_LARGE,
- INVALID = DH_R_CHECK_PUBKEY_INVALID,
+#endif
+ INVALID = DH_R_INVALID_PUBKEY,
CHECK_FAILED = 512,
};
// Check to see if the given public key is suitable for this DH instance.
Cipher() = default;
Cipher(const EVP_CIPHER* cipher) : cipher_(cipher) {}
diff --git a/node.gni b/node.gni
index e2407027ab05e59b2f0f1c213b98ea469db7a91b..c64761b730e61edcdc0e46a48699f2fd5bb1c0a6 100644
--- a/node.gni
@@ -185,31 +107,32 @@ index e2407027ab05e59b2f0f1c213b98ea469db7a91b..c64761b730e61edcdc0e46a48699f2fd
# The location of simdutf - use the one from node's deps by default.
node_simdutf_path = "//third_party/simdutf"
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
index 2176fb6982484e2c42538478eeb4dd81c9d50ee1..c00d3616e08b00b1e0a3a29b2dbb5278e1e14fcc 100644
index 5ed2f8b35a1e2f8348a0f3891f37944f49371256..bd453ae633b2833cc3c6e3e415b43792dc5bf2e5 100644
--- a/src/crypto/crypto_cipher.cc
+++ b/src/crypto/crypto_cipher.cc
@@ -1027,7 +1027,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
return ThrowCryptoError(env, ERR_get_error());
@@ -447,6 +447,7 @@ bool CipherBase::InitAuthenticated(const char* cipher_type,
}
-
} else {
if (auth_tag_len == kNoAuthTagLength) {
+#ifndef OPENSSL_IS_BORINGSSL
int rsa_pkcs1_implicit_rejection =
EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
// From the doc -2 means that the option is not supported.
@@ -1042,6 +1042,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
env,
"RSA_PKCS1_PADDING is no longer supported for private decryption");
}
// We treat ChaCha20-Poly1305 specially. Like GCM, the authentication tag
// length defaults to 16 bytes when encrypting. Unlike GCM, the
// authentication tag length also defaults to 16 bytes when decrypting,
@@ -458,6 +459,9 @@ bool CipherBase::InitAuthenticated(const char* cipher_type,
env(), "authTagLength required for %s", cipher_type);
return false;
}
+#else
+ return false;
+#endif
}
}
const EVP_MD* digest = nullptr;
// TODO(tniessen) Support CCM decryption in FIPS mode
diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc
index d94f6e1c82c4a62547b3b395f375c86ce4deb5de..b81b9005365272217c77e2b9289bd9f877c0e77c 100644
index d005bf0ffb93445fa6611a1beb1b465764271ede..01770687bd191c61af02e76d7de24bbac5c47b8f 100644
--- a/src/crypto/crypto_common.cc
+++ b/src/crypto/crypto_common.cc
@@ -124,7 +124,7 @@ StackOfX509 CloneSSLCerts(X509Pointer&& cert,
@@ -90,7 +90,7 @@ StackOfX509 CloneSSLCerts(X509Pointer&& cert,
if (!peer_certs) return StackOfX509();
if (cert && !sk_X509_push(peer_certs.get(), cert.release()))
return StackOfX509();
@@ -218,7 +141,7 @@ index d94f6e1c82c4a62547b3b395f375c86ce4deb5de..b81b9005365272217c77e2b9289bd9f8
X509Pointer cert(X509_dup(sk_X509_value(ssl_certs, i)));
if (!cert || !sk_X509_push(peer_certs.get(), cert.get()))
return StackOfX509();
@@ -140,7 +140,7 @@ MaybeLocal<Object> AddIssuerChainToObject(X509Pointer* cert,
@@ -106,7 +106,7 @@ MaybeLocal<Object> AddIssuerChainToObject(X509Pointer* cert,
Environment* const env) {
cert->reset(sk_X509_delete(peer_certs.get(), 0));
for (;;) {
@@ -228,10 +151,10 @@ index d94f6e1c82c4a62547b3b395f375c86ce4deb5de..b81b9005365272217c77e2b9289bd9f8
X509View ca(sk_X509_value(peer_certs.get(), i));
if (!cert->view().isIssuedBy(ca)) continue;
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index c08dab17fa229d1d67d3ad5174c97192989b2bd0..a3d309d832c73ddc79564b9644d825bec7459e7f 100644
index 6482bd58bb6a95cfa4074ea9535e1443aea66bb5..20d3c1d9d17fde18fc09b6ee219137831eb08a45 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -141,7 +141,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
@@ -143,7 +143,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
// the CA certificates.
SSL_CTX_clear_extra_chain_certs(ctx);
@@ -240,7 +163,7 @@ index c08dab17fa229d1d67d3ad5174c97192989b2bd0..a3d309d832c73ddc79564b9644d825be
X509* ca = sk_X509_value(extra_certs, i);
// NOTE: Increments reference count on `ca`
@@ -1773,11 +1773,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
@@ -1831,11 +1831,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
// If the user specified "auto" for dhparams, the JavaScript layer will pass
// true to this function instead of the original string. Any other string
// value will be interpreted as custom DH parameters below.
@@ -254,7 +177,7 @@ index c08dab17fa229d1d67d3ad5174c97192989b2bd0..a3d309d832c73ddc79564b9644d825be
DHPointer dh;
{
BIOPointer bio(LoadBIO(env, args[0]));
@@ -2003,7 +2004,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
@@ -2061,7 +2062,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
}
// Add CA certs too
@@ -264,71 +187,10 @@ index c08dab17fa229d1d67d3ad5174c97192989b2bd0..a3d309d832c73ddc79564b9644d825be
X509_STORE_add_cert(sc->GetCertStoreOwnedByThisSecureContext(), ca);
diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc
index c26a88b395abfc645da56231635b36fb23c8fa09..f23cedf4f2449d8edc9a8de1b70332e75d693cdd 100644
index e35fda9ad2e8c52c75492d66566dc6e6c57dd2ae..46a7d1396dc1a175ae99f4e403721f1730fdd320 100644
--- a/src/crypto/crypto_dh.cc
+++ b/src/crypto/crypto_dh.cc
@@ -7,7 +7,9 @@
#include "memory_tracker-inl.h"
#include "ncrypto.h"
#include "node_errors.h"
+#ifndef OPENSSL_IS_BORINGSSL
#include "openssl/bnerr.h"
+#endif
#include "openssl/dh.h"
#include "threadpoolwork-inl.h"
#include "v8.h"
@@ -88,11 +90,7 @@ void New(const FunctionCallbackInfo<Value>& args) {
if (args[0]->IsInt32()) {
int32_t bits = args[0].As<Int32>()->Value();
if (bits < 2) {
-#if OPENSSL_VERSION_MAJOR >= 3
- ERR_put_error(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_SMALL, __FILE__, __LINE__);
-#else
- ERR_put_error(ERR_LIB_BN, 0, BN_R_BITS_TOO_SMALL, __FILE__, __LINE__);
-#endif
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return ThrowCryptoError(env, ERR_get_error(), "Invalid prime length");
}
@@ -105,7 +103,7 @@ void New(const FunctionCallbackInfo<Value>& args) {
}
int32_t generator = args[1].As<Int32>()->Value();
if (generator < 2) {
- ERR_put_error(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return ThrowCryptoError(env, ERR_get_error(), "Invalid generator");
}
@@ -134,12 +132,12 @@ void New(const FunctionCallbackInfo<Value>& args) {
if (args[1]->IsInt32()) {
int32_t generator = args[1].As<Int32>()->Value();
if (generator < 2) {
- ERR_put_error(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return ThrowCryptoError(env, ERR_get_error(), "Invalid generator");
}
bn_g = BignumPointer::New();
if (!bn_g.setWord(generator)) {
- ERR_put_error(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return ThrowCryptoError(env, ERR_get_error(), "Invalid generator");
}
} else {
@@ -148,11 +146,11 @@ void New(const FunctionCallbackInfo<Value>& args) {
return THROW_ERR_OUT_OF_RANGE(env, "generator is too big");
bn_g = BignumPointer(reinterpret_cast<uint8_t*>(arg1.data()), arg1.size());
if (!bn_g) {
- ERR_put_error(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return ThrowCryptoError(env, ERR_get_error(), "Invalid generator");
}
if (bn_g.getWord() < 2) {
- ERR_put_error(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return ThrowCryptoError(env, ERR_get_error(), "Invalid generator");
}
}
@@ -260,15 +258,17 @@ void ComputeSecret(const FunctionCallbackInfo<Value>& args) {
@@ -309,15 +309,17 @@ void ComputeSecret(const FunctionCallbackInfo<Value>& args) {
BignumPointer key(key_buf.data(), key_buf.size());
switch (dh.checkPublicKey(key)) {
@@ -348,58 +210,24 @@ index c26a88b395abfc645da56231635b36fb23c8fa09..f23cedf4f2449d8edc9a8de1b70332e7
case DHPointer::CheckPublicKeyResult::NONE:
break;
}
@@ -400,9 +400,11 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
key_params = EVPKeyPointer::New();
CHECK(key_params);
CHECK_EQ(EVP_PKEY_assign_DH(key_params.get(), dh.release()), 1);
- } else if (int* prime_size = std::get_if<int>(&params->params.prime)) {
+ } else if (std::get_if<int>(&params->params.prime)) {
EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DH, nullptr));
EVP_PKEY* raw_params = nullptr;
+#ifndef OPENSSL_IS_BORINGSSL
+ int* prime_size = std::get_if<int>(&params->params.prime);
if (!param_ctx ||
EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
EVP_PKEY_CTX_set_dh_paramgen_prime_len(
@@ -416,6 +418,9 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
}
diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc
index 33cde71b105c7cf22b559583d2e46bfb50016f6d..659910992dff7c05bb7e367e1cba14256b46dea4 100644
--- a/src/crypto/crypto_hash.cc
+++ b/src/crypto/crypto_hash.cc
@@ -232,7 +232,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
enum encoding output_enc = ParseEncoding(isolate, args[4], args[5], HEX);
key_params = EVPKeyPointer(raw_params);
+#else
+ return EVPKeyCtxPointer();
+#endif
} else {
UNREACHABLE();
}
diff --git a/src/crypto/crypto_dsa.cc b/src/crypto/crypto_dsa.cc
index ca5edc8ebdf2550bb62b7969a5650733a2647f4f..198e18b58f31e361a9d2865cbe81e067e5f0b543 100644
--- a/src/crypto/crypto_dsa.cc
+++ b/src/crypto/crypto_dsa.cc
@@ -43,7 +43,7 @@ namespace crypto {
EVPKeyCtxPointer DsaKeyGenTraits::Setup(DsaKeyPairGenConfig* params) {
EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, nullptr));
EVP_PKEY* raw_params = nullptr;
-
+#ifndef OPENSSL_IS_BORINGSSL
if (!param_ctx ||
EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
EVP_PKEY_CTX_set_dsa_paramgen_bits(
@@ -58,7 +58,9 @@ EVPKeyCtxPointer DsaKeyGenTraits::Setup(DsaKeyPairGenConfig* params) {
return EVPKeyCtxPointer();
}
}
-
+#else
+ return EVPKeyCtxPointer();
+#endif
if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
return EVPKeyCtxPointer();
bool is_xof = (EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0;
- int output_length = EVP_MD_size(md);
+ size_t output_length = EVP_MD_size(md);
// This is to cause hash() to fail when an incorrect
// outputLength option was passed for a non-XOF hash function.
diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc
index 7238cda445fd663e6b45fa134f31d017bb267dfc..522655555cdb2ab2083797f736bf167d1f42c15e 100644
index e805a984322c8348ceba950fe6f45e002ade10b3..bb9b1f8e1b3c6dd8479ee463e303088e3240d6be 100644
--- a/src/crypto/crypto_keys.cc
+++ b/src/crypto/crypto_keys.cc
@@ -949,6 +949,7 @@ void KeyObjectHandle::GetAsymmetricKeyType(
@@ -1034,6 +1034,7 @@ void KeyObjectHandle::GetAsymmetricKeyType(
}
bool KeyObjectHandle::CheckEcKeyData() const {
@@ -407,62 +235,21 @@ index 7238cda445fd663e6b45fa134f31d017bb267dfc..522655555cdb2ab2083797f736bf167d
MarkPopErrorOnReturn mark_pop_error_on_return;
const auto& key = data_.GetAsymmetricKey();
@@ -965,6 +966,9 @@ bool KeyObjectHandle::CheckEcKeyData() const {
#else
return EVP_PKEY_public_check(ctx.get()) == 1;
#endif
@@ -1043,6 +1044,9 @@ bool KeyObjectHandle::CheckEcKeyData() const {
return data_.GetKeyType() == kKeyTypePrivate ? ctx.privateCheck()
: ctx.publicCheck();
+#else
+ return true;
+#endif
}
void KeyObjectHandle::CheckEcKeyData(const FunctionCallbackInfo<Value>& args) {
diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc
index 78f2093d1d010be6f9c492662f4f582657ff6a13..b6aef7fd27cd974697bcee05955bfd9ccf4d5837 100644
--- a/src/crypto/crypto_random.cc
+++ b/src/crypto/crypto_random.cc
@@ -143,7 +143,7 @@ Maybe<void> RandomPrimeTraits::AdditionalConfig(
params->bits = bits;
params->safe = safe;
- params->prime = BignumPointer::NewSecure();
+ params->prime = BignumPointer::New();
if (!params->prime) {
THROW_ERR_CRYPTO_OPERATION_FAILED(env, "could not generate prime");
return Nothing<void>();
diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc
index 05a3882c7e17d78e27aabb29891aa250789a47c0..1f2fccce6ed8f14525557644e0bdd130eedf3337 100644
--- a/src/crypto/crypto_rsa.cc
+++ b/src/crypto/crypto_rsa.cc
@@ -612,10 +612,13 @@ Maybe<void> GetRsaKeyDetail(Environment* env,
}
if (params->saltLength != nullptr) {
+#ifndef OPENSSL_IS_BORINGSSL
+ // TODO(codebytere): Upstream a shim to BoringSSL?
if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error");
return Nothing<void>();
}
+#endif
}
if (target
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index 7c548d32b40365343f0e208c3aa856a1c847f4c3..6346f8f7199cf7b7d3736c59571606fff102fbb6 100644
index 205e248e0f20f019e189a6c69d3c011a616b3939..12b0d804c6f1d4998b85160b0aac8eb7a3b5576b 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -207,7 +207,8 @@ void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) {
void GetOpenSSLSecLevelCrypto(const FunctionCallbackInfo<Value>& args) {
// for BoringSSL assume the same as the default
- int sec_level = OPENSSL_TLS_SECURITY_LEVEL;
+ // value of OPENSSL_TLS_SECURITY_LEVEL.
+ int sec_level = 1;
#ifndef OPENSSL_IS_BORINGSSL
Environment* env = Environment::GetCurrent(args);
@@ -527,24 +528,15 @@ Maybe<void> Decorate(Environment* env,
@@ -533,24 +533,15 @@ Maybe<void> Decorate(Environment* env,
V(BIO) \
V(PKCS7) \
V(X509V3) \
@@ -488,42 +275,11 @@ index 7c548d32b40365343f0e208c3aa856a1c847f4c3..6346f8f7199cf7b7d3736c59571606ff
V(USER) \
#define V(name) case ERR_LIB_##name: lib = #name "_"; break;
@@ -686,7 +678,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsUint32());
Environment* env = Environment::GetCurrent(args);
uint32_t len = args[0].As<Uint32>()->Value();
- void* data = OPENSSL_secure_zalloc(len);
+ void* data = OPENSSL_malloc(len);
if (data == nullptr) {
// There's no memory available for the allocation.
// Return nothing.
@@ -697,7 +689,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
data,
len,
[](void* data, size_t len, void* deleter_data) {
- OPENSSL_secure_clear_free(data, len);
+ OPENSSL_clear_free(data, len);
},
data);
Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
@@ -705,10 +697,12 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
}
void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {
+#ifndef OPENSSL_IS_BORINGSSL
Environment* env = Environment::GetCurrent(args);
if (CRYPTO_secure_malloc_initialized())
args.GetReturnValue().Set(
BigInt::New(env->isolate(), CRYPTO_secure_used()));
+#endif
}
} // namespace
diff --git a/src/env.h b/src/env.h
index 874e5f4d15a75307e45cf70c06fc104fed843a6a..35e16159a94bb97f19d17767e3ad4bb798660f44 100644
index f3a2d221f4bb52987e1bdacdadf19aacfcf65ec3..d34aec43630b3cf53004d8180446d7136b59ceac 100644
--- a/src/env.h
+++ b/src/env.h
@@ -51,7 +51,7 @@
@@ -52,7 +52,7 @@
#include "v8-profiler.h"
#include "v8.h"
@@ -532,7 +288,7 @@ index 874e5f4d15a75307e45cf70c06fc104fed843a6a..35e16159a94bb97f19d17767e3ad4bb7
#include <openssl/evp.h>
#endif
@@ -1077,7 +1077,7 @@ class Environment final : public MemoryRetainer {
@@ -1058,7 +1058,7 @@ class Environment final : public MemoryRetainer {
kExitInfoFieldCount
};
@@ -554,21 +310,8 @@ index d9c533f100d25aeab1fe8589932a8ddead431258..2acab8786a8a752b17961445edeb872c
#include <openssl/crypto.h>
#if NODE_OPENSSL_HAS_QUIC
#include <openssl/quic.h>
diff --git a/src/node_options.cc b/src/node_options.cc
index ed85bf11f6f325823b59b3b0275908f9210c1b24..e3509abbc3bf84ac0edcd495eb3dde6219dbfc2d 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -7,7 +7,7 @@
#include "node_external_reference.h"
#include "node_internals.h"
#include "node_sea.h"
-#if HAVE_OPENSSL
+#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
#include "openssl/opensslv.h"
#endif
diff --git a/src/node_options.h b/src/node_options.h
index cdbd9ca39e907ab22515293eac2c5512223f4ca2..418dee360f867c363f1576012b32213a51c4fdd0 100644
index 3a1503a035e12b5dce75c77c327607c857a8a367..941ae4f15c42fb8016d03c786973fd4709ac1a0d 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -11,7 +11,7 @@

View File

@@ -6,19 +6,19 @@ Subject: fix: lazyload fs in esm loaders to apply asar patches
Changes { foo } from fs to just "fs.foo" so that our patching of fs is applied to esm loaders
diff --git a/lib/internal/modules/esm/load.js b/lib/internal/modules/esm/load.js
index 3676a9852bcd42de0a3a380de117de58035f757b..eaecfcfd8b922908957c3fefea65fb9deb445249 100644
index e8a2326e158550786620439fa4039c2b449624cc..c17867136a07022a740d6bf957fe7a8138a48c11 100644
--- a/lib/internal/modules/esm/load.js
+++ b/lib/internal/modules/esm/load.js
@@ -10,7 +10,7 @@ const {
@@ -9,7 +9,7 @@ const {
const { defaultGetFormat } = require('internal/modules/esm/get_format');
const { validateAttributes, emitImportAssertionWarning } = require('internal/modules/esm/assert');
const { getOptionValue } = require('internal/options');
-const { readFileSync } = require('fs');
+const fs = require('fs');
const defaultType =
getOptionValue('--experimental-default-type');
@@ -38,7 +38,7 @@ function getSourceSync(url, context) {
const { Buffer: { from: BufferFrom } } = require('buffer');
@@ -34,7 +34,7 @@ function getSourceSync(url, context) {
const responseURL = href;
let source;
if (protocol === 'file:') {
@@ -28,7 +28,7 @@ index 3676a9852bcd42de0a3a380de117de58035f757b..eaecfcfd8b922908957c3fefea65fb9d
const result = dataURLProcessor(url);
if (result === 'failure') {
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index 5aa946f66c71beff0b7a43c30638ab28a1a5dfc0..e3afd30ba1f591d0298793bc42fd7166a4219bce 100644
index 5f03cf14e948d449d303b22ab6710b5508fb83b2..72cc9444ca93ef7a1526e23314693aeaf5f173b0 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -25,7 +25,7 @@ const {
@@ -50,7 +50,7 @@ index 5aa946f66c71beff0b7a43c30638ab28a1a5dfc0..e3afd30ba1f591d0298793bc42fd7166
});
const { search, hash } = resolved;
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index c8cea2117080930105b33e4e50586a2c88ef7352..2c33fd44b9a251682de78a8bcdad9ee5a0d3e5e8 100644
index 3c82913ca381eba30596f22a734b49dcba9b6f5b..1f967df42128a05e49acfa6d409737c06a3372e3 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -24,7 +24,7 @@ const {
@@ -62,7 +62,7 @@ index c8cea2117080930105b33e4e50586a2c88ef7352..2c33fd44b9a251682de78a8bcdad9ee5
const { dirname, extname } = require('path');
const {
assertBufferSource,
@@ -315,7 +315,7 @@ translators.set('commonjs', function commonjsStrategy(url, source, isMain) {
@@ -350,7 +350,7 @@ translators.set('commonjs', function commonjsStrategy(url, source, isMain) {
try {
// We still need to read the FS to detect the exports.

View File

@@ -10,7 +10,7 @@ change, it seems to introduce an incompatibility when compiling
using clang modules. Disabling them resolves the issue.
diff --git a/unofficial.gni b/unofficial.gni
index a64d2e4ac475abc049fff7ea62ec76de565a747d..ab456452d102088005fc4bfcb394d2de5ec44889 100644
index dd686d2f7c8d2f6e8d6bd13a7bf2b4b140556ba9..97e4bcfaa8aa42a5fc2b68ccdd8128eac8886532 100644
--- a/unofficial.gni
+++ b/unofficial.gni
@@ -195,6 +195,10 @@ template("node_gn_build") {
@@ -24,7 +24,7 @@ index a64d2e4ac475abc049fff7ea62ec76de565a747d..ab456452d102088005fc4bfcb394d2de
}
if (is_posix) {
configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
@@ -350,6 +354,12 @@ template("node_gn_build") {
@@ -367,6 +371,12 @@ template("node_gn_build") {
include_dirs = [ "src", "tools" ]
configs += [ "//build/config/compiler:no_exit_time_destructors" ]

View File

@@ -45,10 +45,10 @@ index ac00778cfc59fb55e361b24fc81a965a5e8f97e7..f0c4d6dfc9f03bee59e656b2da9ac325
# define UV__EUNATCH UV__ERR(EUNATCH)
#else
diff --git a/src/node_constants.cc b/src/node_constants.cc
index 0ca643aa74d13f278685d2330b791182b55c15b4..cbcecfba33070b820aca0e2814982160a97a6378 100644
index fd28e0904d05e24e8eeb74fa36abd9727699a649..fea0426496978c0003fe1481afcf93fc9c23edca 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -241,10 +241,6 @@ void DefineErrnoConstants(Local<Object> target) {
@@ -242,10 +242,6 @@ void DefineErrnoConstants(Local<Object> target) {
NODE_DEFINE_CONSTANT(target, ENOBUFS);
#endif
@@ -59,7 +59,7 @@ index 0ca643aa74d13f278685d2330b791182b55c15b4..cbcecfba33070b820aca0e2814982160
#ifdef ENODEV
NODE_DEFINE_CONSTANT(target, ENODEV);
#endif
@@ -281,14 +277,6 @@ void DefineErrnoConstants(Local<Object> target) {
@@ -282,14 +278,6 @@ void DefineErrnoConstants(Local<Object> target) {
NODE_DEFINE_CONSTANT(target, ENOSPC);
#endif
@@ -74,7 +74,7 @@ index 0ca643aa74d13f278685d2330b791182b55c15b4..cbcecfba33070b820aca0e2814982160
#ifdef ENOSYS
NODE_DEFINE_CONSTANT(target, ENOSYS);
#endif
@@ -369,10 +357,6 @@ void DefineErrnoConstants(Local<Object> target) {
@@ -370,10 +358,6 @@ void DefineErrnoConstants(Local<Object> target) {
NODE_DEFINE_CONSTANT(target, ESTALE);
#endif
@@ -86,7 +86,7 @@ index 0ca643aa74d13f278685d2330b791182b55c15b4..cbcecfba33070b820aca0e2814982160
NODE_DEFINE_CONSTANT(target, ETIMEDOUT);
#endif
diff --git a/src/node_errors.cc b/src/node_errors.cc
index 5f51add4cdf68a9487edfc9382f586cc94539571..befb642f1effa3c4139e4cd99ff64d9c5175fd72 100644
index ae8553ee2022d60fea4572976b14ba9cd253aa45..4386a1bc5678e351ce084cd2c47202561619b164 100644
--- a/src/node_errors.cc
+++ b/src/node_errors.cc
@@ -862,10 +862,6 @@ const char* errno_string(int errorno) {

View File

@@ -1,224 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Sun, 29 Dec 2024 04:01:32 +0900
Subject: fix: remove FastApiTypedArray usage
Refs https://github.com/electron/electron/pull/45055#issuecomment-2559095439
Can be removed when upstream adopts relevant V8 version.
diff --git a/src/crypto/crypto_timing.cc b/src/crypto/crypto_timing.cc
index fe669d40c31a29334b047b9cfee3067f64ef0a7b..9e5de7bbe574add017cd12ee091304d01e6458d6 100644
--- a/src/crypto/crypto_timing.cc
+++ b/src/crypto/crypto_timing.cc
@@ -12,7 +12,6 @@ namespace node {
using v8::CFunction;
using v8::FastApiCallbackOptions;
-using v8::FastApiTypedArray;
using v8::FunctionCallbackInfo;
using v8::Local;
using v8::Object;
@@ -51,14 +50,13 @@ void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
}
bool FastTimingSafeEqual(Local<Value> receiver,
- const FastApiTypedArray<uint8_t>& a,
- const FastApiTypedArray<uint8_t>& b,
+ Local<Value> a,
+ Local<Value> b,
// NOLINTNEXTLINE(runtime/references)
FastApiCallbackOptions& options) {
- uint8_t* data_a;
- uint8_t* data_b;
- if (a.length() != b.length() || !a.getStorageIfAligned(&data_a) ||
- !b.getStorageIfAligned(&data_b)) {
+ FAST_SPREAD_BUFFER_ARG(a, a_buffer);
+ FAST_SPREAD_BUFFER_ARG(b, b_buffer);
+ if (a_buffer_length != b_buffer_length) {
TRACK_V8_FAST_API_CALL("crypto.timingSafeEqual.error");
v8::HandleScope scope(options.isolate);
THROW_ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH(options.isolate);
@@ -66,7 +64,7 @@ bool FastTimingSafeEqual(Local<Value> receiver,
}
TRACK_V8_FAST_API_CALL("crypto.timingSafeEqual.ok");
- return CRYPTO_memcmp(data_a, data_b, a.length()) == 0;
+ return CRYPTO_memcmp(a_buffer_data, b_buffer_data, a_buffer_length) == 0;
}
static CFunction fast_timing_safe_equal(CFunction::Make(FastTimingSafeEqual));
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index e39852c8e0392e0a9ae5d4ea58be115416e19233..c94b14741c827a81d69a6f036426a344e563ad72 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -44,6 +44,14 @@
#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \
THROW_AND_RETURN_IF_NOT_BUFFER(env, obj, "argument") \
+#define THROW_AND_RETURN_VAL_UNLESS_BUFFER(isolate, val, prefix, retval) \
+ do { \
+ if (!Buffer::HasInstance(val)) { \
+ node::THROW_ERR_INVALID_ARG_TYPE(isolate, prefix " must be a buffer"); \
+ return retval; \
+ } \
+ } while (0)
+
#define THROW_AND_RETURN_IF_OOB(r) \
do { \
Maybe<bool> m = (r); \
@@ -60,7 +68,6 @@ using v8::ArrayBufferView;
using v8::BackingStore;
using v8::Context;
using v8::EscapableHandleScope;
-using v8::FastApiTypedArray;
using v8::FunctionCallbackInfo;
using v8::Global;
using v8::HandleScope;
@@ -584,19 +591,24 @@ void SlowCopy(const FunctionCallbackInfo<Value>& args) {
// Assume caller has properly validated args.
uint32_t FastCopy(Local<Value> receiver,
- const v8::FastApiTypedArray<uint8_t>& source,
- const v8::FastApiTypedArray<uint8_t>& target,
+ Local<Value> source_obj,
+ Local<Value> target_obj,
uint32_t target_start,
uint32_t source_start,
- uint32_t to_copy) {
- uint8_t* source_data;
- CHECK(source.getStorageIfAligned(&source_data));
-
+ uint32_t to_copy,
+ v8::FastApiCallbackOptions& options) {
+ FAST_SPREAD_BUFFER_ARG(source_obj, source);
uint8_t* target_data;
- CHECK(target.getStorageIfAligned(&target_data));
+ FAST_SPREAD_BUFFER_ARG(target_obj, target_buffer);
+ if (target_buffer_length <= kMaxSizeInHeap) {
+ HandleScope handle_scope(options.isolate);
+ SPREAD_BUFFER_ARG(target_obj, target_buffer);
+ target_data = reinterpret_cast<uint8_t*>(target_buffer_data);
+ } else {
+ target_data = target_buffer_data;
+ }
memmove(target_data + target_start, source_data + source_start, to_copy);
-
return to_copy;
}
@@ -865,19 +877,17 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
}
int32_t FastCompare(v8::Local<v8::Value>,
- const FastApiTypedArray<uint8_t>& a,
- const FastApiTypedArray<uint8_t>& b) {
- uint8_t* data_a;
- uint8_t* data_b;
- CHECK(a.getStorageIfAligned(&data_a));
- CHECK(b.getStorageIfAligned(&data_b));
+ v8::Local<v8::Value> a,
+ v8::Local<v8::Value> b) {
+ FAST_SPREAD_BUFFER_ARG(a, a_buffer);
+ FAST_SPREAD_BUFFER_ARG(b, b_buffer);
- size_t cmp_length = std::min(a.length(), b.length());
+ size_t cmp_length = std::min(a_buffer_length, b_buffer_length);
return normalizeCompareVal(
- cmp_length > 0 ? memcmp(data_a, data_b, cmp_length) : 0,
- a.length(),
- b.length());
+ cmp_length > 0 ? memcmp(a_buffer_data, b_buffer_data, cmp_length) : 0,
+ a_buffer_length,
+ b_buffer_length);
}
static v8::CFunction fast_compare(v8::CFunction::Make(FastCompare));
@@ -1149,14 +1159,13 @@ void SlowIndexOfNumber(const FunctionCallbackInfo<Value>& args) {
}
int32_t FastIndexOfNumber(v8::Local<v8::Value>,
- const FastApiTypedArray<uint8_t>& buffer,
+ v8::Local<v8::Value> source_obj,
uint32_t needle,
int64_t offset_i64,
bool is_forward) {
- uint8_t* buffer_data;
- CHECK(buffer.getStorageIfAligned(&buffer_data));
+ FAST_SPREAD_BUFFER_ARG(source_obj, buffer);
return IndexOfNumber(
- buffer_data, buffer.length(), needle, offset_i64, is_forward);
+ buffer_data, buffer_length, needle, offset_i64, is_forward);
}
static v8::CFunction fast_index_of_number(
@@ -1496,21 +1505,31 @@ void SlowWriteString(const FunctionCallbackInfo<Value>& args) {
template <encoding encoding>
uint32_t FastWriteString(Local<Value> receiver,
- const v8::FastApiTypedArray<uint8_t>& dst,
+ Local<v8::Value> dst,
const v8::FastOneByteString& src,
uint32_t offset,
- uint32_t max_length) {
- uint8_t* dst_data;
- CHECK(dst.getStorageIfAligned(&dst_data));
- CHECK(offset <= dst.length());
- CHECK(dst.length() - offset <= std::numeric_limits<uint32_t>::max());
+ uint32_t max_length,
+ v8::FastApiCallbackOptions& options) {
+ THROW_AND_RETURN_VAL_UNLESS_BUFFER(options.isolate, dst, "dst", 0);
+ uint8_t* dst_buffer_data;
+ FAST_SPREAD_BUFFER_ARG(dst, dst_fast_buffer);
+ if (dst_fast_buffer_length <= kMaxSizeInHeap) {
+ HandleScope handle_scope(options.isolate);
+ SPREAD_BUFFER_ARG(dst, dst_slow_buffer);
+ dst_buffer_data = reinterpret_cast<uint8_t*>(dst_slow_buffer_data);
+ } else {
+ dst_buffer_data = dst_fast_buffer_data;
+ };
+
+ CHECK(dst_fast_buffer_length <= std::numeric_limits<uint32_t>::max());
+ uint32_t dst_size = static_cast<uint32_t>(dst_fast_buffer_length);
TRACK_V8_FAST_API_CALL("buffer.writeString");
return WriteOneByteString<encoding>(
src.data,
src.length,
- reinterpret_cast<char*>(dst_data + offset),
- std::min<uint32_t>(dst.length() - offset, max_length));
+ reinterpret_cast<char*>(dst_buffer_data + offset),
+ std::min<uint32_t>(dst_size - offset, max_length));
}
static const v8::CFunction fast_write_string_ascii(
diff --git a/src/util.h b/src/util.h
index dcd6548d41be786c42ce8328d89e532a8e9d43a2..7c98de621ca4d53cbaaa5bd4488aab20c7b033a7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -62,6 +62,7 @@
namespace node {
constexpr char kPathSeparator = std::filesystem::path::preferred_separator;
+static constexpr size_t kMaxSizeInHeap = 64;
#ifdef _WIN32
/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
@@ -589,6 +590,16 @@ class BufferValue : public MaybeStackBuffer<char> {
static_cast<char*>(name->Buffer()->Data()) + name##_offset; \
if (name##_length > 0) CHECK_NE(name##_data, nullptr);
+#define FAST_SPREAD_BUFFER_ARG(val, name) \
+ CHECK((val)->IsArrayBufferView()); \
+ v8::Local<v8::ArrayBufferView> name = (val).As<v8::ArrayBufferView>(); \
+ uint8_t name##_buffer[kMaxSizeInHeap]; \
+ v8::MemorySpan<uint8_t> name##_storage(name##_buffer); \
+ name##_storage = name->GetContents(name##_storage); \
+ const size_t name##_length = name##_storage.size(); \
+ uint8_t* name##_data = name##_storage.data(); \
+ if (name##_length > 0) CHECK_NE(name##_data, nullptr);
+
// Use this when a variable or parameter is unused in order to explicitly
// silence a compiler warning about that.
template <typename T> inline void USE(T&&) {}

View File

@@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Fri, 18 Oct 2024 17:01:06 +0200
Subject: fix: remove outdated V8 flags from node.cc
Refs https://chromium-review.googlesource.com/c/v8/v8/+/5507047
Refs https://chromium-review.googlesource.com/c/v8/v8/+/6249026
Refs https://chromium-review.googlesource.com/c/v8/v8/+/6948286
The above CLs remove the following flags from V8:
* --harmony-import-assertions
* --experimental-wasm-memory64
* --experimental-wasm-imported-strings
This patch can be removed when we upgrade to a V8 version that
contains the above CLs.
diff --git a/src/node.cc b/src/node.cc
index 07684482f855363e26c3d7299a585a8a5654015e..5a7378890dc310bb3779974c79f387e7cdda15b0 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -816,7 +816,7 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
}
// TODO(nicolo-ribaudo): remove this once V8 doesn't enable it by default
// anymore.
- v8_args.emplace_back("--no-harmony-import-assertions");
+ // v8_args.emplace_back("--no-harmony-import-assertions");
auto env_opts = per_process::cli_options->per_isolate->per_env;
if (std::find(v8_args.begin(), v8_args.end(),
@@ -827,8 +827,8 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
}
// Support stable Phase 5 WebAssembly proposals
- v8_args.emplace_back("--experimental-wasm-imported-strings");
- v8_args.emplace_back("--experimental-wasm-memory64");
+ // v8_args.emplace_back("--experimental-wasm-imported-strings");
+ // v8_args.emplace_back("--experimental-wasm-memory64");
v8_args.emplace_back("--experimental-wasm-exnref");
#ifdef __POSIX__

View File

@@ -1,61 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Maddock <smaddock@slack-corp.com>
Date: Mon, 6 Oct 2025 16:34:43 -0400
Subject: fix: replace deprecated Get/SetPrototype
https://chromium-review.googlesource.com/c/v8/v8/+/6983465
This is already applied in newer versions of Node so we can drop
this patch once we upgrade to v23.
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 0a358735c331767e8eb563a80e9aaccfb544c27b..d7d18d5fcbf008ac131db189a141315af4f6410b 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -835,7 +835,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
Local<Object> private_symbols_object;
if (!private_symbols->NewInstance(context).ToLocal(&private_symbols_object) ||
- private_symbols_object->SetPrototype(context, Null(isolate))
+ private_symbols_object->SetPrototypeV2(context, Null(isolate))
.IsNothing()) {
return MaybeLocal<Object>();
}
@@ -861,7 +861,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
Local<Object> per_isolate_symbols_object;
if (!per_isolate_symbols->NewInstance(context).ToLocal(
&per_isolate_symbols_object) ||
- per_isolate_symbols_object->SetPrototype(context, Null(isolate))
+ per_isolate_symbols_object->SetPrototypeV2(context, Null(isolate))
.IsNothing()) {
return MaybeLocal<Object>();
}
diff --git a/src/node_constants.cc b/src/node_constants.cc
index 2f23cc63f148a792f1302e1d2d88822730abaa33..42678e5d11e5ff9543bf12ec02fee7d3263d7629 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -1307,7 +1307,7 @@ void CreatePerContextProperties(Local<Object> target,
.FromJust());
Local<Object> internal_constants = Object::New(isolate);
- CHECK(internal_constants->SetPrototype(env->context(),
+ CHECK(internal_constants->SetPrototypeV2(env->context(),
Null(env->isolate())).FromJust());
DefineErrnoConstants(err_constants);
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
index 96101167016573e80fff520256ebb78c71d83302..a76a68e50d81bddd80c02fa8263b788c098c887d 100644
--- a/src/node_sqlite.cc
+++ b/src/node_sqlite.cc
@@ -2106,9 +2106,9 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
StatementSyncIterator::Create(env, BaseObjectPtr<StatementSync>(stmt));
if (iter->object()
- ->GetPrototype()
+ ->GetPrototypeV2()
.As<Object>()
- ->SetPrototype(context, js_iterator_prototype)
+ ->SetPrototypeV2(context, js_iterator_prototype)
.IsNothing()) {
return;
}

View File

@@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Calvin Watford <cwatford@slack-corp.com>
Date: Thu, 3 Apr 2025 10:59:30 -0600
Subject: Fix task starvation in inspector context test
A V8 change makes these contexts get collected in a task that is posted
and run asynchronously. The tests were synchronously GC'ing in an
infinite loop, preventing the task loop from running the task that would
GC these contexts.
This change should be upstreamed in some way.
Ref: https://chromium-review.googlesource.com/c/v8/v8/+/4733273
diff --git a/test/parallel/test-inspector-contexts.js b/test/parallel/test-inspector-contexts.js
index e7bdc53f8cd5763572798cbd9ef07c902e3fc335..8b7a1f1aaf648efe10761af205ac561952a06980 100644
--- a/test/parallel/test-inspector-contexts.js
+++ b/test/parallel/test-inspector-contexts.js
@@ -17,6 +17,13 @@ function notificationPromise(method) {
return new Promise((resolve) => session.once(method, resolve));
}
+function gcImmediate() {
+ return new Promise((resolve) => {
+ global.gc();
+ setImmediate(resolve);
+ });
+}
+
async function testContextCreatedAndDestroyed() {
console.log('Testing context created/destroyed notifications');
{
@@ -68,7 +75,7 @@ async function testContextCreatedAndDestroyed() {
// GC is unpredictable...
console.log('Checking/waiting for GC.');
while (!contextDestroyed)
- global.gc();
+ await gcImmediate();
console.log('Context destroyed.');
assert.strictEqual(contextDestroyed.params.executionContextId, id,
@@ -100,7 +107,7 @@ async function testContextCreatedAndDestroyed() {
// GC is unpredictable...
console.log('Checking/waiting for GC again.');
while (!contextDestroyed)
- global.gc();
+ await gcImmediate();
console.log('Other context destroyed.');
}
@@ -126,7 +133,7 @@ async function testContextCreatedAndDestroyed() {
// GC is unpredictable...
console.log('Checking/waiting for GC a third time.');
while (!contextDestroyed)
- global.gc();
+ await gcImmediate();
console.log('Context destroyed once again.');
}
@@ -150,7 +157,7 @@ async function testContextCreatedAndDestroyed() {
// GC is unpredictable...
console.log('Checking/waiting for GC a fourth time.');
while (!contextDestroyed)
- global.gc();
+ await gcImmediate();
console.log('Context destroyed a fourth time.');
}
}

View File

@@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Sat, 25 Oct 2025 11:06:10 +0200
Subject: lib: check SharedArrayBuffer existence in fast-utf8-stream
After https://github.com/nodejs/node/pull/58897 calling
Object.entries on fs will lazy-load fast-utf8-stream, which uses
SharedArrayBuffer without checking for its existence first. It
won't exist in the renderer process and will throw
'SharedArrayBuffer is not a constructor'. Refactor to check
for SharedArrayBuffer first.
This should be upstreamed to Node.js
diff --git a/lib/internal/streams/fast-utf8-stream.js b/lib/internal/streams/fast-utf8-stream.js
index 3bfcc494d17b5cc4c9f494fab4aff4f0d68d2287..241a6b05e84f8e79b8c9b93abfda5562c2e35e9e 100644
--- a/lib/internal/streams/fast-utf8-stream.js
+++ b/lib/internal/streams/fast-utf8-stream.js
@@ -49,7 +49,8 @@ const {
const BUSY_WRITE_TIMEOUT = 100;
const kEmptyBuffer = Buffer.allocUnsafe(0);
-const kNil = new Int32Array(new SharedArrayBuffer(4));
+const haveSAB = typeof SharedArrayBuffer !== 'undefined';
+const kNil = haveSAB ? new Int32Array(new SharedArrayBuffer(4)) : null;
function sleep(ms) {
// Also filters out NaN, non-number types, including empty strings, but allows bigints
@@ -59,10 +60,14 @@ function sleep(ms) {
throw new ERR_INVALID_ARG_TYPE('ms', ['number', 'bigint'], ms);
}
throw new ERR_INVALID_ARG_VALUE.RangeError('ms', ms,
- 'must be a number greater than 0 and less than Infinity');
+ 'must be a number greater than 0 and less than Infinity');
+ }
+ if (haveSAB) {
+ AtomicsWait(kNil, 0, 0, Number(ms));
+ } else {
+ const { sleep: _sleep } = internalBinding('util');
+ _sleep(ms);
}
-
- AtomicsWait(kNil, 0, 0, Number(ms));
}
// 16 KB. Don't write more than docker buffer size.

View File

@@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chengzhong Wu <cwu631@bloomberg.net>
Date: Fri, 16 May 2025 17:10:54 +0100
Subject: node-api: use WriteOneByteV2 in napi_get_value_string_latin1
PR-URL: https://github.com/nodejs/node/pull/58325
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
index cc2312bd2fd1ed194f927bbf33951ca0548d1a31..e4fd88f406be4d9117aa490ca2aa328c5ff0aab9 100644
--- a/src/js_native_api_v8.cc
+++ b/src/js_native_api_v8.cc
@@ -2441,21 +2441,21 @@ napi_status NAPI_CDECL napi_get_value_string_latin1(
v8::Local<v8::Value> val = v8impl::V8LocalValueFromJsValue(value);
RETURN_STATUS_IF_FALSE(env, val->IsString(), napi_string_expected);
+ v8::Local<v8::String> str = val.As<v8::String>();
if (!buf) {
CHECK_ARG(env, result);
- *result = val.As<v8::String>()->Length();
+ *result = str->Length();
} else if (bufsize != 0) {
- int copied =
- val.As<v8::String>()->WriteOneByte(env->isolate,
- reinterpret_cast<uint8_t*>(buf),
- 0,
- bufsize - 1,
- v8::String::NO_NULL_TERMINATION);
-
- buf[copied] = '\0';
+ uint32_t length = static_cast<uint32_t>(
+ std::min(bufsize - 1, static_cast<size_t>(str->Length())));
+ str->WriteOneByteV2(env->isolate,
+ 0,
+ length,
+ reinterpret_cast<uint8_t*>(buf),
+ v8::String::WriteFlags::kNullTerminate);
if (result != nullptr) {
- *result = copied;
+ *result = length;
}
} else if (result != nullptr) {
*result = 0;
@@ -2479,12 +2479,12 @@ napi_status NAPI_CDECL napi_get_value_string_utf8(
v8::Local<v8::Value> val = v8impl::V8LocalValueFromJsValue(value);
RETURN_STATUS_IF_FALSE(env, val->IsString(), napi_string_expected);
+ v8::Local<v8::String> str = val.As<v8::String>();
if (!buf) {
CHECK_ARG(env, result);
- *result = val.As<v8::String>()->Utf8LengthV2(env->isolate);
+ *result = str->Utf8LengthV2(env->isolate);
} else if (bufsize != 0) {
- auto str = val.As<v8::String>();
size_t copied =
str->WriteUtf8V2(env->isolate,
buf,

View File

@@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
Date: Fri, 16 May 2025 17:10:45 +0100
Subject: node-api: use WriteV2 in napi_get_value_string_utf16
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since `String::Write()` is deprecated, use `String::Write2()` instead.
That requires us to compute the correct number of characters ahead of
time but removes the need for dealing with the return value.
PR-URL: https://github.com/nodejs/node/pull/58165
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Vladimir Morozov <vmorozov@microsoft.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
index 8f97ca4d9cbb840efd36c77fed12d746a2793670..cc2312bd2fd1ed194f927bbf33951ca0548d1a31 100644
--- a/src/js_native_api_v8.cc
+++ b/src/js_native_api_v8.cc
@@ -2520,21 +2520,23 @@ napi_status NAPI_CDECL napi_get_value_string_utf16(napi_env env,
v8::Local<v8::Value> val = v8impl::V8LocalValueFromJsValue(value);
RETURN_STATUS_IF_FALSE(env, val->IsString(), napi_string_expected);
+ v8::Local<v8::String> str = val.As<v8::String>();
if (!buf) {
CHECK_ARG(env, result);
// V8 assumes UTF-16 length is the same as the number of characters.
- *result = val.As<v8::String>()->Length();
+ *result = str->Length();
} else if (bufsize != 0) {
- int copied = val.As<v8::String>()->Write(env->isolate,
- reinterpret_cast<uint16_t*>(buf),
- 0,
- bufsize - 1,
- v8::String::NO_NULL_TERMINATION);
+ uint32_t length = static_cast<uint32_t>(
+ std::min(bufsize - 1, static_cast<size_t>(str->Length())));
+ str->WriteV2(env->isolate,
+ 0,
+ length,
+ reinterpret_cast<uint16_t*>(buf),
+ v8::String::WriteFlags::kNullTerminate);
- buf[copied] = '\0';
if (result != nullptr) {
- *result = copied;
+ *result = length;
}
} else if (result != nullptr) {
*result = 0;

View File

@@ -6,10 +6,10 @@ Subject: Pass all globals through "require"
(cherry picked from commit 7d015419cb7a0ecfe6728431a4ed2056cd411d62)
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index a7d8fa1139c82054ac37a4e11cfb68605dc21f31..589c239aa544e118b7d9b7fff86d7deefe903896 100644
index 8a28cd0e497911550cb0fa889c4f2f780d86c24b..811a2961834b9648f5f6b51c3bda570541413818 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -202,6 +202,13 @@ const {
@@ -208,6 +208,13 @@ const {
CHAR_FORWARD_SLASH,
} = require('internal/constants');
@@ -23,7 +23,7 @@ index a7d8fa1139c82054ac37a4e11cfb68605dc21f31..589c239aa544e118b7d9b7fff86d7dee
const {
isProxy,
} = require('internal/util/types');
@@ -1701,10 +1708,12 @@ Module.prototype._compile = function(content, filename, format) {
@@ -1755,10 +1762,12 @@ Module.prototype._compile = function(content, filename, format) {
if (this[kIsMainSymbol] && getOptionValue('--inspect-brk')) {
const { callAndPauseOnStart } = internalBinding('inspector');
result = callAndPauseOnStart(compiledWrapper, thisValue, exports,

View File

@@ -7,10 +7,10 @@ We use this to allow node's 'fs' module to read from ASAR files as if they were
a real filesystem.
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
index 1a39b9f15e689e5c7ca1e3001b2ef6d854f8cc1e..9035311718c0a68e903e0ce748480bc78112c6ff 100644
index 963fe2ab11927a6802d2b1c0f653b5b1032d4243..0a531f216bd64477b800a169e91d859844161f16 100644
--- a/lib/internal/bootstrap/node.js
+++ b/lib/internal/bootstrap/node.js
@@ -132,6 +132,10 @@ process.domain = null;
@@ -129,6 +129,10 @@ process.domain = null;
}
process._exiting = false;

View File

@@ -18,10 +18,10 @@ This can be removed when Node.js upgrades to a version of V8 containing CLs
from the above issue.
diff --git a/src/api/environment.cc b/src/api/environment.cc
index cb37fa080fc8e8d524cfa2758c4a8c2c5652324d..8e227ddd1be50c046a8cf2895a31d607eb7d31de 100644
index a869bc0a145009b57db3f37208e405d9356cc20f..072deb1fa70313e33397f6ff994e3f3548e86092 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -316,6 +316,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
@@ -319,6 +319,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
MultiIsolatePlatform* platform,
const SnapshotData* snapshot_data,
const IsolateSettings& settings) {
@@ -32,7 +32,7 @@ index cb37fa080fc8e8d524cfa2758c4a8c2c5652324d..8e227ddd1be50c046a8cf2895a31d607
Isolate* isolate = Isolate::Allocate();
if (isolate == nullptr) return nullptr;
@@ -359,9 +363,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator,
@@ -374,9 +378,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator,
uv_loop_t* event_loop,
MultiIsolatePlatform* platform,
const EmbedderSnapshotData* snapshot_data,
@@ -46,100 +46,66 @@ index cb37fa080fc8e8d524cfa2758c4a8c2c5652324d..8e227ddd1be50c046a8cf2895a31d607
return NewIsolate(&params,
event_loop,
platform,
diff --git a/src/env.cc b/src/env.cc
index 85641b68b1e6f6dd4149f33ba13f76bccc8bf47d..c6209cc7cf317de1bb9217e39dd760e5a83303e2 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -578,14 +578,6 @@ IsolateData::IsolateData(Isolate* isolate,
// We do not care about overflow since we just want this to be different
// from the cppgc id.
uint16_t non_cppgc_id = cppgc_id + 1;
- if (cpp_heap == nullptr) {
- cpp_heap_ = CppHeap::Create(platform, v8::CppHeapCreateParams{{}});
- // TODO(joyeecheung): pass it into v8::Isolate::CreateParams and let V8
- // own it when we can keep the isolate registered/task runner discoverable
- // during isolate disposal.
- isolate->AttachCppHeap(cpp_heap_.get());
- }
-
{
// GC could still be run after the IsolateData is destroyed, so we store
// the ids in a static map to ensure pointers to them are still valid
@@ -608,15 +600,6 @@ IsolateData::IsolateData(Isolate* isolate,
}
diff --git a/src/cppgc_helpers-inl.h b/src/cppgc_helpers-inl.h
index 745ecab746f7c7540733d31a94f52809dcddd5be..0e52bf5a6f4837d0f4bfed83987c6903796fda55 100644
--- a/src/cppgc_helpers-inl.h
+++ b/src/cppgc_helpers-inl.h
@@ -15,11 +15,12 @@ void CppgcMixin::Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj) {
v8::Isolate* isolate = realm->isolate();
ptr->traced_reference_ = v8::TracedReference<v8::Object>(isolate, obj);
// Note that ptr must be of concrete type T in Wrap.
- v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(isolate, obj, ptr);
+ auto* wrappable = static_cast<v8::Object::Wrappable*>(ptr);
+ v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(isolate, obj, wrappable);
// Keep the layout consistent with BaseObjects.
obj->SetAlignedPointerInInternalField(
- kEmbedderType, realm->isolate_data()->embedder_id_for_cppgc());
- obj->SetAlignedPointerInInternalField(kSlot, ptr);
+ kEmbedderType, realm->isolate_data()->embedder_id_for_cppgc(), 0);
+ obj->SetAlignedPointerInInternalField(kSlot, ptr, 0);
realm->TrackCppgcWrapper(ptr);
}
-IsolateData::~IsolateData() {
- if (cpp_heap_ != nullptr) {
- v8::Locker locker(isolate_);
- // The CppHeap must be detached before being terminated.
- isolate_->DetachCppHeap();
- cpp_heap_->Terminate();
- }
-}
-
@@ -40,7 +41,7 @@ T* CppgcMixin::Unwrap(v8::Local<v8::Object> obj) {
if (obj->InternalFieldCount() != T::kInternalFieldCount) {
return nullptr;
}
- T* ptr = static_cast<T*>(obj->GetAlignedPointerFromInternalField(T::kSlot));
+ T* ptr = static_cast<T*>(obj->GetAlignedPointerFromInternalField(T::kSlot, 0));
return ptr;
}
diff --git a/src/cppgc_helpers.h b/src/cppgc_helpers.h
index fb2af584a4ae777022c9ef8c20ada1edcbbbefdc..fe6300a5d5d2d6602a84cbd33736c2133041d1b0 100644
--- a/src/cppgc_helpers.h
+++ b/src/cppgc_helpers.h
@@ -155,7 +155,7 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
*/
#define CPPGC_MIXIN(Klass) \
public /* NOLINT(whitespace/indent) */ \
- cppgc::GarbageCollected<Klass>, public cppgc::NameProvider, public CppgcMixin
+ v8::Object::Wrappable, public CppgcMixin
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
diff --git a/src/env.cc b/src/env.cc
index 53f0bf7fc1e5c85fa9a5a323e998f04310f4f75e..a78817467518245c4a190e870e0eb30658eafcdb 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -611,7 +611,7 @@ IsolateData::~IsolateData() {}
// Deprecated API, embedders should use v8::Object::Wrap() directly instead.
void SetCppgcReference(Isolate* isolate,
Local<Object> object,
diff --git a/src/env.h b/src/env.h
index 2d5fa8dbd75851bca30453548f6cbe0159509f26..c346e3a9c827993036438685d758a734f9ce8c05 100644
--- a/src/env.h
+++ b/src/env.h
@@ -157,7 +157,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
ArrayBufferAllocator* node_allocator = nullptr,
const EmbedderSnapshotData* embedder_snapshot_data = nullptr,
std::shared_ptr<PerIsolateOptions> options = nullptr);
- ~IsolateData();
SET_MEMORY_INFO_NAME(IsolateData)
SET_SELF_SIZE(IsolateData)
@@ -260,7 +259,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
const SnapshotData* snapshot_data_;
std::optional<SnapshotConfig> snapshot_config_;
- std::unique_ptr<v8::CppHeap> cpp_heap_;
std::shared_ptr<PerIsolateOptions> options_;
worker::Worker* worker_context_ = nullptr;
PerIsolateWrapperData* wrapper_data_;
diff --git a/src/node.cc b/src/node.cc
index 5a7378890dc310bb3779974c79f387e7cdda15b0..0725cc97510375bc616534ddf3de4b231bae6bf5 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1295,6 +1295,14 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
result->platform_ = per_process::v8_platform.Platform();
}
+ if (!(flags & ProcessInitializationFlags::kNoInitializeCppgc)) {
+ v8::PageAllocator* allocator = nullptr;
+ if (result->platform_ != nullptr) {
+ allocator = result->platform_->GetPageAllocator();
+ }
+ cppgc::InitializeProcess(allocator);
+ }
+
if (!(flags & ProcessInitializationFlags::kNoInitializeV8)) {
V8::Initialize();
@@ -1304,14 +1312,6 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);
}
- if (!(flags & ProcessInitializationFlags::kNoInitializeCppgc)) {
- v8::PageAllocator* allocator = nullptr;
- if (result->platform_ != nullptr) {
- allocator = result->platform_->GetPageAllocator();
- }
- cppgc::InitializeProcess(allocator);
- }
-
#if NODE_USE_V8_WASM_TRAP_HANDLER
bool use_wasm_trap_handler =
!per_process::cli_options->disable_wasm_trap_handler;
- void* wrappable) {
+ v8::Object::Wrappable* wrappable) {
v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(
isolate, object, wrappable);
}
diff --git a/src/node.h b/src/node.h
index d3a965661d068db359bb1bb4b14e59c28bb615f9..16a0c71aef949b0ddd27def9dc843298f9a6b75f 100644
index f7b3f90b0c2cfbeacc5bc50112dd711df8d3c364..7fae281a6e0f3c1a9f0eb97536883bb26c16d94d 100644
--- a/src/node.h
+++ b/src/node.h
@@ -590,7 +590,8 @@ NODE_EXTERN v8::Isolate* NewIsolate(
@@ -604,7 +604,8 @@ NODE_EXTERN v8::Isolate* NewIsolate(
struct uv_loop_s* event_loop,
MultiIsolatePlatform* platform,
const EmbedderSnapshotData* snapshot_data = nullptr,
@@ -149,8 +115,22 @@ index d3a965661d068db359bb1bb4b14e59c28bb615f9..16a0c71aef949b0ddd27def9dc843298
NODE_EXTERN v8::Isolate* NewIsolate(
std::shared_ptr<ArrayBufferAllocator> allocator,
struct uv_loop_s* event_loop,
@@ -1617,9 +1618,10 @@ void RegisterSignalHandler(int signal,
// work with only Node.js versions with v8::Object::Wrap() should use that
// instead.
NODE_DEPRECATED("Use v8::Object::Wrap()",
- NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable));
+ NODE_EXTERN void SetCppgcReference(
+ v8::Isolate* isolate,
+ v8::Local<v8::Object> object,
+ v8::Object::Wrappable* wrappable));
} // namespace node
diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc
index 4119ac1b002681d39711eac810ca2fcc2702ffc7..790347056cde949ffe6cf8498a7eca0c4864c997 100644
index dd6ecd1f9d82f6661b2480c0195e33515633429f..334d5cb7df7a763e0929468392dad83421cad606 100644
--- a/src/node_main_instance.cc
+++ b/src/node_main_instance.cc
@@ -44,6 +44,8 @@ NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
@@ -162,22 +142,11 @@ index 4119ac1b002681d39711eac810ca2fcc2702ffc7..790347056cde949ffe6cf8498a7eca0c
isolate_ =
NewIsolate(isolate_params_.get(), event_loop, platform, snapshot_data);
@@ -81,9 +83,9 @@ NodeMainInstance::~NodeMainInstance() {
// This should only be done on a main instance that owns its isolate.
// IsolateData must be freed before UnregisterIsolate() is called.
isolate_data_.reset();
- platform_->UnregisterIsolate(isolate_);
}
isolate_->Dispose();
+ platform_->UnregisterIsolate(isolate_);
}
ExitCode NodeMainInstance::Run() {
diff --git a/src/node_worker.cc b/src/node_worker.cc
index 29c4b1de42b3127a98871d200c80197bf974b31f..8555ab556b5b74a1cf9cf30747f1f417bfe4e4d9 100644
index 7bae29747d8cd8e83973d105099f9111fc185fe1..62c53368d1173edb7eb42e3337049c46fd7cdda9 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -177,6 +177,9 @@ class WorkerThreadData {
@@ -181,6 +181,9 @@ class WorkerThreadData {
SetIsolateCreateParamsForNode(&params);
w->UpdateResourceConstraints(&params.constraints);
params.array_buffer_allocator_shared = allocator;
@@ -187,153 +156,3 @@ index 29c4b1de42b3127a98871d200c80197bf974b31f..8555ab556b5b74a1cf9cf30747f1f417
Isolate* isolate =
NewIsolate(&params, &loop_, w->platform_, w->snapshot_data());
if (isolate == nullptr) {
@@ -245,13 +248,8 @@ class WorkerThreadData {
*static_cast<bool*>(data) = true;
}, &platform_finished);
- // The order of these calls is important; if the Isolate is first disposed
- // and then unregistered, there is a race condition window in which no
- // new Isolate at the same address can successfully be registered with
- // the platform.
- // (Refs: https://github.com/nodejs/node/issues/30846)
- w_->platform_->UnregisterIsolate(isolate);
isolate->Dispose();
+ w_->platform_->UnregisterIsolate(isolate);
// Wait until the platform has cleaned up all relevant resources.
while (!platform_finished) {
diff --git a/src/util.cc b/src/util.cc
index 0c01d338b9d1ced7f173ac862239315f91326791..5ca32f026f9f001ddadc14965705fe005600eddd 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -726,8 +726,8 @@ RAIIIsolateWithoutEntering::RAIIIsolateWithoutEntering(const SnapshotData* data)
}
RAIIIsolateWithoutEntering::~RAIIIsolateWithoutEntering() {
- per_process::v8_platform.Platform()->UnregisterIsolate(isolate_);
isolate_->Dispose();
+ per_process::v8_platform.Platform()->UnregisterIsolate(isolate_);
}
RAIIIsolate::RAIIIsolate(const SnapshotData* data)
diff --git a/test/cctest/node_test_fixture.h b/test/cctest/node_test_fixture.h
index 3414c0be8ad777f0b9836323150071b688831a38..82013ffe7667d53248bd616efb79b294e4ae47dd 100644
--- a/test/cctest/node_test_fixture.h
+++ b/test/cctest/node_test_fixture.h
@@ -123,8 +123,8 @@ class NodeTestFixture : public NodeZeroIsolateTestFixture {
void TearDown() override {
platform->DrainTasks(isolate_);
isolate_->Exit();
- platform->UnregisterIsolate(isolate_);
isolate_->Dispose();
+ platform->UnregisterIsolate(isolate_);
isolate_ = nullptr;
NodeZeroIsolateTestFixture::TearDown();
}
diff --git a/test/cctest/test_cppgc.cc b/test/cctest/test_cppgc.cc
index edd413ae9b956b2e59e8166785adef6a8ff06d51..d1c1549efcb0320bc0f7d354db2101acc0930005 100644
--- a/test/cctest/test_cppgc.cc
+++ b/test/cctest/test_cppgc.cc
@@ -46,18 +46,15 @@ int CppGCed::kDestructCount = 0;
int CppGCed::kTraceCount = 0;
TEST_F(NodeZeroIsolateTestFixture, ExistingCppHeapTest) {
- v8::Isolate* isolate =
- node::NewIsolate(allocator.get(), &current_loop, platform.get());
// Create and attach the CppHeap before we set up the IsolateData so that
// it recognizes the existing heap.
std::unique_ptr<v8::CppHeap> cpp_heap =
v8::CppHeap::Create(platform.get(), v8::CppHeapCreateParams{{}});
- // TODO(joyeecheung): pass it into v8::Isolate::CreateParams and let V8
- // own it when we can keep the isolate registered/task runner discoverable
- // during isolate disposal.
- isolate->AttachCppHeap(cpp_heap.get());
+ v8::Isolate* isolate =
+ node::NewIsolate(allocator.get(), &current_loop, platform.get(),
+ nullptr, {}, std::move(cpp_heap));
// Try creating Context + IsolateData + Environment.
{
@@ -102,13 +99,11 @@ TEST_F(NodeZeroIsolateTestFixture, ExistingCppHeapTest) {
platform->DrainTasks(isolate);
// Cleanup.
- isolate->DetachCppHeap();
- cpp_heap->Terminate();
platform->DrainTasks(isolate);
}
- platform->UnregisterIsolate(isolate);
isolate->Dispose();
+ platform->UnregisterIsolate(isolate);
// Check that all the objects are created and destroyed properly.
EXPECT_EQ(CppGCed::kConstructCount, 100);
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
index 008cda77b650dc2d904ae00e7629b5ad05d297ad..103931516cea9beb7f25c53526928e67b3c90d2d 100644
--- a/test/cctest/test_environment.cc
+++ b/test/cctest/test_environment.cc
@@ -625,6 +625,9 @@ TEST_F(NodeZeroIsolateTestFixture, CtrlCWithOnlySafeTerminationTest) {
// Allocate and initialize Isolate.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = allocator.get();
+ create_params.cpp_heap =
+ v8::CppHeap::Create(platform.get(), v8::CppHeapCreateParams{{}})
+ .release();
v8::Isolate* isolate = v8::Isolate::Allocate();
CHECK_NOT_NULL(isolate);
platform->RegisterIsolate(isolate, &current_loop);
@@ -675,8 +678,8 @@ TEST_F(NodeZeroIsolateTestFixture, CtrlCWithOnlySafeTerminationTest) {
}
// Cleanup.
- platform->UnregisterIsolate(isolate);
isolate->Dispose();
+ platform->UnregisterIsolate(isolate);
}
#endif // _WIN32
diff --git a/test/cctest/test_platform.cc b/test/cctest/test_platform.cc
index 53644accf29749bf8fc18b641ae1eaef93cd6f98..7e5b143fb4b633e18a4b2d7440cba7e077c50950 100644
--- a/test/cctest/test_platform.cc
+++ b/test/cctest/test_platform.cc
@@ -102,8 +102,8 @@ TEST_F(NodeZeroIsolateTestFixture, IsolatePlatformDelegateTest) {
// Graceful shutdown
delegate->Shutdown();
- platform->UnregisterIsolate(isolate);
isolate->Dispose();
+ platform->UnregisterIsolate(isolate);
}
TEST_F(PlatformTest, TracingControllerNullptr) {
diff --git a/test/fuzzers/fuzz_env.cc b/test/fuzzers/fuzz_env.cc
index bace3051f8cecd5050d4707f2431973752a22188..5ca295848a974c70ff1a9094eb288ef7e658d8e5 100644
--- a/test/fuzzers/fuzz_env.cc
+++ b/test/fuzzers/fuzz_env.cc
@@ -65,8 +65,8 @@ public:
void Teardown() {
platform->DrainTasks(isolate_);
isolate_->Exit();
- platform->UnregisterIsolate(isolate_);
isolate_->Dispose();
+ platform->UnregisterIsolate(isolate_);
isolate_ = nullptr;
}
};
diff --git a/test/fuzzers/fuzz_strings.cc b/test/fuzzers/fuzz_strings.cc
index 8f5e1a473e3148e0bcdcc3c2fd582685665ce461..936876cdae20d29618d3789a5ab46a1b3101a79d 100644
--- a/test/fuzzers/fuzz_strings.cc
+++ b/test/fuzzers/fuzz_strings.cc
@@ -72,8 +72,8 @@ public:
void Teardown() {
platform->DrainTasks(isolate_);
isolate_->Exit();
- platform->UnregisterIsolate(isolate_);
isolate_->Dispose();
+ platform->UnregisterIsolate(isolate_);
isolate_ = nullptr;
}
};

View File

@@ -1,127 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Fri, 19 Apr 2024 12:29:53 +0200
Subject: src: do not use soon-to-be-deprecated V8 API
V8 announced deprecation of the following methods:
- v8::Object::SetAccessor(...) in favor of
v8::Object::SetNativeDataProperty(...),
- v8::ObjectTemplate::SetNativeDataProperty(...) with AccessControl
parameter in favor of
v8::ObjectTemplate::SetNativeDataProperty(...) without AccessControl
parameter.
See https://crrev.com/c/5006387.
This slightly changes behavior of the following properties:
- process.debugPort (for worker processes),
- process.title (for worker processes),
- process.ppid.
The difference is that they will now behave like a regular writable
JavaScript data properties - in case setter callback is not provided
they will be be reconfigured from a native data property (the one
that calls C++ callbacks upon get/set operations) to a real data
property (so subsequent reads will no longer trigger C++ getter
callbacks).
PR-URL: https://github.com/nodejs/node/pull/53174
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/src/node_process_object.cc b/src/node_process_object.cc
index 2e0d180d249c6925c761cb673a4a396905cc971c..5bf854723040859f841608f40ac43ea3d4a44b1e 100644
--- a/src/node_process_object.cc
+++ b/src/node_process_object.cc
@@ -13,7 +13,6 @@
namespace node {
using v8::Context;
-using v8::DEFAULT;
using v8::EscapableHandleScope;
using v8::Function;
using v8::FunctionCallbackInfo;
@@ -168,13 +167,12 @@ void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
// process.title
CHECK(process
- ->SetAccessor(
+ ->SetNativeDataProperty(
context,
FIXED_ONE_BYTE_STRING(isolate, "title"),
ProcessTitleGetter,
env->owns_process_state() ? ProcessTitleSetter : nullptr,
Local<Value>(),
- DEFAULT,
None,
SideEffectType::kHasNoSideEffect)
.FromJust());
@@ -193,9 +191,15 @@ void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
READONLY_PROPERTY(process, "pid",
Integer::New(isolate, uv_os_getpid()));
- CHECK(process->SetAccessor(context,
- FIXED_ONE_BYTE_STRING(isolate, "ppid"),
- GetParentProcessId).FromJust());
+ CHECK(process
+ ->SetNativeDataProperty(context,
+ FIXED_ONE_BYTE_STRING(isolate, "ppid"),
+ GetParentProcessId,
+ nullptr,
+ Local<Value>(),
+ None,
+ SideEffectType::kHasNoSideEffect)
+ .FromJust());
// --security-revert flags
#define V(code, _, __) \
@@ -220,12 +224,15 @@ void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
// process.debugPort
CHECK(process
- ->SetAccessor(context,
- FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
- DebugPortGetter,
- env->owns_process_state() ? DebugPortSetter : nullptr,
- Local<Value>())
- .FromJust());
+ ->SetNativeDataProperty(
+ context,
+ FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
+ DebugPortGetter,
+ env->owns_process_state() ? DebugPortSetter : nullptr,
+ Local<Value>(),
+ None,
+ SideEffectType::kHasNoSideEffect)
+ .FromJust());
// process.versions
Local<Object> versions = Object::New(isolate);
diff --git a/test/parallel/test-worker-unsupported-things.js b/test/parallel/test-worker-unsupported-things.js
index 18c1617c3cde5ef12f9c97828840c39e0be3dc2c..95d93d24dec9f1944091a97574f01c94d617cc49 100644
--- a/test/parallel/test-worker-unsupported-things.js
+++ b/test/parallel/test-worker-unsupported-things.js
@@ -14,14 +14,16 @@ if (!process.env.HAS_STARTED_WORKER) {
} else {
{
const before = process.title;
- process.title += ' in worker';
- assert.strictEqual(process.title, before);
+ const after = before + ' in worker';
+ process.title = after;
+ assert.strictEqual(process.title, after);
}
{
const before = process.debugPort;
- process.debugPort++;
- assert.strictEqual(process.debugPort, before);
+ const after = before + 1;
+ process.debugPort = after;
+ assert.strictEqual(process.debugPort, after);
}
{

View File

@@ -1,166 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yagiz Nizipli <yagiz@nizipli.com>
Date: Mon, 16 Sep 2024 20:19:46 -0400
Subject: src: improve utf8 string generation performance
PR-URL: https://github.com/nodejs/node/pull/54873
Reviewed-By: Daniel Lemire <daniel@lemire.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
index f0fbf496dcfdec2c522508c61ae24fb20b1eb081..4324ed52d7cd6af5202512858a62346c3ab6c302 100644
--- a/src/string_bytes.cc
+++ b/src/string_bytes.cc
@@ -386,21 +386,21 @@ Maybe<size_t> StringBytes::StorageSize(Isolate* isolate,
Local<Value> val,
enum encoding encoding) {
HandleScope scope(isolate);
- size_t data_size = 0;
- bool is_buffer = Buffer::HasInstance(val);
- if (is_buffer && (encoding == BUFFER || encoding == LATIN1)) {
+ if (Buffer::HasInstance(val) && (encoding == BUFFER || encoding == LATIN1)) {
return Just(Buffer::Length(val));
}
Local<String> str;
if (!val->ToString(isolate->GetCurrentContext()).ToLocal(&str))
return Nothing<size_t>();
+ String::ValueView view(isolate, str);
+ size_t data_size = 0;
switch (encoding) {
case ASCII:
case LATIN1:
- data_size = str->Length();
+ data_size = view.length();
break;
case BUFFER:
@@ -408,25 +408,25 @@ Maybe<size_t> StringBytes::StorageSize(Isolate* isolate,
// A single UCS2 codepoint never takes up more than 3 utf8 bytes.
// It is an exercise for the caller to decide when a string is
// long enough to justify calling Size() instead of StorageSize()
- data_size = 3 * str->Length();
+ data_size = 3 * view.length();
break;
case UCS2:
- data_size = str->Length() * sizeof(uint16_t);
+ data_size = view.length() * sizeof(uint16_t);
break;
case BASE64URL:
- data_size = simdutf::base64_length_from_binary(str->Length(),
+ data_size = simdutf::base64_length_from_binary(view.length(),
simdutf::base64_url);
break;
case BASE64:
- data_size = simdutf::base64_length_from_binary(str->Length());
+ data_size = simdutf::base64_length_from_binary(view.length());
break;
case HEX:
- CHECK(str->Length() % 2 == 0 && "invalid hex string length");
- data_size = str->Length() / 2;
+ CHECK(view.length() % 2 == 0 && "invalid hex string length");
+ data_size = view.length() / 2;
break;
default:
@@ -447,32 +447,36 @@ Maybe<size_t> StringBytes::Size(Isolate* isolate,
Local<String> str;
if (!val->ToString(isolate->GetCurrentContext()).ToLocal(&str))
return Nothing<size_t>();
+ String::ValueView view(isolate, str);
switch (encoding) {
case ASCII:
case LATIN1:
- return Just<size_t>(str->Length());
+ return Just<size_t>(view.length());
case BUFFER:
case UTF8:
- return Just<size_t>(str->Utf8Length(isolate));
+ if (view.is_one_byte()) {
+ return Just<size_t>(simdutf::utf8_length_from_latin1(
+ reinterpret_cast<const char*>(view.data8()), view.length()));
+ }
+ return Just<size_t>(simdutf::utf8_length_from_utf16(
+ reinterpret_cast<const char16_t*>(view.data16()), view.length()));
case UCS2:
- return Just(str->Length() * sizeof(uint16_t));
+ return Just(view.length() * sizeof(uint16_t));
case BASE64URL: {
- String::Value value(isolate, str);
- return Just(simdutf::base64_length_from_binary(value.length(),
+ return Just(simdutf::base64_length_from_binary(view.length(),
simdutf::base64_url));
}
case BASE64: {
- String::Value value(isolate, str);
- return Just(simdutf::base64_length_from_binary(value.length()));
+ return Just(simdutf::base64_length_from_binary(view.length()));
}
case HEX:
- return Just<size_t>(str->Length() / 2);
+ return Just<size_t>(view.length() / 2);
}
UNREACHABLE();
diff --git a/src/util.cc b/src/util.cc
index 1b38f22b930b77d80aa53f9b12299d3cc469a46d..03c4794314c1c228f95536d2d20a440061cf3a80 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -48,6 +48,8 @@
#include <sys/types.h>
#endif
+#include <simdutf.h>
+
#include <atomic>
#include <cstdio>
#include <cstring>
@@ -100,11 +102,31 @@ static void MakeUtf8String(Isolate* isolate,
MaybeStackBuffer<T>* target) {
Local<String> string;
if (!value->ToString(isolate->GetCurrentContext()).ToLocal(&string)) return;
+ String::ValueView value_view(isolate, string);
+
+ auto value_length = value_view.length();
+
+ if (value_view.is_one_byte()) {
+ auto const_char = reinterpret_cast<const char*>(value_view.data8());
+ auto expected_length =
+ target->capacity() < (static_cast<size_t>(value_length) * 2 + 1)
+ ? simdutf::utf8_length_from_latin1(const_char, value_length)
+ : value_length * 2;
+
+ // Add +1 for null termination.
+ target->AllocateSufficientStorage(expected_length + 1);
+ const auto actual_length = simdutf::convert_latin1_to_utf8(
+ const_char, value_length, target->out());
+ target->SetLengthAndZeroTerminate(actual_length);
+ return;
+ }
- size_t storage;
- if (!StringBytes::StorageSize(isolate, string, UTF8).To(&storage)) return;
- storage += 1;
+ // Add +1 for null termination.
+ size_t storage = (3 * value_length) + 1;
target->AllocateSufficientStorage(storage);
+
+ // TODO(@anonrig): Use simdutf to speed up non-one-byte strings once it's
+ // implemented
const int flags =
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8;
const int length =

View File

@@ -1,276 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chengzhong Wu <cwu631@bloomberg.net>
Date: Fri, 29 Aug 2025 23:41:00 +0100
Subject: src: migrate WriteOneByte to WriteOneByteV2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PR-URL: https://github.com/nodejs/node/pull/59634
Fixes: https://github.com/nodejs/node/issues/59555
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index ae73e6743879f32f08b4f6f8c546c587de71d2f3..be93e60f851c6c144fdd19f810e0a44cf3845bce 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -1033,8 +1033,11 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
if (needle_data == nullptr) {
return args.GetReturnValue().Set(-1);
}
- needle->WriteOneByte(
- isolate, needle_data, 0, needle_length, String::NO_NULL_TERMINATION);
+ StringBytes::Write(isolate,
+ reinterpret_cast<char*>(needle_data),
+ needle_length,
+ needle,
+ enc);
result = nbytes::SearchString(reinterpret_cast<const uint8_t*>(haystack),
haystack_length,
@@ -1288,11 +1291,7 @@ static void Btoa(const FunctionCallbackInfo<Value>& args) {
simdutf::binary_to_base64(ext->data(), ext->length(), buffer.out());
} else if (input->IsOneByte()) {
MaybeStackBuffer<uint8_t> stack_buf(input->Length());
- input->WriteOneByte(env->isolate(),
- stack_buf.out(),
- 0,
- input->Length(),
- String::NO_NULL_TERMINATION);
+ input->WriteOneByteV2(env->isolate(), 0, input->Length(), stack_buf.out());
size_t expected_length =
simdutf::base64_length_from_binary(input->Length());
@@ -1348,11 +1347,8 @@ static void Atob(const FunctionCallbackInfo<Value>& args) {
ext->data(), ext->length(), buffer.out(), simdutf::base64_default);
} else if (input->IsOneByte()) {
MaybeStackBuffer<uint8_t> stack_buf(input->Length());
- input->WriteOneByte(args.GetIsolate(),
- stack_buf.out(),
- 0,
- input->Length(),
- String::NO_NULL_TERMINATION);
+ input->WriteOneByteV2(
+ args.GetIsolate(), 0, input->Length(), stack_buf.out());
const char* data = reinterpret_cast<const char*>(*stack_buf);
size_t expected_length =
simdutf::maximal_binary_length_from_base64(data, input->Length());
diff --git a/src/node_http2.cc b/src/node_http2.cc
index 8237c9b7d325dd925ae8798d7795fcd94eeb13d0..27a0db87e1f7f75336ecaa044e7cd66a9a5e87a4 100644
--- a/src/node_http2.cc
+++ b/src/node_http2.cc
@@ -485,13 +485,10 @@ Origins::Origins(
CHECK_LE(origin_contents + origin_string_len,
static_cast<char*>(bs_->Data()) + bs_->ByteLength());
- CHECK_EQ(origin_string->WriteOneByte(
- env->isolate(),
- reinterpret_cast<uint8_t*>(origin_contents),
- 0,
- origin_string_len,
- String::NO_NULL_TERMINATION),
- origin_string_len);
+ origin_string->WriteOneByteV2(env->isolate(),
+ 0,
+ origin_string_len,
+ reinterpret_cast<uint8_t*>(origin_contents));
size_t n = 0;
char* p;
@@ -3183,8 +3180,8 @@ void Http2Session::AltSvc(const FunctionCallbackInfo<Value>& args) {
if (origin_str.IsEmpty() || value_str.IsEmpty())
return;
- size_t origin_len = origin_str->Length();
- size_t value_len = value_str->Length();
+ int origin_len = origin_str->Length();
+ int value_len = value_str->Length();
CHECK_LE(origin_len + value_len, 16382); // Max permitted for ALTSVC
// Verify that origin len != 0 if stream id == 0, or
@@ -3193,8 +3190,13 @@ void Http2Session::AltSvc(const FunctionCallbackInfo<Value>& args) {
MaybeStackBuffer<uint8_t> origin(origin_len);
MaybeStackBuffer<uint8_t> value(value_len);
- origin_str->WriteOneByte(env->isolate(), *origin);
- value_str->WriteOneByte(env->isolate(), *value);
+ origin_str->WriteOneByteV2(env->isolate(),
+ 0,
+ origin_len,
+ *origin,
+ String::WriteFlags::kNullTerminate);
+ value_str->WriteOneByteV2(
+ env->isolate(), 0, value_len, *value, String::WriteFlags::kNullTerminate);
session->AltSvc(id, *origin, origin_len, *value, value_len);
}
diff --git a/src/node_http_common-inl.h b/src/node_http_common-inl.h
index dba1a5e051b3e03c435ba3885b3fe2d04ea8ca9e..46984dba907fffb836d62b9c6e6b325a0ba504dd 100644
--- a/src/node_http_common-inl.h
+++ b/src/node_http_common-inl.h
@@ -2,9 +2,11 @@
#define SRC_NODE_HTTP_COMMON_INL_H_
#include "node_http_common.h"
+
+#include "env-inl.h"
#include "node.h"
#include "node_mem-inl.h"
-#include "env-inl.h"
+#include "string_bytes.h"
#include "v8.h"
#include <algorithm>
@@ -37,13 +39,12 @@ NgHeaders<T>::NgHeaders(Environment* env, v8::Local<v8::Array> headers) {
nv_t* const nva = reinterpret_cast<nv_t*>(start);
CHECK_LE(header_contents + header_string_len, *buf_ + buf_.length());
- CHECK_EQ(header_string.As<v8::String>()->WriteOneByte(
- env->isolate(),
- reinterpret_cast<uint8_t*>(header_contents),
- 0,
- header_string_len,
- v8::String::NO_NULL_TERMINATION),
- header_string_len);
+ CHECK_EQ(StringBytes::Write(env->isolate(),
+ header_contents,
+ header_string_len,
+ header_string.As<v8::String>(),
+ LATIN1),
+ static_cast<size_t>(header_string_len));
size_t n = 0;
char* p;
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
index b02e9c5d14c2438d30b16f977c4e8a76bb23479d..71381f8fdc341cf2bac34028eb10df30fd9306b9 100644
--- a/src/string_bytes.cc
+++ b/src/string_bytes.cc
@@ -249,11 +249,13 @@ size_t StringBytes::Write(Isolate* isolate,
nbytes = std::min(buflen, static_cast<size_t>(input_view.length()));
memcpy(buf, input_view.data8(), nbytes);
} else {
- uint8_t* const dst = reinterpret_cast<uint8_t*>(buf);
- const int flags = String::HINT_MANY_WRITES_EXPECTED |
- String::NO_NULL_TERMINATION |
- String::REPLACE_INVALID_UTF8;
- nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags);
+ nbytes = std::min(buflen, static_cast<size_t>(input_view.length()));
+ // Do not use v8::String::WriteOneByteV2 as it asserts the string to be
+ // a one byte string. For compatibility, convert the uint16_t to uint8_t
+ // even though this may loose accuracy.
+ for (size_t i = 0; i < nbytes; i++) {
+ buf[i] = static_cast<uint8_t>(input_view.data16()[i]);
+ }
}
break;
diff --git a/test/cctest/test_string_bytes.cc b/test/cctest/test_string_bytes.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bc308918680bb153dbbda8b18dcb24d129f14833
--- /dev/null
+++ b/test/cctest/test_string_bytes.cc
@@ -0,0 +1,100 @@
+#include "gtest/gtest.h"
+#include "node.h"
+#include "node_test_fixture.h"
+#include "string_bytes.h"
+#include "util-inl.h"
+
+using node::MaybeStackBuffer;
+using node::StringBytes;
+using v8::HandleScope;
+using v8::Local;
+using v8::Maybe;
+using v8::String;
+
+class StringBytesTest : public EnvironmentTestFixture {};
+
+// Data "Hello, ÆÊÎÖÿ"
+static const char latin1_data[] = "Hello, \xC6\xCA\xCE\xD6\xFF";
+static const char utf8_data[] = "Hello, ÆÊÎÖÿ";
+
+TEST_F(StringBytesTest, WriteLatin1WithOneByteString) {
+ const HandleScope handle_scope(isolate_);
+ const Argv argv;
+ Env env_{handle_scope, argv};
+
+ Local<String> one_byte_str =
+ String::NewFromOneByte(isolate_,
+ reinterpret_cast<const uint8_t*>(latin1_data))
+ .ToLocalChecked();
+
+ Maybe<size_t> size_maybe =
+ StringBytes::StorageSize(isolate_, one_byte_str, node::LATIN1);
+
+ ASSERT_TRUE(size_maybe.IsJust());
+ size_t size = size_maybe.FromJust();
+ ASSERT_EQ(size, 12u);
+
+ MaybeStackBuffer<char> buf;
+ size_t written = StringBytes::Write(
+ isolate_, buf.out(), buf.capacity(), one_byte_str, node::LATIN1);
+ ASSERT_EQ(written, 12u);
+
+ // Null-terminate the buffer and compare the contents.
+ buf.SetLength(13);
+ buf[12] = '\0';
+ ASSERT_STREQ(latin1_data, buf.out());
+}
+
+TEST_F(StringBytesTest, WriteLatin1WithUtf8String) {
+ const HandleScope handle_scope(isolate_);
+ const Argv argv;
+ Env env_{handle_scope, argv};
+
+ Local<String> utf8_str =
+ String::NewFromUtf8(isolate_, utf8_data).ToLocalChecked();
+
+ Maybe<size_t> size_maybe =
+ StringBytes::StorageSize(isolate_, utf8_str, node::LATIN1);
+
+ ASSERT_TRUE(size_maybe.IsJust());
+ size_t size = size_maybe.FromJust();
+ ASSERT_EQ(size, 12u);
+
+ MaybeStackBuffer<char> buf;
+ size_t written = StringBytes::Write(
+ isolate_, buf.out(), buf.capacity(), utf8_str, node::LATIN1);
+ ASSERT_EQ(written, 12u);
+
+ // Null-terminate the buffer and compare the contents.
+ buf.SetLength(13);
+ buf[12] = '\0';
+ ASSERT_STREQ(latin1_data, buf.out());
+}
+
+// Verify that StringBytes::Write converts two-byte characters to one-byte
+// characters, even if there is no valid one-byte representation.
+TEST_F(StringBytesTest, WriteLatin1WithInvalidChar) {
+ const HandleScope handle_scope(isolate_);
+ const Argv argv;
+ Env env_{handle_scope, argv};
+
+ Local<String> utf8_str =
+ String::NewFromUtf8(isolate_, "Hello, 世界").ToLocalChecked();
+
+ Maybe<size_t> size_maybe =
+ StringBytes::StorageSize(isolate_, utf8_str, node::LATIN1);
+
+ ASSERT_TRUE(size_maybe.IsJust());
+ size_t size = size_maybe.FromJust();
+ ASSERT_EQ(size, 9u);
+
+ MaybeStackBuffer<char> buf;
+ size_t written = StringBytes::Write(
+ isolate_, buf.out(), buf.capacity(), utf8_str, node::LATIN1);
+ ASSERT_EQ(written, 9u);
+
+ // Null-terminate the buffer and compare the contents.
+ buf.SetLength(10);
+ buf[9] = '\0';
+ ASSERT_STREQ("Hello, \x16\x4C", buf.out());
+}

View File

@@ -1,140 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
Date: Thu, 8 May 2025 13:55:26 +0100
Subject: src: refactor WriteUCS2 and remove flags argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This change refactors `StringBytes::WriteUCS2()` in multiple ways.
The `flags` argument being passed to `WriteUCS2()` is not useful: the
only really relevant flag is `NO_NULL_TERMINATION` since V8 ignores
`REPLACE_INVALID_UTF8`, `HINT_MANY_WRITES_EXPECTED`, and
`PRESERVE_ONE_BYTE_NULL` for UTF-16 strings. However, `WriteUCS2()`
might not null-terminate the result correctly regardless of whether
`NO_NULL_TERMINATION` is set because it makes multiple calls to
`String::Write()` internally. For these reasons, this patch removes the
`flags` argument entirely and always assumes `NO_NULL_TERMINATION`.
Next, this patch replaces the calls to the deprecated function
`String::Write()` with calls to the new function `String::WriteV2()`,
which always succeeds and always writes a predictable number of
characters, removing the need to deal with a return value here.
Lastly, this patch simplifies the implementation of `WriteUCS2()` and
computes the exact number of characters `nchars` from the beginning,
removing the need to later check again if the number of characters is
zero.
PR-URL: https://github.com/nodejs/node/pull/58163
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
index 0eb9b1967f1f185a140239924809468394297d58..b02e9c5d14c2438d30b16f977c4e8a76bb23479d 100644
--- a/src/string_bytes.cc
+++ b/src/string_bytes.cc
@@ -198,40 +198,34 @@ MaybeLocal<Value> ExternTwoByteString::NewSimpleFromCopy(Isolate* isolate,
} // anonymous namespace
-size_t StringBytes::WriteUCS2(
- Isolate* isolate, char* buf, size_t buflen, Local<String> str, int flags) {
+size_t StringBytes::WriteUCS2(Isolate* isolate,
+ char* buf,
+ size_t buflen,
+ Local<String> str) {
uint16_t* const dst = reinterpret_cast<uint16_t*>(buf);
- size_t max_chars = buflen / sizeof(*dst);
- if (max_chars == 0) {
+ const size_t max_chars = buflen / sizeof(*dst);
+ const size_t nchars = std::min(max_chars, static_cast<size_t>(str->Length()));
+ if (nchars == 0) {
return 0;
}
uint16_t* const aligned_dst = nbytes::AlignUp(dst, sizeof(*dst));
- size_t nchars;
+ CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);
if (aligned_dst == dst) {
- nchars = str->Write(isolate, dst, 0, max_chars, flags);
- return nchars * sizeof(*dst);
- }
+ str->WriteV2(isolate, 0, nchars, dst);
+ } else {
+ // Write all but the last char.
+ str->WriteV2(isolate, 0, nchars - 1, aligned_dst);
- CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);
+ // Shift everything to unaligned-left.
+ memmove(dst, aligned_dst, (nchars - 1) * sizeof(*dst));
- // Write all but the last char
- max_chars = std::min(max_chars, static_cast<size_t>(str->Length()));
- if (max_chars == 0) {
- return 0;
+ // One more char to be written.
+ uint16_t last;
+ str->WriteV2(isolate, nchars - 1, 1, &last);
+ memcpy(dst + nchars - 1, &last, sizeof(last));
}
- nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
- CHECK_EQ(nchars, max_chars - 1);
-
- // Shift everything to unaligned-left
- memmove(dst, aligned_dst, nchars * sizeof(*dst));
-
- // One more char to be written
- uint16_t last;
- CHECK_EQ(str->Write(isolate, &last, nchars, 1, flags), 1);
- memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
- nchars++;
return nchars * sizeof(*dst);
}
@@ -248,10 +242,6 @@ size_t StringBytes::Write(Isolate* isolate,
Local<String> str = val.As<String>();
String::ValueView input_view(isolate, str);
- int flags = String::HINT_MANY_WRITES_EXPECTED |
- String::NO_NULL_TERMINATION |
- String::REPLACE_INVALID_UTF8;
-
switch (encoding) {
case ASCII:
case LATIN1:
@@ -260,6 +250,9 @@ size_t StringBytes::Write(Isolate* isolate,
memcpy(buf, input_view.data8(), nbytes);
} else {
uint8_t* const dst = reinterpret_cast<uint8_t*>(buf);
+ const int flags = String::HINT_MANY_WRITES_EXPECTED |
+ String::NO_NULL_TERMINATION |
+ String::REPLACE_INVALID_UTF8;
nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags);
}
break;
@@ -271,7 +264,7 @@ size_t StringBytes::Write(Isolate* isolate,
break;
case UCS2: {
- nbytes = WriteUCS2(isolate, buf, buflen, str, flags);
+ nbytes = WriteUCS2(isolate, buf, buflen, str);
// Node's "ucs2" encoding wants LE character data stored in
// the Buffer, so we need to reorder on BE platforms. See
diff --git a/src/string_bytes.h b/src/string_bytes.h
index 53bc003fbda43663d6b8619672b23803fc88deb6..2a916b1c6a03b53c15e96e050dfa5711caaa07e2 100644
--- a/src/string_bytes.h
+++ b/src/string_bytes.h
@@ -102,8 +102,7 @@ class StringBytes {
static size_t WriteUCS2(v8::Isolate* isolate,
char* buf,
size_t buflen,
- v8::Local<v8::String> str,
- int flags);
+ v8::Local<v8::String> str);
};
} // namespace node

View File

@@ -1,308 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joyee Cheung <joyeec9h3@gmail.com>
Date: Wed, 29 May 2024 19:59:19 +0200
Subject: src: remove dependency on wrapper-descriptor-based CppHeap
As V8 has moved away from wrapper-descriptor-based CppHeap, this
patch:
1. Create the CppHeap without using wrapper descirptors.
2. Deprecates node::SetCppgcReference() in favor of
v8::Object::Wrap() since the wrapper descriptor is no longer
relevant. It is still kept as a compatibility layer for addons
that need to also work on Node.js versions without
v8::Object::Wrap().
(cherry picked from commit 30329d06235a9f9733b1d4da479b403462d1b326)
diff --git a/src/env-inl.h b/src/env-inl.h
index 67b4cc2037b8e02f6382cd12a7abb157d0dbac65..4906c6c4c0ab5260d6e6387d0ed8e0687f982a38 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -62,31 +62,6 @@ inline uv_loop_t* IsolateData::event_loop() const {
return event_loop_;
}
-inline void IsolateData::SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable) {
- v8::CppHeap* heap = isolate->GetCppHeap();
- CHECK_NOT_NULL(heap);
- v8::WrapperDescriptor descriptor = heap->wrapper_descriptor();
- uint16_t required_size = std::max(descriptor.wrappable_instance_index,
- descriptor.wrappable_type_index);
- CHECK_GT(object->InternalFieldCount(), required_size);
-
- uint16_t* id_ptr = nullptr;
- {
- Mutex::ScopedLock lock(isolate_data_mutex_);
- auto it =
- wrapper_data_map_.find(descriptor.embedder_id_for_garbage_collected);
- CHECK_NE(it, wrapper_data_map_.end());
- id_ptr = &(it->second->cppgc_id);
- }
-
- object->SetAlignedPointerInInternalField(descriptor.wrappable_type_index,
- id_ptr);
- object->SetAlignedPointerInInternalField(descriptor.wrappable_instance_index,
- wrappable);
-}
-
inline uint16_t* IsolateData::embedder_id_for_cppgc() const {
return &(wrapper_data_->cppgc_id);
}
diff --git a/src/env.cc b/src/env.cc
index 926645dc647fe7ca01165462f08eac1ade71ac4e..85641b68b1e6f6dd4149f33ba13f76bccc8bf47d 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -23,6 +23,7 @@
#include "util-inl.h"
#include "v8-cppgc.h"
#include "v8-profiler.h"
+#include "v8-sandbox.h" // v8::Object::Wrap(), v8::Object::Unwrap()
#include <algorithm>
#include <atomic>
@@ -72,7 +73,6 @@ using v8::TryCatch;
using v8::Uint32;
using v8::Undefined;
using v8::Value;
-using v8::WrapperDescriptor;
using worker::Worker;
int const ContextEmbedderTag::kNodeContextTag = 0x6e6f64;
@@ -530,6 +530,14 @@ void IsolateData::CreateProperties() {
CreateEnvProxyTemplate(this);
}
+// Previously, the general convention of the wrappable layout for cppgc in
+// the ecosystem is:
+// [ 0 ] -> embedder id
+// [ 1 ] -> wrappable instance
+// Now V8 has deprecated this layout-based tracing enablement, embedders
+// should simply use v8::Object::Wrap() and v8::Object::Unwrap(). We preserve
+// this layout only to distinguish internally how the memory of a Node.js
+// wrapper is managed or whether a wrapper is managed by Node.js.
constexpr uint16_t kDefaultCppGCEmbedderID = 0x90de;
Mutex IsolateData::isolate_data_mutex_;
std::unordered_map<uint16_t, std::unique_ptr<PerIsolateWrapperData>>
@@ -567,36 +575,16 @@ IsolateData::IsolateData(Isolate* isolate,
v8::CppHeap* cpp_heap = isolate->GetCppHeap();
uint16_t cppgc_id = kDefaultCppGCEmbedderID;
- if (cpp_heap != nullptr) {
- // The general convention of the wrappable layout for cppgc in the
- // ecosystem is:
- // [ 0 ] -> embedder id
- // [ 1 ] -> wrappable instance
- // If the Isolate includes a CppHeap attached by another embedder,
- // And if they also use the field 0 for the ID, we DCHECK that
- // the layout matches our layout, and record the embedder ID for cppgc
- // to avoid accidentally enabling cppgc on non-cppgc-managed wrappers .
- v8::WrapperDescriptor descriptor = cpp_heap->wrapper_descriptor();
- if (descriptor.wrappable_type_index == BaseObject::kEmbedderType) {
- cppgc_id = descriptor.embedder_id_for_garbage_collected;
- DCHECK_EQ(descriptor.wrappable_instance_index, BaseObject::kSlot);
- }
- // If the CppHeap uses the slot we use to put non-cppgc-traced BaseObject
- // for embedder ID, V8 could accidentally enable cppgc on them. So
- // safe guard against this.
- DCHECK_NE(descriptor.wrappable_type_index, BaseObject::kSlot);
- } else {
- cpp_heap_ = CppHeap::Create(
- platform,
- CppHeapCreateParams{
- {},
- WrapperDescriptor(
- BaseObject::kEmbedderType, BaseObject::kSlot, cppgc_id)});
- isolate->AttachCppHeap(cpp_heap_.get());
- }
// We do not care about overflow since we just want this to be different
// from the cppgc id.
uint16_t non_cppgc_id = cppgc_id + 1;
+ if (cpp_heap == nullptr) {
+ cpp_heap_ = CppHeap::Create(platform, v8::CppHeapCreateParams{{}});
+ // TODO(joyeecheung): pass it into v8::Isolate::CreateParams and let V8
+ // own it when we can keep the isolate registered/task runner discoverable
+ // during isolate disposal.
+ isolate->AttachCppHeap(cpp_heap_.get());
+ }
{
// GC could still be run after the IsolateData is destroyed, so we store
@@ -629,11 +617,12 @@ IsolateData::~IsolateData() {
}
}
-// Public API
+// Deprecated API, embedders should use v8::Object::Wrap() directly instead.
void SetCppgcReference(Isolate* isolate,
Local<Object> object,
void* wrappable) {
- IsolateData::SetCppgcReference(isolate, object, wrappable);
+ v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(
+ isolate, object, static_cast<v8::Object::Wrappable*>(wrappable));
}
void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
diff --git a/src/env.h b/src/env.h
index 35e16159a94bb97f19d17767e3ad4bb798660f44..2d5fa8dbd75851bca30453548f6cbe0159509f26 100644
--- a/src/env.h
+++ b/src/env.h
@@ -177,10 +177,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
uint16_t* embedder_id_for_cppgc() const;
uint16_t* embedder_id_for_non_cppgc() const;
- static inline void SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable);
-
inline uv_loop_t* event_loop() const;
inline MultiIsolatePlatform* platform() const;
inline const SnapshotData* snapshot_data() const;
diff --git a/src/node.h b/src/node.h
index 96c599aa6448e2aa8e57e84f811564a5281c139a..d3a965661d068db359bb1bb4b14e59c28bb615f9 100644
--- a/src/node.h
+++ b/src/node.h
@@ -1576,24 +1576,14 @@ void RegisterSignalHandler(int signal,
bool reset_handler = false);
#endif // _WIN32
-// Configure the layout of the JavaScript object with a cppgc::GarbageCollected
-// instance so that when the JavaScript object is reachable, the garbage
-// collected instance would have its Trace() method invoked per the cppgc
-// contract. To make it work, the process must have called
-// cppgc::InitializeProcess() before, which is usually the case for addons
-// loaded by the stand-alone Node.js executable. Embedders of Node.js can use
-// either need to call it themselves or make sure that
-// ProcessInitializationFlags::kNoInitializeCppgc is *not* set for cppgc to
-// work.
-// If the CppHeap is owned by Node.js, which is usually the case for addon,
-// the object must be created with at least two internal fields available,
-// and the first two internal fields would be configured by Node.js.
-// This may be superseded by a V8 API in the future, see
-// https://bugs.chromium.org/p/v8/issues/detail?id=13960. Until then this
-// serves as a helper for Node.js isolates.
-NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate,
- v8::Local<v8::Object> object,
- void* wrappable);
+// This is kept as a compatibility layer for addons to wrap cppgc-managed
+// objects on Node.js versions without v8::Object::Wrap(). Addons created to
+// work with only Node.js versions with v8::Object::Wrap() should use that
+// instead.
+NODE_DEPRECATED("Use v8::Object::Wrap()",
+ NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate,
+ v8::Local<v8::Object> object,
+ void* wrappable));
} // namespace node
diff --git a/test/addons/cppgc-object/binding.cc b/test/addons/cppgc-object/binding.cc
index 1b70ff11dc561abdc5ac794f6280557d5c428239..7fc16a87b843ce0626ee137a07c3ccb7f4cc6493 100644
--- a/test/addons/cppgc-object/binding.cc
+++ b/test/addons/cppgc-object/binding.cc
@@ -1,8 +1,10 @@
+#include <assert.h>
#include <cppgc/allocation.h>
#include <cppgc/garbage-collected.h>
#include <cppgc/heap.h>
#include <node.h>
#include <v8-cppgc.h>
+#include <v8-sandbox.h>
#include <v8.h>
#include <algorithm>
@@ -15,8 +17,10 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static void New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::Local<v8::Object> js_object = args.This();
- CppGCed* gc_object = cppgc::MakeGarbageCollected<CppGCed>(
- isolate->GetCppHeap()->GetAllocationHandle());
+ auto* heap = isolate->GetCppHeap();
+ assert(heap != nullptr);
+ CppGCed* gc_object =
+ cppgc::MakeGarbageCollected<CppGCed>(heap->GetAllocationHandle());
node::SetCppgcReference(isolate, js_object, gc_object);
args.GetReturnValue().Set(js_object);
}
@@ -24,12 +28,6 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static v8::Local<v8::Function> GetConstructor(
v8::Local<v8::Context> context) {
auto ft = v8::FunctionTemplate::New(context->GetIsolate(), New);
- auto ot = ft->InstanceTemplate();
- v8::WrapperDescriptor descriptor =
- context->GetIsolate()->GetCppHeap()->wrapper_descriptor();
- uint16_t required_size = std::max(descriptor.wrappable_instance_index,
- descriptor.wrappable_type_index);
- ot->SetInternalFieldCount(required_size + 1);
return ft->GetFunction(context).ToLocalChecked();
}
diff --git a/test/cctest/test_cppgc.cc b/test/cctest/test_cppgc.cc
index 49665174615870b4f70529b1d548e593846140a1..edd413ae9b956b2e59e8166785adef6a8ff06d51 100644
--- a/test/cctest/test_cppgc.cc
+++ b/test/cctest/test_cppgc.cc
@@ -3,16 +3,12 @@
#include <cppgc/heap.h>
#include <node.h>
#include <v8-cppgc.h>
+#include <v8-sandbox.h>
#include <v8.h>
#include "node_test_fixture.h"
// This tests that Node.js can work with an existing CppHeap.
-// Mimic the Blink layout.
-static int kWrappableTypeIndex = 0;
-static int kWrappableInstanceIndex = 1;
-static uint16_t kEmbedderID = 0x1;
-
// Mimic a class that does not know about Node.js.
class CppGCed : public cppgc::GarbageCollected<CppGCed> {
public:
@@ -23,12 +19,11 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static void New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::Local<v8::Object> js_object = args.This();
- CppGCed* gc_object = cppgc::MakeGarbageCollected<CppGCed>(
- isolate->GetCppHeap()->GetAllocationHandle());
- js_object->SetAlignedPointerInInternalField(kWrappableTypeIndex,
- &kEmbedderID);
- js_object->SetAlignedPointerInInternalField(kWrappableInstanceIndex,
- gc_object);
+ auto* heap = isolate->GetCppHeap();
+ CHECK_NOT_NULL(heap);
+ CppGCed* gc_object =
+ cppgc::MakeGarbageCollected<CppGCed>(heap->GetAllocationHandle());
+ node::SetCppgcReference(isolate, js_object, gc_object);
kConstructCount++;
args.GetReturnValue().Set(js_object);
}
@@ -36,8 +31,6 @@ class CppGCed : public cppgc::GarbageCollected<CppGCed> {
static v8::Local<v8::Function> GetConstructor(
v8::Local<v8::Context> context) {
auto ft = v8::FunctionTemplate::New(context->GetIsolate(), New);
- auto ot = ft->InstanceTemplate();
- ot->SetInternalFieldCount(2);
return ft->GetFunction(context).ToLocalChecked();
}
@@ -58,12 +51,12 @@ TEST_F(NodeZeroIsolateTestFixture, ExistingCppHeapTest) {
// Create and attach the CppHeap before we set up the IsolateData so that
// it recognizes the existing heap.
- std::unique_ptr<v8::CppHeap> cpp_heap = v8::CppHeap::Create(
- platform.get(),
- v8::CppHeapCreateParams(
- {},
- v8::WrapperDescriptor(
- kWrappableTypeIndex, kWrappableInstanceIndex, kEmbedderID)));
+ std::unique_ptr<v8::CppHeap> cpp_heap =
+ v8::CppHeap::Create(platform.get(), v8::CppHeapCreateParams{{}});
+
+ // TODO(joyeecheung): pass it into v8::Isolate::CreateParams and let V8
+ // own it when we can keep the isolate registered/task runner discoverable
+ // during isolate disposal.
isolate->AttachCppHeap(cpp_heap.get());
// Try creating Context + IsolateData + Environment.

View File

@@ -1,150 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Lemire <daniel@lemire.me>
Date: Thu, 12 Sep 2024 12:07:08 -0400
Subject: src: simplify string_bytes with views
PR-URL: https://github.com/nodejs/node/pull/54876
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
index addb7e21ba6a3bbabf3ff5f32240a5e428d176ee..f0fbf496dcfdec2c522508c61ae24fb20b1eb081 100644
--- a/src/string_bytes.cc
+++ b/src/string_bytes.cc
@@ -246,6 +246,7 @@ size_t StringBytes::Write(Isolate* isolate,
CHECK(val->IsString() == true);
Local<String> str = val.As<String>();
+ String::ValueView input_view(isolate, str);
int flags = String::HINT_MANY_WRITES_EXPECTED |
String::NO_NULL_TERMINATION |
@@ -254,10 +255,9 @@ size_t StringBytes::Write(Isolate* isolate,
switch (encoding) {
case ASCII:
case LATIN1:
- if (str->IsExternalOneByte()) {
- auto ext = str->GetExternalOneByteStringResource();
- nbytes = std::min(buflen, ext->length());
- memcpy(buf, ext->data(), nbytes);
+ if (input_view.is_one_byte()) {
+ nbytes = std::min(buflen, static_cast<size_t>(input_view.length()));
+ memcpy(buf, input_view.data8(), nbytes);
} else {
uint8_t* const dst = reinterpret_cast<uint8_t*>(buf);
nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags);
@@ -282,31 +282,11 @@ size_t StringBytes::Write(Isolate* isolate,
}
case BASE64URL:
- if (str->IsExternalOneByte()) { // 8-bit case
- auto ext = str->GetExternalOneByteStringResource();
+ if (input_view.is_one_byte()) { // 8-bit case
size_t written_len = buflen;
auto result = simdutf::base64_to_binary_safe(
- ext->data(), ext->length(), buf, written_len, simdutf::base64_url);
- if (result.error == simdutf::error_code::SUCCESS) {
- nbytes = written_len;
- } else {
- // The input does not follow the WHATWG forgiving-base64 specification
- // adapted for base64url
- // https://infra.spec.whatwg.org/#forgiving-base64-decode
- nbytes =
- nbytes::Base64Decode(buf, buflen, ext->data(), ext->length());
- }
- } else if (str->IsOneByte()) {
- MaybeStackBuffer<uint8_t> stack_buf(str->Length());
- str->WriteOneByte(isolate,
- stack_buf.out(),
- 0,
- str->Length(),
- String::NO_NULL_TERMINATION);
- size_t written_len = buflen;
- auto result = simdutf::base64_to_binary_safe(
- reinterpret_cast<const char*>(*stack_buf),
- stack_buf.length(),
+ reinterpret_cast<const char*>(input_view.data8()),
+ input_view.length(),
buf,
written_len,
simdutf::base64_url);
@@ -316,8 +296,11 @@ size_t StringBytes::Write(Isolate* isolate,
// The input does not follow the WHATWG forgiving-base64 specification
// (adapted for base64url with + and / replaced by - and _).
// https://infra.spec.whatwg.org/#forgiving-base64-decode
- nbytes =
- nbytes::Base64Decode(buf, buflen, *stack_buf, stack_buf.length());
+ nbytes = nbytes::Base64Decode(
+ buf,
+ buflen,
+ reinterpret_cast<const char*>(input_view.data8()),
+ input_view.length());
}
} else {
String::Value value(isolate, str);
@@ -340,40 +323,23 @@ size_t StringBytes::Write(Isolate* isolate,
break;
case BASE64: {
- if (str->IsExternalOneByte()) { // 8-bit case
- auto ext = str->GetExternalOneByteStringResource();
+ if (input_view.is_one_byte()) { // 8-bit case
size_t written_len = buflen;
auto result = simdutf::base64_to_binary_safe(
- ext->data(), ext->length(), buf, written_len);
- if (result.error == simdutf::error_code::SUCCESS) {
- nbytes = written_len;
- } else {
- // The input does not follow the WHATWG forgiving-base64 specification
- // https://infra.spec.whatwg.org/#forgiving-base64-decode
- nbytes =
- nbytes::Base64Decode(buf, buflen, ext->data(), ext->length());
- }
- } else if (str->IsOneByte()) {
- MaybeStackBuffer<uint8_t> stack_buf(str->Length());
- str->WriteOneByte(isolate,
- stack_buf.out(),
- 0,
- str->Length(),
- String::NO_NULL_TERMINATION);
- size_t written_len = buflen;
- auto result = simdutf::base64_to_binary_safe(
- reinterpret_cast<const char*>(*stack_buf),
- stack_buf.length(),
+ reinterpret_cast<const char*>(input_view.data8()),
+ input_view.length(),
buf,
written_len);
if (result.error == simdutf::error_code::SUCCESS) {
nbytes = written_len;
} else {
// The input does not follow the WHATWG forgiving-base64 specification
- // (adapted for base64url with + and / replaced by - and _).
// https://infra.spec.whatwg.org/#forgiving-base64-decode
- nbytes =
- nbytes::Base64Decode(buf, buflen, *stack_buf, stack_buf.length());
+ nbytes = nbytes::Base64Decode(
+ buf,
+ buflen,
+ reinterpret_cast<const char*>(input_view.data8()),
+ input_view.length());
}
} else {
String::Value value(isolate, str);
@@ -394,9 +360,12 @@ size_t StringBytes::Write(Isolate* isolate,
break;
}
case HEX:
- if (str->IsExternalOneByte()) {
- auto ext = str->GetExternalOneByteStringResource();
- nbytes = nbytes::HexDecode(buf, buflen, ext->data(), ext->length());
+ if (input_view.is_one_byte()) {
+ nbytes =
+ nbytes::HexDecode(buf,
+ buflen,
+ reinterpret_cast<const char*>(input_view.data8()),
+ input_view.length());
} else {
String::Value value(isolate, str);
nbytes = nbytes::HexDecode(buf, buflen, *value, value.length());

View File

@@ -1,73 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andreas Haas <ahaas@chromium.org>
Date: Sun, 28 Jul 2024 09:20:12 +0200
Subject: src: stop using deprecated fields of `v8::FastApiCallbackOptions`
Two fields on the `v8::FastApiCallbackOptions` struct were deprecated
recently: `fallback` and `wasm_memory`. This PR removes uses of these
two fields in node.js.
(This is a subset of upstream commit d0000b118 from the `canary-base`
branch of Node.js. This patch can be removed when Electron upgrades to
a stable Node release that contains the change. -- Charles)
diff --git a/src/crypto/crypto_timing.cc b/src/crypto/crypto_timing.cc
index dbc46400501b61814d5be0ec1cb01b0dcd94e1d0..fe669d40c31a29334b047b9cfee3067f64ef0a7b 100644
--- a/src/crypto/crypto_timing.cc
+++ b/src/crypto/crypto_timing.cc
@@ -60,7 +60,8 @@ bool FastTimingSafeEqual(Local<Value> receiver,
if (a.length() != b.length() || !a.getStorageIfAligned(&data_a) ||
!b.getStorageIfAligned(&data_b)) {
TRACK_V8_FAST_API_CALL("crypto.timingSafeEqual.error");
- options.fallback = true;
+ v8::HandleScope scope(options.isolate);
+ THROW_ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH(options.isolate);
return false;
}
diff --git a/src/histogram.cc b/src/histogram.cc
index b655808e43d7c700ddeab7690e287bdbc9bfa50a..b0f7ae4e3af652c6dfe09f66d88485c5783f4037 100644
--- a/src/histogram.cc
+++ b/src/histogram.cc
@@ -187,7 +187,8 @@ void HistogramBase::FastRecord(Local<Value> unused,
const int64_t value,
FastApiCallbackOptions& options) {
if (value < 1) {
- options.fallback = true;
+ Environment* env = Environment::GetCurrent(options.isolate);
+ THROW_ERR_OUT_OF_RANGE(env, "value is out of range");
return;
}
HistogramBase* histogram;
diff --git a/src/node_wasi.cc b/src/node_wasi.cc
index 090866960beb8f1759c99e95536924b8b61fb723..3f91b651b83a20e70d5b368e012f5ee4b9d16092 100644
--- a/src/node_wasi.cc
+++ b/src/node_wasi.cc
@@ -275,17 +275,19 @@ R WASI::WasiFunction<FT, F, R, Args...>::FastCallback(
return EinvalError<R>();
}
- if (options.wasm_memory == nullptr || wasi->memory_.IsEmpty()) [[unlikely]] {
- // fallback to slow path which to throw an error about missing memory.
- options.fallback = true;
+ v8::Isolate* isolate = receiver->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+ if (wasi->memory_.IsEmpty()) {
+ THROW_ERR_WASI_NOT_STARTED(isolate);
return EinvalError<R>();
}
- uint8_t* memory = nullptr;
- CHECK(options.wasm_memory->getStorageIfAligned(&memory));
- return F(*wasi,
- {reinterpret_cast<char*>(memory), options.wasm_memory->length()},
- args...);
+ Local<ArrayBuffer> ab = wasi->memory_.Get(isolate)->Buffer();
+ size_t mem_size = ab->ByteLength();
+ char* mem_data = static_cast<char*>(ab->Data());
+ CHECK_NOT_NULL(mem_data);
+
+ return F(*wasi, {mem_data, mem_size}, args...);
}
namespace {

View File

@@ -1,173 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aviv Keller <redyetidev@gmail.com>
Date: Tue, 22 Oct 2024 01:05:19 -0400
Subject: src: switch from `Get/SetPrototype` to `Get/SetPrototypeV2`
PR-URL: https://github.com/nodejs/node/pull/55453
Reviewed-By: Vladimir Morozov <vmorozov@microsoft.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 82f53bba29613de212f64be440ca20d7c630fddf..0a358735c331767e8eb563a80e9aaccfb544c27b 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -886,7 +886,7 @@ Maybe<void> InitializePrimordials(Local<Context> context,
CHECK(!exports->Has(context, primordials_string).FromJust());
Local<Object> primordials = Object::New(isolate);
- if (primordials->SetPrototype(context, Null(isolate)).IsNothing() ||
+ if (primordials->SetPrototypeV2(context, Null(isolate)).IsNothing() ||
exports->Set(context, primordials_string, primordials).IsNothing()) {
return Nothing<void>();
}
diff --git a/src/internal_only_v8.cc b/src/internal_only_v8.cc
index 487b8b7adfd35646d20fdb15be5fd6f2bee9315b..6a3c4e6952a8f3250bf1b57652a1622e9f63ec52 100644
--- a/src/internal_only_v8.cc
+++ b/src/internal_only_v8.cc
@@ -33,8 +33,8 @@ class PrototypeChainHas : public v8::QueryObjectPredicate {
if (creation_context != context_) {
return false;
}
- for (Local<Value> proto = object->GetPrototype(); proto->IsObject();
- proto = proto.As<Object>()->GetPrototype()) {
+ for (Local<Value> proto = object->GetPrototypeV2(); proto->IsObject();
+ proto = proto.As<Object>()->GetPrototypeV2()) {
if (search_ == proto) return true;
}
return false;
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
index de3d1f2f1832740b24480267f8c573794179859c..6e1680a74e21240ab99be86dcf23e60a05174888 100644
--- a/src/js_native_api_v8.cc
+++ b/src/js_native_api_v8.cc
@@ -1577,7 +1577,7 @@ napi_status NAPI_CDECL napi_get_prototype(napi_env env,
CHECK_TO_OBJECT(env, context, obj, object);
// This doesn't invokes Proxy's [[GetPrototypeOf]] handler.
- v8::Local<v8::Value> val = obj->GetPrototype();
+ v8::Local<v8::Value> val = obj->GetPrototypeV2();
*result = v8impl::JsValueFromV8LocalValue(val);
return GET_RETURN_STATUS(env);
}
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index c94b14741c827a81d69a6f036426a344e563ad72..15129e4455fdc8792f21511a04d534ba3a4ebb5f 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -284,8 +284,9 @@ MaybeLocal<Uint8Array> New(Environment* env,
size_t length) {
CHECK(!env->buffer_prototype_object().IsEmpty());
Local<Uint8Array> ui = Uint8Array::New(ab, byte_offset, length);
- if (ui->SetPrototype(env->context(), env->buffer_prototype_object())
- .IsNothing()) {
+ Maybe<bool> mb =
+ ui->SetPrototypeV2(env->context(), env->buffer_prototype_object());
+ if (mb.IsNothing()) {
return MaybeLocal<Uint8Array>();
}
return ui;
diff --git a/src/node_constants.cc b/src/node_constants.cc
index b1ee513fc0873a51b4885f612dbf7b950b5cf2ca..2f23cc63f148a792f1302e1d2d88822730abaa33 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -1267,43 +1267,44 @@ void CreatePerContextProperties(Local<Object> target,
Isolate* isolate = Isolate::GetCurrent();
Environment* env = Environment::GetCurrent(context);
- CHECK(target->SetPrototype(env->context(), Null(env->isolate())).FromJust());
+ CHECK(
+ target->SetPrototypeV2(env->context(), Null(env->isolate())).FromJust());
Local<Object> os_constants = Object::New(isolate);
- CHECK(os_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(os_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> err_constants = Object::New(isolate);
- CHECK(err_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(err_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> sig_constants = Object::New(isolate);
- CHECK(sig_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(sig_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> priority_constants = Object::New(isolate);
- CHECK(priority_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(priority_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> fs_constants = Object::New(isolate);
- CHECK(fs_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(fs_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> crypto_constants = Object::New(isolate);
- CHECK(crypto_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(crypto_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> zlib_constants = Object::New(isolate);
- CHECK(zlib_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(zlib_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> dlopen_constants = Object::New(isolate);
- CHECK(dlopen_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(dlopen_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> trace_constants = Object::New(isolate);
- CHECK(trace_constants->SetPrototype(env->context(),
- Null(env->isolate())).FromJust());
+ CHECK(trace_constants->SetPrototypeV2(env->context(), Null(env->isolate()))
+ .FromJust());
Local<Object> internal_constants = Object::New(isolate);
CHECK(internal_constants->SetPrototype(env->context(),
diff --git a/src/node_options.cc b/src/node_options.cc
index 556776b79282d953fdc371d1901f21ca301bec1a..b33193c4d017b35aec5e73c1ead04cfb3ba50d55 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1493,7 +1493,8 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
Local<Map> options = Map::New(isolate);
if (options
- ->SetPrototype(context, env->primordials_safe_map_prototype_object())
+ ->SetPrototypeV2(context,
+ env->primordials_safe_map_prototype_object())
.IsNothing()) {
return;
}
@@ -1533,7 +1534,8 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
if (!ToV8Value(context, _ppop_instance.aliases_).ToLocal(&aliases)) return;
if (aliases.As<Object>()
- ->SetPrototype(context, env->primordials_safe_map_prototype_object())
+ ->SetPrototypeV2(context,
+ env->primordials_safe_map_prototype_object())
.IsNothing()) {
return;
}
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
index 1705e430099c5a363e02010f83d729b0aa54f8e5..0577777723747327dc57830ace316aebc0cfd891 100644
--- a/src/node_webstorage.cc
+++ b/src/node_webstorage.cc
@@ -532,7 +532,7 @@ template <typename T>
static bool ShouldIntercept(Local<Name> property,
const PropertyCallbackInfo<T>& info) {
Environment* env = Environment::GetCurrent(info);
- Local<Value> proto = info.This()->GetPrototype();
+ Local<Value> proto = info.This()->GetPrototypeV2();
if (proto->IsObject()) {
bool has_prop;

View File

@@ -1,87 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yagiz Nizipli <yagiz@nizipli.com>
Date: Thu, 17 Apr 2025 10:57:40 -0400
Subject: src: use non-deprecated Utf8LengthV2() method
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
diff --git a/benchmark/napi/function_args/binding.cc b/benchmark/napi/function_args/binding.cc
index 078fe0ee3ea767616e7b938fe4a2fb8d6a2b8d6e..e7c3cb40586ce9f99a57f3d26944e03738bdbabd 100644
--- a/benchmark/napi/function_args/binding.cc
+++ b/benchmark/napi/function_args/binding.cc
@@ -21,7 +21,7 @@ void CallWithString(const FunctionCallbackInfo<Value>& args) {
assert(args.Length() == 1 && args[0]->IsString());
if (args.Length() == 1 && args[0]->IsString()) {
Local<String> str = args[0].As<String>();
- const int32_t length = str->Utf8Length(args.GetIsolate()) + 1;
+ const size_t length = str->Utf8LengthV2(args.GetIsolate()) + 1;
char* buf = new char[length];
str->WriteUtf8(args.GetIsolate(), buf, length);
delete[] buf;
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index 7eea2eaefcad5780663a6b87985925ae5d70a5f9..b9a7710ef3cc516ff89aee0da0a8f142507605e3 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -445,7 +445,7 @@ ByteSource ByteSource::FromStringOrBuffer(Environment* env,
ByteSource ByteSource::FromString(Environment* env, Local<String> str,
bool ntc) {
CHECK(str->IsString());
- size_t size = str->Utf8Length(env->isolate());
+ size_t size = str->Utf8LengthV2(env->isolate());
size_t alloc_size = ntc ? size + 1 : size;
ByteSource::Builder out(alloc_size);
int opts = String::NO_OPTIONS;
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
index 5ace688bb7ffc86eedf5aff11ab0ab487ad9440e..2d45bbe60f413121b3fd0f01802aeb4368f0c301 100644
--- a/src/encoding_binding.cc
+++ b/src/encoding_binding.cc
@@ -119,7 +119,7 @@ void BindingData::EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());
Local<String> str = args[0].As<String>();
- size_t length = str->Utf8Length(isolate);
+ size_t length = str->Utf8LengthV2(isolate);
Local<ArrayBuffer> ab;
{
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
index 6e1680a74e21240ab99be86dcf23e60a05174888..a84fdae795dc1cb367a2e446264575c550ce07ee 100644
--- a/src/js_native_api_v8.cc
+++ b/src/js_native_api_v8.cc
@@ -2482,7 +2482,7 @@ napi_status NAPI_CDECL napi_get_value_string_utf8(
if (!buf) {
CHECK_ARG(env, result);
- *result = val.As<v8::String>()->Utf8Length(env->isolate);
+ *result = val.As<v8::String>()->Utf8LengthV2(env->isolate);
} else if (bufsize != 0) {
int copied = val.As<v8::String>()->WriteUtf8(
env->isolate,
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 15129e4455fdc8792f21511a04d534ba3a4ebb5f..ae73e6743879f32f08b4f6f8c546c587de71d2f3 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -662,7 +662,7 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
// Can't use StringBytes::Write() in all cases. For example if attempting
// to write a two byte character into a one byte Buffer.
if (enc == UTF8) {
- str_length = str_obj->Utf8Length(env->isolate());
+ str_length = str_obj->Utf8LengthV2(env->isolate());
node::Utf8Value str(env->isolate(), args[1]);
memcpy(ts_obj_data + start, *str, std::min(str_length, fill_length));
@@ -750,8 +750,8 @@ void SlowByteLengthUtf8(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());
// Fast case: avoid StringBytes on UTF8 string. Jump to v8.
- args.GetReturnValue().Set(
- args[0].As<String>()->Utf8Length(args.GetIsolate()));
+ size_t result = args[0].As<String>()->Utf8LengthV2(args.GetIsolate());
+ args.GetReturnValue().Set(static_cast<uint64_t>(result));
}
uint32_t FastByteLengthUtf8(Local<Value> receiver,

View File

@@ -1,138 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yagiz Nizipli <yagiz@nizipli.com>
Date: Thu, 17 Apr 2025 11:36:25 -0400
Subject: src: use non-deprecated WriteUtf8V2() method
PR-URL: https://github.com/nodejs/node/pull/58070
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index b9a7710ef3cc516ff89aee0da0a8f142507605e3..73bfa6ac5e6e2b837b1bbc4a6d5f337fc0b79913 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -29,6 +29,7 @@ namespace node {
using ncrypto::BignumPointer;
using ncrypto::BIOPointer;
using ncrypto::CryptoErrorList;
+using ncrypto::DataPointer;
#ifndef OPENSSL_NO_ENGINE
using ncrypto::EnginePointer;
#endif // !OPENSSL_NO_ENGINE
@@ -447,11 +448,12 @@ ByteSource ByteSource::FromString(Environment* env, Local<String> str,
CHECK(str->IsString());
size_t size = str->Utf8LengthV2(env->isolate());
size_t alloc_size = ntc ? size + 1 : size;
- ByteSource::Builder out(alloc_size);
- int opts = String::NO_OPTIONS;
- if (!ntc) opts |= String::NO_NULL_TERMINATION;
- str->WriteUtf8(env->isolate(), out.data<char>(), alloc_size, nullptr, opts);
- return std::move(out).release();
+ auto out = DataPointer::Alloc(alloc_size);
+ int flags = String::WriteFlags::kNone;
+ if (ntc) flags |= String::WriteFlags::kNullTerminate;
+ str->WriteUtf8V2(
+ env->isolate(), static_cast<char*>(out.get()), alloc_size, flags);
+ return ByteSource::Allocated(out.release());
}
ByteSource ByteSource::FromBuffer(Local<Value> buffer, bool ntc) {
diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc
index 2d45bbe60f413121b3fd0f01802aeb4368f0c301..2af83e27f77f9afe2f725338b04061efbf0960a1 100644
--- a/src/encoding_binding.cc
+++ b/src/encoding_binding.cc
@@ -98,13 +98,12 @@ void BindingData::EncodeInto(const FunctionCallbackInfo<Value>& args) {
char* write_result = static_cast<char*>(buf->Data()) + dest->ByteOffset();
size_t dest_length = dest->ByteLength();
- int nchars;
- int written = source->WriteUtf8(
- isolate,
- write_result,
- dest_length,
- &nchars,
- String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
+ size_t nchars;
+ size_t written = source->WriteUtf8V2(isolate,
+ write_result,
+ dest_length,
+ String::WriteFlags::kReplaceInvalidUtf8,
+ &nchars);
binding_data->encode_into_results_buffer_[0] = nchars;
binding_data->encode_into_results_buffer_[1] = written;
@@ -129,11 +128,11 @@ void BindingData::EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
CHECK(bs);
- str->WriteUtf8(isolate,
- static_cast<char*>(bs->Data()),
- -1, // We are certain that `data` is sufficiently large
- nullptr,
- String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
+ // We are certain that `data` is sufficiently large
+ str->WriteUtf8V2(isolate,
+ static_cast<char*>(bs->Data()),
+ bs->MaxByteLength(),
+ String::WriteFlags::kReplaceInvalidUtf8);
ab = ArrayBuffer::New(isolate, std::move(bs));
}
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
index a84fdae795dc1cb367a2e446264575c550ce07ee..8f97ca4d9cbb840efd36c77fed12d746a2793670 100644
--- a/src/js_native_api_v8.cc
+++ b/src/js_native_api_v8.cc
@@ -2484,12 +2484,12 @@ napi_status NAPI_CDECL napi_get_value_string_utf8(
CHECK_ARG(env, result);
*result = val.As<v8::String>()->Utf8LengthV2(env->isolate);
} else if (bufsize != 0) {
- int copied = val.As<v8::String>()->WriteUtf8(
- env->isolate,
- buf,
- bufsize - 1,
- nullptr,
- v8::String::REPLACE_INVALID_UTF8 | v8::String::NO_NULL_TERMINATION);
+ auto str = val.As<v8::String>();
+ size_t copied =
+ str->WriteUtf8V2(env->isolate,
+ buf,
+ bufsize - 1,
+ v8::String::WriteFlags::kReplaceInvalidUtf8);
buf[copied] = '\0';
if (result != nullptr) {
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
index 4324ed52d7cd6af5202512858a62346c3ab6c302..0eb9b1967f1f185a140239924809468394297d58 100644
--- a/src/string_bytes.cc
+++ b/src/string_bytes.cc
@@ -266,7 +266,8 @@ size_t StringBytes::Write(Isolate* isolate,
case BUFFER:
case UTF8:
- nbytes = str->WriteUtf8(isolate, buf, buflen, nullptr, flags);
+ nbytes = str->WriteUtf8V2(
+ isolate, buf, buflen, String::WriteFlags::kReplaceInvalidUtf8);
break;
case UCS2: {
diff --git a/src/util.cc b/src/util.cc
index 03c4794314c1c228f95536d2d20a440061cf3a80..e616e11107555f0613cb631e3b4320fc281441fa 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -125,12 +125,8 @@ static void MakeUtf8String(Isolate* isolate,
size_t storage = (3 * value_length) + 1;
target->AllocateSufficientStorage(storage);
- // TODO(@anonrig): Use simdutf to speed up non-one-byte strings once it's
- // implemented
- const int flags =
- String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8;
- const int length =
- string->WriteUtf8(isolate, target->out(), storage, nullptr, flags);
+ size_t length = string->WriteUtf8V2(
+ isolate, target->out(), storage, String::WriteFlags::kReplaceInvalidUtf8);
target->SetLengthAndZeroTerminate(length);
}

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
Date: Fri, 9 May 2025 04:15:47 +0100
Subject: src: use String::WriteV2() in TwoByteValue
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since `String::Write()` is deprecated, use `String::WriteV2()` instead.
PR-URL: https://github.com/nodejs/node/pull/58164
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/src/util.cc b/src/util.cc
index e616e11107555f0613cb631e3b4320fc281441fa..c5c2b89dc3fc008114b2492d1e16928428f097b4 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -146,12 +146,10 @@ TwoByteValue::TwoByteValue(Isolate* isolate, Local<Value> value) {
Local<String> string;
if (!value->ToString(isolate->GetCurrentContext()).ToLocal(&string)) return;
- // Allocate enough space to include the null terminator
- const size_t storage = string->Length() + 1;
- AllocateSufficientStorage(storage);
-
- const int flags = String::NO_NULL_TERMINATION;
- const int length = string->Write(isolate, out(), 0, storage, flags);
+ // Allocate enough space to include the null terminator.
+ const size_t length = string->Length();
+ AllocateSufficientStorage(length + 1);
+ string->WriteV2(isolate, 0, length, out());
SetLengthAndZeroTerminate(length);
}

View File

@@ -7,10 +7,10 @@ This refactors several allocators to allocate within the V8 memory cage,
allowing them to be compatible with the V8_SANDBOXED_POINTERS feature.
diff --git a/src/api/environment.cc b/src/api/environment.cc
index fd71ceac65ccef1d2832b45b0b5612877cee22c1..cb37fa080fc8e8d524cfa2758c4a8c2c5652324d 100644
index d10f861c96931d06fb50dcdb66f2e79b0dee55a7..a869bc0a145009b57db3f37208e405d9356cc20f 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -106,6 +106,14 @@ MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
@@ -109,6 +109,14 @@ MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
return result;
}
@@ -25,17 +25,39 @@ index fd71ceac65ccef1d2832b45b0b5612877cee22c1..cb37fa080fc8e8d524cfa2758c4a8c2c
void* NodeArrayBufferAllocator::Allocate(size_t size) {
void* ret;
if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers)
@@ -324,6 +332,12 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
// but also otherwise just doesn't work, and the only real alternative
// is disabling shared-readonly-heap mode altogether.
static Isolate::CreateParams first_params = *params;
+ // Clear allocator pointers to prevent use-after-free during static
+ // destruction. The static first_params can outlive V8's internal
+ // allocator systems, causing crashes when its destructor tries to
+ // free resources after V8 has shut down.
+ first_params.array_buffer_allocator = nullptr;
+ first_params.array_buffer_allocator_shared.reset();
params->snapshot_blob = first_params.snapshot_blob;
params->external_references = first_params.external_references;
}
diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc
index f23cedf4f2449d8edc9a8de1b70332e75d693cdd..976653dd1e9363e046788fc3419a9b649ceb2ea4 100644
index 46a7d1396dc1a175ae99f4e403721f1730fdd320..bbb0abb3b9563074d350578e0f5a8fa211046b17 100644
--- a/src/crypto/crypto_dh.cc
+++ b/src/crypto/crypto_dh.cc
@@ -55,13 +55,32 @@ void DiffieHellman::MemoryInfo(MemoryTracker* tracker) const {
namespace {
MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) {
+#if defined(V8_ENABLE_SANDBOX)
@@ -61,17 +61,22 @@ MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) {
bool secure;
};
#ifdef V8_ENABLE_SANDBOX
- auto backing = ArrayBuffer::NewBackingStore(
- env->isolate(),
- data.size(),
- BackingStoreInitializationMode::kUninitialized,
- BackingStoreOnFailureMode::kReturnNull);
- if (!backing) {
- THROW_ERR_MEMORY_ALLOCATION_FAILED(env);
- return MaybeLocal<Value>();
- }
+ std::unique_ptr<v8::BackingStore> backing;
+ if (data.size() > 0) {
if (data.size() > 0) {
- memcpy(backing->Data(), data.get(), data.size());
+ std::unique_ptr<ArrayBuffer::Allocator> allocator(ArrayBuffer::Allocator::NewDefaultAllocator());
+ void* v8_data = allocator->Allocate(data.size());
+ CHECK(v8_data);
@@ -50,32 +72,24 @@ index f23cedf4f2449d8edc9a8de1b70332e75d693cdd..976653dd1e9363e046788fc3419a9b64
+ } else {
+ NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
+ backing = v8::ArrayBuffer::NewBackingStore(env->isolate(), data.size());
+ }
+#else
}
#else
auto backing = ArrayBuffer::NewBackingStore(
data.get(),
data.size(),
[](void* data, size_t len, void* ptr) { DataPointer free_me(data, len); },
nullptr);
data.release();
-
+#endif
auto ab = ArrayBuffer::New(env->isolate(), std::move(backing));
return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>());
}
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index 6346f8f7199cf7b7d3736c59571606fff102fbb6..7eea2eaefcad5780663a6b87985925ae5d70a5f9 100644
index 12b0d804c6f1d4998b85160b0aac8eb7a3b5576b..27bd93769233dc65a064710db4095d9cdc3a8b1a 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -359,10 +359,35 @@ ByteSource& ByteSource::operator=(ByteSource&& other) noexcept {
return *this;
}
-std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
+std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore(Environment* env) {
@@ -346,24 +346,30 @@ std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore(
// It's ok for allocated_data_ to be nullptr but
// only if size_ is zero.
CHECK_IMPLIES(size_ > 0, allocated_data_ != nullptr);
-#ifdef V8_ENABLE_SANDBOX
- // If the v8 sandbox is enabled, then all array buffers must be allocated
- // via the isolate. External buffers are not allowed. So, instead of wrapping
- // the allocated data we'll copy it instead.
-
- // TODO(@jasnell): It would be nice to use an abstracted utility to do this
- // branch instead of duplicating the V8_ENABLE_SANDBOX check each time.
+#if defined(V8_ENABLE_SANDBOX)
+ // When V8 sandboxed pointers are enabled, we have to copy into the memory
+ // cage. We still want to ensure we erase the data on free though, so
@@ -87,9 +101,18 @@ index 6346f8f7199cf7b7d3736c59571606fff102fbb6..7eea2eaefcad5780663a6b87985925ae
+ CHECK(v8_data);
+ memcpy(v8_data, allocated_data_, size());
+ OPENSSL_clear_free(allocated_data_, size());
+ std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
- env->isolate(),
+ v8_data,
+ size(),
size(),
- BackingStoreInitializationMode::kUninitialized,
- BackingStoreOnFailureMode::kReturnNull);
- if (!ptr) {
- THROW_ERR_MEMORY_ALLOCATION_FAILED(env);
- return nullptr;
- }
- memcpy(ptr->Data(), allocated_data_, size());
- OPENSSL_clear_free(allocated_data_, size_);
+ [](void* data, size_t length, void*) {
+ OPENSSL_cleanse(data, length);
+ std::unique_ptr<ArrayBuffer::Allocator> allocator(ArrayBuffer::Allocator::NewDefaultAllocator());
@@ -100,108 +123,131 @@ index 6346f8f7199cf7b7d3736c59571606fff102fbb6..7eea2eaefcad5780663a6b87985925ae
+ data_ = nullptr;
+ size_ = 0;
+ return ptr;
+#else
#else
std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
allocated_data_,
size(),
@@ -374,10 +399,11 @@ std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
data_ = nullptr;
size_ = 0;
return ptr;
+#endif // defined(V8_ENABLE_SANDBOX)
}
Local<ArrayBuffer> ByteSource::ToArrayBuffer(Environment* env) {
- std::unique_ptr<BackingStore> store = ReleaseToBackingStore();
+ std::unique_ptr<BackingStore> store = ReleaseToBackingStore(env);
return ArrayBuffer::New(env->isolate(), std::move(store));
}
@@ -674,6 +700,16 @@ namespace {
// in which case this has the same semantics as
@@ -662,23 +668,16 @@ namespace {
// using OPENSSL_malloc. However, if the secure heap is
// initialized, SecureBuffer will automatically use it.
+#if defined(V8_ENABLE_SANDBOX)
+// When V8 sandboxed pointers are enabled, the secure heap cannot be used as
+// all ArrayBuffers must be allocated inside the V8 memory cage.
+void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
+ CHECK(args[0]->IsUint32());
+ uint32_t len = args[0].As<Uint32>()->Value();
+ Local<ArrayBuffer> buffer = ArrayBuffer::New(args.GetIsolate(), len);
+ args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len));
+}
+#else
void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsUint32());
Environment* env = Environment::GetCurrent(args);
@@ -695,6 +731,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len));
}
+#endif // defined(V8_ENABLE_SANDBOX)
void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {
#ifndef OPENSSL_IS_BORINGSSL
diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h
index ebc7fddeccf04a92c610849b626b33f900d63493..ed7d202d1b041f8a6cd43ae767d696fb29ab9cd9 100644
--- a/src/crypto/crypto_util.h
+++ b/src/crypto/crypto_util.h
@@ -243,7 +243,7 @@ class ByteSource {
// Creates a v8::BackingStore that takes over responsibility for
// any allocated data. The ByteSource will be reset with size = 0
// after being called.
- std::unique_ptr<v8::BackingStore> ReleaseToBackingStore();
+ std::unique_ptr<v8::BackingStore> ReleaseToBackingStore(Environment* env);
v8::Local<v8::ArrayBuffer> ToArrayBuffer(Environment* env);
- Environment* env = Environment::GetCurrent(args);
+ CHECK(args[0]->IsUint32());
#ifdef V8_ENABLE_SANDBOX
- // The v8 sandbox is enabled, so we cannot use the secure heap because
- // the sandbox requires that all array buffers be allocated via the isolate.
- // That is fundamentally incompatible with the secure heap which allocates
- // in openssl's secure heap area. Instead we'll just throw an error here.
- //
- // That said, we really shouldn't get here in the first place since the
- // option to enable the secure heap is only available when the sandbox
- // is disabled.
- UNREACHABLE();
+ uint32_t len = args[0].As<Uint32>()->Value();
+ Local<ArrayBuffer> buffer = ArrayBuffer::New(args.GetIsolate(), len);
+ args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len));
#else
- CHECK(args[0]->IsUint32());
+ Environment* env = Environment::GetCurrent(args);
uint32_t len = args[0].As<Uint32>()->Value();
auto data = DataPointer::SecureAlloc(len);
- CHECK(data.isSecure());
if (!data) {
return THROW_ERR_OPERATION_FAILED(env, "Allocation failed");
}
diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc
index f616223cfb0f6e10f7cf57ada9704316bde2797e..eb6dad44a49d997097c8fb5009eeb60a7305da27 100644
index b30297eac08ad9587642b723f91d7e3b954294d4..4c5427596d1c90d3a413cdd9ff4f1151e657073d 100644
--- a/src/crypto/crypto_x509.cc
+++ b/src/crypto/crypto_x509.cc
@@ -167,6 +167,19 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, const BIOPointer& bio) {
MaybeLocal<Value> ToBuffer(Environment* env, BIOPointer* bio) {
if (bio == nullptr || !*bio) return {};
@@ -135,19 +135,17 @@ MaybeLocal<Value> ToBuffer(Environment* env, BIOPointer* bio) {
return {};
BUF_MEM* mem = *bio;
+#if defined(V8_ENABLE_SANDBOX)
#ifdef V8_ENABLE_SANDBOX
- // If the v8 sandbox is enabled, then all array buffers must be allocated
- // via the isolate. External buffers are not allowed. So, instead of wrapping
- // the BIOPointer we'll copy it instead.
- auto backing = ArrayBuffer::NewBackingStore(
- env->isolate(),
+ std::unique_ptr<ArrayBuffer::Allocator> allocator(ArrayBuffer::Allocator::NewDefaultAllocator());
+ void* v8_data = allocator->Allocate(mem->length);
+ CHECK(v8_data);
+ memcpy(v8_data, mem->data, mem->length);
+ std::unique_ptr<v8::BackingStore> backing = ArrayBuffer::NewBackingStore(
+ v8_data,
+ mem->length,
mem->length,
- BackingStoreInitializationMode::kUninitialized,
- BackingStoreOnFailureMode::kReturnNull);
- if (!backing) {
- THROW_ERR_MEMORY_ALLOCATION_FAILED(env);
- return MaybeLocal<Value>();
- }
- memcpy(backing->Data(), mem->data, mem->length);
+ [](void* data, size_t length, void*) {
+ std::unique_ptr<ArrayBuffer::Allocator> allocator(ArrayBuffer::Allocator::NewDefaultAllocator());
+ allocator->Free(data, length);
+ }, nullptr);
+#else
#else
auto backing = ArrayBuffer::NewBackingStore(
mem->data,
mem->length,
@@ -174,6 +187,8 @@ MaybeLocal<Value> ToBuffer(Environment* env, BIOPointer* bio) {
BIOPointer free_me(static_cast<BIO*>(data));
},
bio->release());
+#endif
diff --git a/src/env-inl.h b/src/env-inl.h
index 97c43afb487b58c0c77bd59b4a6b6d7a13690053..5dfbd564d5bbd22ebf3b529a07b73e85cbe51986 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -44,6 +44,16 @@
namespace node {
+NoArrayBufferZeroFillScope::NoArrayBufferZeroFillScope(
+ IsolateData* isolate_data)
+ : node_allocator_(isolate_data->node_allocator()) {
+ if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 0;
+}
+
auto ab = ArrayBuffer::New(env->isolate(), std::move(backing));
Local<Value> ret;
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {};
+NoArrayBufferZeroFillScope::~NoArrayBufferZeroFillScope() {
+ if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 1;
+}
+
inline v8::Isolate* IsolateData::isolate() const {
return isolate_;
}
diff --git a/src/env.h b/src/env.h
index d34aec43630b3cf53004d8180446d7136b59ceac..b30314d7773742e2332ff47f84bc326151563690 100644
--- a/src/env.h
+++ b/src/env.h
@@ -111,6 +111,19 @@ class ModuleWrap;
class Environment;
class Realm;
+// Disables zero-filling for ArrayBuffer allocations in this scope. This is
+// similar to how we implement Buffer.allocUnsafe() in JS land.
+class NoArrayBufferZeroFillScope {
+ public:
+ inline explicit NoArrayBufferZeroFillScope(IsolateData* isolate_data);
+ inline ~NoArrayBufferZeroFillScope();
+
+ private:
+ NodeArrayBufferAllocator* node_allocator_;
+
+ friend class Environment;
+};
+
struct IsolateDataSerializeInfo {
std::vector<SnapshotIndex> primitive_values;
std::vector<PropInfo> template_values;
diff --git a/src/node_i18n.cc b/src/node_i18n.cc
index 61b6ecd240c9500f21f683065a2f920af3afb502..ad2b1c76325cb5c8f18a618c5a85ae87b6a7bbe7 100644
index 3c4f419aa29470b3280174b58680b9421b0340b5..3b24ad2a2316f89d98b067e2c13988f87a9a00d2 100644
--- a/src/node_i18n.cc
+++ b/src/node_i18n.cc
@@ -104,7 +104,7 @@ namespace {
@@ -105,7 +105,7 @@ namespace {
template <typename T>
MaybeLocal<Object> ToBufferEndian(Environment* env, MaybeStackBuffer<T>* buf) {
- MaybeLocal<Object> ret = Buffer::New(env, buf);
+ MaybeLocal<Object> ret = Buffer::Copy(env, reinterpret_cast<char*>(buf->out()), buf->length() * sizeof(T));
if (ret.IsEmpty())
return ret;
Local<Object> ret;
- if (!Buffer::New(env, buf).ToLocal(&ret)) {
+ if (!Buffer::Copy(env, reinterpret_cast<char*>(buf->out()), buf->length() * sizeof(T)).ToLocal(&ret)) {
return {};
}
@@ -181,7 +181,7 @@ MaybeLocal<Object> TranscodeLatin1ToUcs2(Environment* env,
@@ -182,7 +182,7 @@ MaybeLocal<Object> TranscodeLatin1ToUcs2(Environment* env,
return {};
}
@@ -210,7 +256,7 @@ index 61b6ecd240c9500f21f683065a2f920af3afb502..ad2b1c76325cb5c8f18a618c5a85ae87
}
MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
@@ -226,7 +226,7 @@ MaybeLocal<Object> TranscodeUcs2FromUtf8(Environment* env,
@@ -227,7 +227,7 @@ MaybeLocal<Object> TranscodeUcs2FromUtf8(Environment* env,
return {};
}
@@ -219,7 +265,7 @@ index 61b6ecd240c9500f21f683065a2f920af3afb502..ad2b1c76325cb5c8f18a618c5a85ae87
}
MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
@@ -250,7 +250,7 @@ MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
@@ -251,7 +251,7 @@ MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
return {};
}
@@ -253,7 +299,7 @@ index 12ea72b61b0a5e194207bb369dfed4b8667107cb..64442215714a98f648971e517ddd9c77
// Delegate to V8's allocator for compatibility with the V8 memory cage.
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
index c55a2e28066147ae5ca5def10ec76ccc03c634b4..c54183c72944989219b6437c9e571a3f7f3f8dd5 100644
index 00fcd4b6afccce47ff21c4447d9cd60f25c11835..5f96ee2051e5339456185efddb149c4d43093f31 100644
--- a/src/node_serdes.cc
+++ b/src/node_serdes.cc
@@ -29,6 +29,26 @@ using v8::ValueSerializer;
@@ -307,8 +353,8 @@ index c55a2e28066147ae5ca5def10ec76ccc03c634b4..c54183c72944989219b6437c9e571a3f
};
class DeserializerContext : public BaseObject,
@@ -144,6 +170,24 @@ Maybe<uint32_t> SerializerContext::GetSharedArrayBufferId(
return id.ToLocalChecked()->Uint32Value(env()->context());
@@ -145,6 +171,24 @@ Maybe<uint32_t> SerializerContext::GetSharedArrayBufferId(
return id->Uint32Value(env()->context());
}
+void* SerializerContext::ReallocateBufferMemory(void* old_buffer,
@@ -331,14 +377,15 @@ index c55a2e28066147ae5ca5def10ec76ccc03c634b4..c54183c72944989219b6437c9e571a3f
+
Maybe<bool> SerializerContext::WriteHostObject(Isolate* isolate,
Local<Object> input) {
MaybeLocal<Value> ret;
@@ -209,9 +253,14 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
Local<Value> args[1] = { input };
@@ -211,10 +255,17 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
// Note: Both ValueSerializer and this Buffer::New() variant use malloc()
// as the underlying allocator.
std::pair<uint8_t*, size_t> ret = ctx->serializer_.Release();
- auto buf = Buffer::New(ctx->env(),
- reinterpret_cast<char*>(ret.first),
- ret.second);
- Local<Object> buf;
- if (Buffer::New(ctx->env(), reinterpret_cast<char*>(ret.first), ret.second)
- .ToLocal(&buf)) {
- args.GetReturnValue().Set(buf);
+ std::unique_ptr<v8::BackingStore> bs =
+ v8::ArrayBuffer::NewBackingStore(reinterpret_cast<char*>(ret.first), ret.second,
+ [](void* data, size_t length, void* deleter_data) {
@@ -347,14 +394,17 @@ index c55a2e28066147ae5ca5def10ec76ccc03c634b4..c54183c72944989219b6437c9e571a3f
+ Local<ArrayBuffer> ab = v8::ArrayBuffer::New(ctx->env()->isolate(), std::move(bs));
+
+ auto buf = Buffer::New(ctx->env(), ab, 0, ret.second);
+
+ if (!buf.IsEmpty()) {
+ args.GetReturnValue().Set(buf.ToLocalChecked());
}
}
if (!buf.IsEmpty()) {
args.GetReturnValue().Set(buf.ToLocalChecked());
diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc
index 9787b14352753c5e0f8dc2b90093680e7cd10f1a..31af9e62396368af1b81f8841a705fd313df2b9f 100644
index ef659f1c39f7ee958879bf395377bc99911fc346..225b1465b7c97d972a38968faf6d685017a80bf0 100644
--- a/src/node_trace_events.cc
+++ b/src/node_trace_events.cc
@@ -132,12 +132,28 @@ static void GetCategoryEnabledBuffer(const FunctionCallbackInfo<Value>& args) {
@@ -129,12 +129,28 @@ static void GetCategoryEnabledBuffer(const FunctionCallbackInfo<Value>& args) {
const uint8_t* enabled_pointer =
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_name.out());
uint8_t* enabled_pointer_cast = const_cast<uint8_t*>(enabled_pointer);
@@ -384,3 +434,26 @@ index 9787b14352753c5e0f8dc2b90093680e7cd10f1a..31af9e62396368af1b81f8841a705fd3
auto ab = ArrayBuffer::New(isolate, std::move(bs));
v8::Local<Uint8Array> u8 = v8::Uint8Array::New(ab, 0, 1);
diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js
index 07e38748b07ddd32a6e3caa3c34183387e1cae18..f09bf0940dad2068f0aa5dce783dd422773d4bbb 100644
--- a/test/parallel/test-process-env-allowed-flags-are-documented.js
+++ b/test/parallel/test-process-env-allowed-flags-are-documented.js
@@ -49,6 +49,8 @@ if (!hasOpenSSL3) {
documented.delete('--openssl-shared-config');
}
+const isV8Sandboxed = process.config.variables.v8_enable_sandbox;
+
// Filter out options that are conditionally present.
const conditionalOpts = [
{
@@ -74,6 +76,9 @@ const conditionalOpts = [
}, {
include: process.features.inspector,
filter: (opt) => opt.startsWith('--inspect') || opt === '--debug-port'
+ }, {
+ include: !isV8Sandboxed,
+ filter: (opt) => ['--secure-heap', '--secure-heap-min'].includes(opt)
},
];
documented.forEach((opt) => {

View File

@@ -12,7 +12,7 @@ See:
https://chromium-review.googlesource.com/c/v8/v8/+/6826001
diff --git a/test/fixtures/test-runner/output/describe_it.snapshot b/test/fixtures/test-runner/output/describe_it.snapshot
index 347f3789693ddae7e7f9bd4125d8b19a31c1e764..35913d7f487dbd56eb8015e20f14a447de1db9bc 100644
index 67d4af7f1b9f45d48b35c930cb1490ee019d0bdf..21d8744340c5a4c002d8c91266f46c2b66591b6e 100644
--- a/test/fixtures/test-runner/output/describe_it.snapshot
+++ b/test/fixtures/test-runner/output/describe_it.snapshot
@@ -690,6 +690,8 @@ not ok 54 - timeouts

View File

@@ -7,7 +7,7 @@ Instead of disabling the tests, flag them as flaky so they still run
but don't cause CI failures on flakes.
diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
index 67c0c04d2365e59db111258d008f8c73173e3e96..a4204e7580e7823399f6057d57c09cba56b5ff78 100644
index 0036beb318df2241d49201dc9d0679763e551e7b..5713f13de818f84b1c598b73024773c1bbf936c6 100644
--- a/test/parallel/parallel.status
+++ b/test/parallel/parallel.status
@@ -5,6 +5,16 @@ prefix parallel
@@ -25,10 +25,10 @@ index 67c0c04d2365e59db111258d008f8c73173e3e96..a4204e7580e7823399f6057d57c09cba
+test-cluster-shared-handle-bind-privileged-port: PASS, FLAKY
+test-debugger-random-port-with-inspect-port: PASS, FLAKY
# https://github.com/nodejs/node/issues/52273
test-net-write-fully-async-hex-string: PASS, FLAKY
# https://github.com/nodejs/node/issues/52273
test-shadow-realm-gc: SKIP
test-shadow-realm-gc-module: SKIP
diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status
index 4ae3b6c5fd2eb633ae78bed1824046d862d7579b..d291954d4451b63aeb2bf46232e8705150eb9e79 100644
index c36eac6302d43a6b80ed0bc77db2c628bb66169c..627c4d576787e4363736615d08eebe481800909e 100644
--- a/test/sequential/sequential.status
+++ b/test/sequential/sequential.status
@@ -7,6 +7,18 @@ prefix sequential

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= <targos@protonmail.com>
Date: Sat, 21 Dec 2024 09:25:55 +0100
Subject: test: handle explicit resource management globals
https://chromium-review.googlesource.com/c/chromium/src/+/6174695
diff --git a/test/common/globals.js b/test/common/globals.js
index 5d1c4415eeb09e92d062330afc0aecb1d297b6d3..2c1dac019ba2aa0a23c2434997e2007dd2eacde8 100644
--- a/test/common/globals.js
+++ b/test/common/globals.js
@@ -64,6 +64,9 @@ const intrinsics = new Set([
'Atomics',
'WebAssembly',
'Iterator',
+ 'SuppressedError',
+ 'DisposableStack',
+ 'AsyncDisposableStack',
]);
if (global.gc) {

View File

@@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "targos@protonmail.com" <targos@protonmail.com>
Date: Thu, 9 May 2024 12:00:39 +0200
Subject: test: update v8-stats test for V8 12.6
Refs: https://github.com/v8/v8/commit/e30e228ee6e034de49a40af0173113198a19b497
diff --git a/test/parallel/test-v8-stats.js b/test/parallel/test-v8-stats.js
index bb954165f42c9de3db66bc5fdcac647654ad71ea..07be833e6e749a2bb68490c935c6791c178d126f 100644
--- a/test/parallel/test-v8-stats.js
+++ b/test/parallel/test-v8-stats.js
@@ -48,6 +48,8 @@ const expectedHeapSpaces = [
'read_only_space',
'shared_large_object_space',
'shared_space',
+ 'shared_trusted_large_object_space',
+ 'shared_trusted_space',
'trusted_large_object_space',
'trusted_space',
];

View File

@@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Maddock <smaddock@slack-corp.com>
Date: Fri, 22 Nov 2024 15:18:05 -0500
Subject: test: use static method names in call stacks
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/5907815
diff --git a/test/message/assert_throws_stack.out b/test/message/assert_throws_stack.out
index 1ecda64889e07fe64d03404d478311f9f8267a4e..2b5587292a2c7a8797589804f14bfd0c3e9725f8 100644
--- a/test/message/assert_throws_stack.out
+++ b/test/message/assert_throws_stack.out
@@ -24,7 +24,7 @@ AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
actual: Error: foo
at assert.throws.bar (*assert_throws_stack.js:*)
at getActual (node:assert:*)
- at Function.throws (node:assert:*)
+ at strict.throws (node:assert:*)
at Object.<anonymous> (*assert_throws_stack.js:*:*)
at *
at *
diff --git a/test/message/internal_assert_fail.out b/test/message/internal_assert_fail.out
index 9fc86673262dbacb45e544340c81b4d14ee3f845..5f1026791f323d6a5965810917c0ef33ae4bfd53 100644
--- a/test/message/internal_assert_fail.out
+++ b/test/message/internal_assert_fail.out
@@ -6,7 +6,7 @@ Error [ERR_INTERNAL_ASSERTION]: Unreachable!
This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues
- at Function.fail (node:internal/assert:*:*)
+ at assert.fail (node:internal/assert:*:*)
at * (*test*message*internal_assert_fail.js:7:8)
at *
at *
diff --git a/test/parallel/test-fs-promises.js b/test/parallel/test-fs-promises.js
index d28af0f4833c4901e8542c8938cbcf51ff22464d..796ad3224c4dba06b53b2da14fc8469b158f206d 100644
--- a/test/parallel/test-fs-promises.js
+++ b/test/parallel/test-fs-promises.js
@@ -58,7 +58,7 @@ assert.strictEqual(
code: 'ENOENT',
name: 'Error',
message: /^ENOENT: no such file or directory, access/,
- stack: /at async Function\.rejects/
+ stack: /at async ok\.rejects/
}
).then(common.mustCall());

View File

@@ -1,7 +1,7 @@
[
"abort/test-abort-backtrace",
"es-module/test-esm-wasm",
"es-module/test-vm-compile-function-lineoffset",
"parallel/test-async-context-frame",
"parallel/test-bootstrap-modules",
"parallel/test-child-process-fork-exec-path",
"parallel/test-code-cache",
@@ -41,11 +41,11 @@
"parallel/test-module-loading-globalpaths",
"parallel/test-module-print-timing",
"parallel/test-openssl-ca-options",
"parallel/test-os-checked-function",
"parallel/test-process-versions",
"parallel/test-process-get-builtin",
"parallel/test-repl",
"parallel/test-repl-underscore",
"parallel/test-tls-securepair-leak",
"parallel/test-single-executable-blob-config",
"parallel/test-single-executable-blob-config-errors",
"parallel/test-shadow-realm-custom-loaders",
@@ -76,6 +76,7 @@
"parallel/test-snapshot-worker",
"parallel/test-strace-openat-openssl",
"parallel/test-sqlite-backup",
"parallel/test-max-old-space-size-percentage",
"parallel/test-tls-alpn-server-client",
"parallel/test-tls-cli-min-version-1.0",
"parallel/test-tls-cli-max-version-1.2",

View File

@@ -284,12 +284,10 @@ v8::MaybeLocal<v8::Promise> HostImportModuleWithPhaseDynamically(
context, v8_host_defined_options, v8_referrer_resource_url,
v8_specifier, import_phase, v8_import_attributes);
case ESMHandlerPlatform::kNodeJS:
// TODO: Switch to node::loader::ImportModuleDynamicallyWithPhase
// once we land the Node.js version that has it in upstream.
CHECK(import_phase == v8::ModuleImportPhase::kEvaluation);
return node::loader::ImportModuleDynamically(
return node::loader::ImportModuleDynamicallyWithPhase(
context, v8_host_defined_options, v8_referrer_resource_url,
v8_specifier, v8_import_attributes);
v8_specifier, import_phase, v8_import_attributes);
case ESMHandlerPlatform::kNone:
default:
return {};

View File

@@ -671,7 +671,7 @@ describe('contextBridge', () => {
it('should release the global hold on methods sent across contexts', async () => {
await makeBindingWindow(() => {
const trackedValues: WeakRef<object>[] = [];
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', { trackedValues: trackedValues.filter(value => value.deref()).length }));
require('electron').ipcRenderer.on('get-gc-info', (e: any) => e.sender.send('gc-info', { trackedValues: trackedValues.filter(value => value.deref()).length }));
contextBridge.exposeInMainWorld('example', {
getFunction: () => () => 123,
track: (value: object) => { trackedValues.push(new WeakRef(value)); }
@@ -699,7 +699,7 @@ describe('contextBridge', () => {
it('should not leak the global hold on methods sent across contexts when reloading a sandboxed renderer', async () => {
await makeBindingWindow(() => {
const trackedValues: WeakRef<object>[] = [];
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', { trackedValues: trackedValues.filter(value => value.deref()).length }));
require('electron').ipcRenderer.on('get-gc-info', (e: any) => e.sender.send('gc-info', { trackedValues: trackedValues.filter(value => value.deref()).length }));
contextBridge.exposeInMainWorld('example', {
getFunction: () => () => 123,
track: (value: object) => { trackedValues.push(new WeakRef(value)); }

View File

@@ -243,7 +243,6 @@ describe('ipc module', () => {
await w.webContents.executeJavaScript(`(${function () {
try {
const buffer = new ArrayBuffer(10);
// @ts-expect-error
require('electron').ipcRenderer.postMessage('port', '', [buffer]);
} catch (e) {
require('electron').ipcRenderer.postMessage('port', { error: (e as Error).message });
@@ -323,7 +322,7 @@ describe('ipc module', () => {
w.loadURL('about:blank');
await w.webContents.executeJavaScript(`(${function () {
const { ipcRenderer } = require('electron');
ipcRenderer.on('port', e => {
ipcRenderer.on('port', (e: any) => {
const [port] = e.ports;
port.start();
port.onclose = () => {
@@ -480,8 +479,8 @@ describe('ipc module', () => {
w.loadURL('about:blank');
await w.webContents.executeJavaScript(`(${function () {
const { ipcRenderer } = require('electron');
ipcRenderer.on('port', ev => {
const [port] = ev.ports;
ipcRenderer.on('port', (e: any) => {
const [port] = e.ports;
port.onmessage = () => {
ipcRenderer.send('done');
};
@@ -498,9 +497,9 @@ describe('ipc module', () => {
w.loadURL('about:blank');
await w.webContents.executeJavaScript(`(${function () {
const { ipcRenderer } = require('electron');
ipcRenderer.on('port', e1 => {
e1.ports[0].onmessage = e2 => {
e2.ports[0].onmessage = e3 => {
ipcRenderer.on('port', (e1: any) => {
e1.ports[0].onmessage = (e2: any) => {
e2.ports[0].onmessage = (e3: any) => {
ipcRenderer.send('done', e3.data);
};
};
@@ -587,7 +586,7 @@ describe('ipc module', () => {
w.loadURL('about:blank');
await w.webContents.executeJavaScript(`(${function () {
const { ipcRenderer } = require('electron');
ipcRenderer.on('foo', (_e, msg) => {
ipcRenderer.on('foo', (_e: Event, msg: string) => {
ipcRenderer.send('bar', msg);
});
}})()`);

View File

@@ -1909,10 +1909,10 @@ describe('chromium features', () => {
});
it('delivers messages that match the origin', async () => {
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, contextIsolation: false } });
const w = new BrowserWindow({ show: false });
w.loadFile(path.resolve(__dirname, 'fixtures', 'blank.html'));
const data = await w.webContents.executeJavaScript(`
window.open(${JSON.stringify(serverURL)}, '', 'show=no,contextIsolation=no,nodeIntegration=yes');
window.open(${JSON.stringify(serverURL)}, '', 'show=no');
new Promise(resolve => window.addEventListener('message', resolve, {once: true})).then(e => e.data)
`);
expect(data).to.equal('deliver');

View File

@@ -1,7 +1,6 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
const url = require('node:url')
function tryPostMessage(...args) {
try {
window.opener.postMessage(...args)
@@ -9,7 +8,8 @@
console.error(e)
}
}
if (url.parse(window.location.href, true).query.opened != null) {
const parsedURL = new URL(window.location.href);
if (parsedURL.searchParams.get('opened') != null) {
// Ensure origins are properly checked by removing a single character from the end
tryPostMessage('do not deliver substring origin', window.location.origin.substring(0, window.location.origin.length - 1))
tryPostMessage('do not deliver file://', 'file://')

View File

@@ -989,7 +989,7 @@
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/node@*", "@types/node@^22.7.7":
"@types/node@*":
version "22.7.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.7.tgz#6cd9541c3dccb4f7e8b141b491443f4a1570e307"
integrity sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==
@@ -1003,6 +1003,13 @@
dependencies:
undici-types "~6.19.2"
"@types/node@^24.9.0":
version "24.9.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.9.1.tgz#b7360b3c789089e57e192695a855aa4f6981a53c"
integrity sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==
dependencies:
undici-types "~7.16.0"
"@types/responselike@*", "@types/responselike@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
@@ -7769,6 +7776,11 @@ undici-types@~6.19.2:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
undici-types@~7.16.0:
version "7.16.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46"
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
unicorn-magic@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz#4efd45c85a69e0dd576d25532fbfa22aa5c8a104"