mirror of
https://github.com/electron/electron.git
synced 2026-10-28 11:44:46 +08:00
chore: bump node to v24.22.0 (main) (#55006)
* chore: bump node in DEPS to v24.22.0 * fix(patch): enable the V8 sandbox in shared-cage builds Upstream now enables the V8 sandbox only for shared-cage builds. Keep Electron's behaviour of enabling it whenever pointer compression is on, matching Chromium's V8. The unofficial.gni x86 hunk landed upstream. Ref: https://github.com/nodejs/node/pull/62237 Ref: https://github.com/nodejs/node/pull/65491 * fix(patch): use names for asymmetric key algorithms Upstream dropped the BoringSSL guard in DhKeyGenTraits::Setup(), removed ReadASN1Element() from ncrypto, and no longer includes <openssl/evp.h> from env.h, so those hunks are no longer needed. Ref: https://github.com/nodejs/node/pull/65966 Ref: https://github.com/nodejs/node/pull/66108 Ref: https://github.com/nodejs/node/pull/65484 * fix(patch): skip RSA-PSS keygen deprecation tests with BoringSSL The skip is now upstream. Ref: https://github.com/nodejs/node/pull/65808 * fix(patch): detach cppgc wrappers from their Realm before it is freed Upstream's CppgcWrapperList::Cleanup() now pops nodes itself and the wrapper owns and frees its list node, so the local PopFront/delete hunk is dropped. Ref: https://github.com/nodejs/node/pull/65778 * fix(patch): gate jspi flag on V8_ENABLE_WEBASSEMBLY Ref: https://github.com/nodejs/node/pull/66082 * chore: remove upstreamed patches - https://github.com/nodejs/node/pull/63985 - https://github.com/nodejs/node/pull/65630 - https://github.com/nodejs/node/pull/64453 - https://github.com/nodejs/node/pull/65778 * chore: update patches (trivial only) * chore: update filenames.auto.gni * fix(patch): discover hashes from OpenSSL providers ncrypto's DigestCache::aliases() now has a function-local static, so ncrypto needs the no_exit_time_destructors config too. Ref: https://github.com/nodejs/node/pull/65484 * fix(patch): read the peer certificate chain without consuming it sk_X509_num() returns size_t in BoringSSL. Ref: https://github.com/nodejs/node/pull/65602 * fix(patch): fix shared buffer growability validation Ref: https://github.com/nodejs/node/pull/65845 * chore: update patches (trivial only) * node#65820: src: fix null pointer call when running without a startup snapshot SnapshotData::AsEmbedderWrapper() was removed. Both call sites wrap the embedded snapshot, so use EmbedderSnapshotData::BuiltinSnapshotData(). Ref: https://github.com/nodejs/node/pull/65820 * node#65407: src: apply IsolateSettings when using a snapshot node::CreateEnvironment() no longer installs the per-isolate message listener when it builds the environment from a snapshot, so stop compensating for that and let SetIsolateUpForNode() add it. Ref: https://github.com/nodejs/node/pull/65407 * test: drop removed wasm rab integration flag from webidl buffer source test Chromium's V8 removed --experimental-wasm-rab-integration after shipping it; the new test-internal-webidl-buffer-source.js passes it. Ref: https://github.com/nodejs/node/pull/65845 Ref: https://chromium-review.googlesource.com/c/v8/v8/+/7708297 * test: skip new rmSync permission error test when the Node suite runs as root test-fs-rmSync-special-char-additional-error.js is new in v24.22.0 and relies on a read-only directory blocking removal, which root bypasses; the Linux Node.js test job runs as root. Ref: https://github.com/nodejs/node/pull/64453 --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: Sam Attard <sattard@anthropic.com>
This commit is contained in:
1 parent
2766ef64b6
commit
1f3d86bcf8
40 files changed
+328
-1218
No files matched your search
@@ -4,7 +4,7 @@ vars = {
|
||||
'chromium_version':
|
||||
'158.0.8105.0',
|
||||
'node_version':
|
||||
'v24.21.0',
|
||||
'v24.22.0',
|
||||
'nan_version':
|
||||
'a1b4ba8f4bf2f46d2f270dbbb7bc0af482dc3e32',
|
||||
'squirrel.mac_version':
|
||||
|
||||
+2
-2
@@ -227,8 +227,6 @@ auto_filenames = {
|
||||
"../third_party/electron_node/src/crypto/crypto_bio.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_chacha20_poly1305.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_cipher.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_clienthello-inl.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_clienthello.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_common.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_context.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_dh.h",
|
||||
@@ -241,7 +239,9 @@ auto_filenames = {
|
||||
"../third_party/electron_node/src/crypto/crypto_keygen.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_keys.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_kmac.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_mac.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_pbkdf2.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_pkcs12.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_pqc.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_random.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_rsa.h",
|
||||
|
||||
@@ -46,10 +46,8 @@ test_account_for_libc_rm_error_on_electron_linux.patch
|
||||
fix_use_embedder_perfetto_client_when_available.patch
|
||||
src_fix_external_reference_registration_for_new_cfunction_lifetime.patch
|
||||
fix_do_not_pass_removed_jspi_v8_flag.patch
|
||||
src_keep_global_list_of_addon-provided_cleanup_hooks.patch
|
||||
src_fix_use-after-free_in_cleanuphookthunkrun.patch
|
||||
fix_allow_electron_s_linked_bindings_under_the_permission_model.patch
|
||||
fs_support_removing_read-only_files_in_rmsync_on_windows.patch
|
||||
src_detach_cppgc_wrappers_from_their_realm_before_it_is_freed.patch
|
||||
add_missing_includes_of_standard_library_headers_1292.patch
|
||||
deps_add_missing_standard_library_includes_to_simdjson.patch
|
||||
test_drop_removed_wasm_rab_integration_flag.patch
|
||||
test_skip_rmsync_permission_error_test_when_running_as_root.patch
|
||||
@@ -6,7 +6,7 @@ Subject: Delete deprecated fields on v8::Isolate
|
||||
https://chromium-review.googlesource.com/c/v8/v8/+/7081397
|
||||
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index ea8ba25085c12f6180c879f19e543a8151e3792d..90d40720a4faad865cf6584bee73e5739d534f36 100644
|
||||
index 51b7607854b77ceeb3f9e977ce15594cdb4eaeca..6313d5ce1839fafb175c0e0c74eb39445baed467 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -219,8 +219,6 @@ void SetIsolateCreateParamsForNode(Isolate::CreateParams* params) {
|
||||
|
||||
+12
-12
@@ -72,10 +72,10 @@ index 5f04e7085f4246b673f8ea629d03cc8b02e93f2a..60d61aef3f8db2e1d43096de580c5127
|
||||
|
||||
inline Environment* Environment::GetCurrent(
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index 3f655793d1353619699d42b09b227c729946075f..5389d6e699f32dacfd4d5710258f04f1cb9f9d12 100644
|
||||
index efda30eb1fb1c18bafd64eed46a6fc72e806a02b..beb700dbe9fabcfe7c154a4c9e0f3dd8c95bc52e 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -703,13 +703,16 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {
|
||||
@@ -704,13 +704,16 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {
|
||||
void Environment::AssignToContext(Local<v8::Context> context,
|
||||
Realm* realm,
|
||||
const ContextInfo& info) {
|
||||
@@ -96,7 +96,7 @@ index 3f655793d1353619699d42b09b227c729946075f..5389d6e699f32dacfd4d5710258f04f1
|
||||
|
||||
// This must not be done before other context fields are initialized.
|
||||
ContextEmbedderTag::TagNodeContext(context);
|
||||
@@ -724,12 +727,16 @@ void Environment::AssignToContext(Local<v8::Context> context,
|
||||
@@ -725,12 +728,16 @@ void Environment::AssignToContext(Local<v8::Context> context,
|
||||
|
||||
void Environment::UnassignFromContext(Local<v8::Context> context) {
|
||||
if (!context.IsEmpty()) {
|
||||
@@ -119,10 +119,10 @@ index 3f655793d1353619699d42b09b227c729946075f..5389d6e699f32dacfd4d5710258f04f1
|
||||
UntrackContext(context);
|
||||
}
|
||||
diff --git a/src/histogram.cc b/src/histogram.cc
|
||||
index 7127bb80cc8fa3ecf3d618358bfd7d53dc8b591e..41c3528529b970a319f9c2baab51eb0b801a7fc0 100644
|
||||
index 30a095b3c43c015d8569f65362b6b3b619290f7f..2e649644acf7aff3be059cd8ec1c96235d2d44e6 100644
|
||||
--- a/src/histogram.cc
|
||||
+++ b/src/histogram.cc
|
||||
@@ -755,7 +755,8 @@ HistogramBase::HistogramBase(
|
||||
@@ -1873,7 +1873,8 @@ HistogramBase::HistogramBase(Environment* env,
|
||||
MakeWeak();
|
||||
wrap->SetAlignedPointerInInternalField(
|
||||
HistogramImpl::InternalFields::kImplField,
|
||||
@@ -131,8 +131,8 @@ index 7127bb80cc8fa3ecf3d618358bfd7d53dc8b591e..41c3528529b970a319f9c2baab51eb0b
|
||||
+ v8::kEmbedderDataTypeTagDefault);
|
||||
}
|
||||
|
||||
HistogramBase::HistogramBase(
|
||||
@@ -767,7 +768,8 @@ HistogramBase::HistogramBase(
|
||||
HistogramBase::HistogramBase(Environment* env,
|
||||
@@ -1883,7 +1884,8 @@ HistogramBase::HistogramBase(Environment* env,
|
||||
MakeWeak();
|
||||
wrap->SetAlignedPointerInInternalField(
|
||||
HistogramImpl::InternalFields::kImplField,
|
||||
@@ -142,7 +142,7 @@ index 7127bb80cc8fa3ecf3d618358bfd7d53dc8b591e..41c3528529b970a319f9c2baab51eb0b
|
||||
}
|
||||
|
||||
void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
|
||||
@@ -1022,7 +1024,8 @@ IntervalHistogram::IntervalHistogram(Environment* env,
|
||||
@@ -2387,7 +2389,8 @@ IntervalHistogram::IntervalHistogram(Environment* env,
|
||||
MakeWeak();
|
||||
wrap->SetAlignedPointerInInternalField(
|
||||
HistogramImpl::InternalFields::kImplField,
|
||||
@@ -152,7 +152,7 @@ index 7127bb80cc8fa3ecf3d618358bfd7d53dc8b591e..41c3528529b970a319f9c2baab51eb0b
|
||||
uv_timer_init(env->event_loop(), &timer_);
|
||||
}
|
||||
|
||||
@@ -1114,7 +1117,8 @@ IterationHistogram::IterationHistogram(Environment* env,
|
||||
@@ -2479,7 +2482,8 @@ IterationHistogram::IterationHistogram(Environment* env,
|
||||
MakeWeak();
|
||||
wrap->SetAlignedPointerInInternalField(
|
||||
HistogramImpl::InternalFields::kImplField,
|
||||
@@ -162,7 +162,7 @@ index 7127bb80cc8fa3ecf3d618358bfd7d53dc8b591e..41c3528529b970a319f9c2baab51eb0b
|
||||
uv_check_init(env->event_loop(), &check_handle_);
|
||||
uv_prepare_init(env->event_loop(), &prepare_handle_);
|
||||
uv_unref(reinterpret_cast<uv_handle_t*>(&check_handle_));
|
||||
@@ -1595,7 +1599,8 @@ HistogramImpl* HistogramImpl::FromJSObject(Local<Value> value) {
|
||||
@@ -3056,7 +3060,8 @@ HistogramImpl* HistogramImpl::FromJSObject(Local<Value> value) {
|
||||
auto obj = value.As<Object>();
|
||||
DCHECK_GE(obj->InternalFieldCount(), HistogramImpl::kInternalFieldCount);
|
||||
return static_cast<HistogramImpl*>(
|
||||
@@ -279,7 +279,7 @@ index d4dd93d084d5e58f0c18ef82a51d25be4643ba7a..2709cdb31869d9e030c654d975b07967
|
||||
|
||||
void BindingData::MemoryInfo(MemoryTracker* tracker) const {
|
||||
diff --git a/src/node_realm-inl.h b/src/node_realm-inl.h
|
||||
index 0af487a9abc9ee1783367ac86b0016ab89e02006..c01cef477aaba52f9894943acede7fb22ed17dcb 100644
|
||||
index d527a4d4c620a30377ce2c0cdb0ff0cb6a11ec66..97756edfce15b2f3647646146683727b36c0eec3 100644
|
||||
--- a/src/node_realm-inl.h
|
||||
+++ b/src/node_realm-inl.h
|
||||
@@ -22,7 +22,8 @@ inline Realm* Realm::GetCurrent(v8::Local<v8::Context> context) {
|
||||
@@ -293,7 +293,7 @@ index 0af487a9abc9ee1783367ac86b0016ab89e02006..c01cef477aaba52f9894943acede7fb2
|
||||
|
||||
inline Realm* Realm::GetCurrent(
|
||||
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
|
||||
index c3e995adf437413fe956e45c2ccc704d8737de59..ae0613fdf35efcdb4b5917b9ecb3ad12d7bf4976 100644
|
||||
index e773fb1ed4e777667fa677b402b20d676e9af4a2..643cc0bb244c89178a499082f0532d887e18c24c 100644
|
||||
--- a/src/node_snapshotable.cc
|
||||
+++ b/src/node_snapshotable.cc
|
||||
@@ -1370,7 +1370,8 @@ StartupData SerializeNodeContextData(Local<Context> holder,
|
||||
|
||||
@@ -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 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a8151e3792d 100644
|
||||
index 312a857537867e408fe2bd1b1a0d1061c41ccf3b..51b7607854b77ceeb3f9e977ce15594cdb4eaeca 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -792,7 +792,7 @@ std::unique_ptr<MultiIsolatePlatform> MultiIsolatePlatform::Create(
|
||||
@@ -810,7 +810,7 @@ std::unique_ptr<MultiIsolatePlatform> MultiIsolatePlatform::Create(
|
||||
|
||||
MaybeLocal<Object> GetPerContextExports(Local<Context> context,
|
||||
IsolateData* isolate_data) {
|
||||
@@ -18,7 +18,7 @@ index 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a81
|
||||
EscapableHandleScope handle_scope(isolate);
|
||||
|
||||
Local<Object> global = context->Global();
|
||||
@@ -838,7 +838,7 @@ void ProtoThrower(const FunctionCallbackInfo<Value>& info) {
|
||||
@@ -856,7 +856,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 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a81
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
// When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path
|
||||
@@ -917,7 +917,7 @@ Maybe<void> InitializeContextRuntime(Local<Context> context) {
|
||||
@@ -935,7 +935,7 @@ Maybe<void> InitializeContextRuntime(Local<Context> context) {
|
||||
}
|
||||
|
||||
Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
||||
@@ -36,7 +36,7 @@ index 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a81
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
// Delete `Intl.v8BreakIterator`
|
||||
@@ -942,7 +942,7 @@ Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
||||
@@ -960,7 +960,7 @@ Maybe<void> InitializeBaseContextForSnapshot(Local<Context> context) {
|
||||
}
|
||||
|
||||
Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
||||
@@ -45,7 +45,7 @@ index 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a81
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
// Initialize the default values.
|
||||
@@ -960,7 +960,7 @@ Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
||||
@@ -978,7 +978,7 @@ Maybe<void> InitializeMainContextForSnapshot(Local<Context> context) {
|
||||
MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||
IsolateData* isolate_data) {
|
||||
CHECK(isolate_data);
|
||||
@@ -54,7 +54,7 @@ index 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a81
|
||||
EscapableHandleScope scope(isolate);
|
||||
Context::Scope context_scope(context);
|
||||
|
||||
@@ -984,7 +984,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||
@@ -1002,7 +1002,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||
MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||
IsolateData* isolate_data) {
|
||||
CHECK(isolate_data);
|
||||
@@ -63,7 +63,7 @@ index 4dea08fafee4379066a7d8af66fb07c7e7a3490c..ea8ba25085c12f6180c879f19e543a81
|
||||
EscapableHandleScope scope(isolate);
|
||||
Context::Scope context_scope(context);
|
||||
|
||||
@@ -1010,7 +1010,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||
@@ -1028,7 +1028,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||
Maybe<void> InitializePrimordials(Local<Context> context,
|
||||
IsolateData* isolate_data) {
|
||||
// Run per-context JS files.
|
||||
@@ -85,10 +85,10 @@ index cc60ddddb037e0279615bbe24821eb20fd8da677..37d83e41b618a07aca98118260abe961
|
||||
|
||||
return handle;
|
||||
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
||||
index 176c69dfe7a7d1f6dfe33fcc7ffc470e50df50d2..9fbca1812491c8a181ab791eeb33a18f906af66f 100644
|
||||
index 114b0c920882dd267f057c6414563c57e91eb236..ec217aadc4a34ce09742c3b9490634727f387c1d 100644
|
||||
--- a/src/crypto/crypto_context.cc
|
||||
+++ b/src/crypto/crypto_context.cc
|
||||
@@ -1173,7 +1173,7 @@ bool ArrayOfStringsToX509s(Local<Context> context,
|
||||
@@ -1174,7 +1174,7 @@ bool ArrayOfStringsToX509s(Local<Context> context,
|
||||
Local<Array> cert_array,
|
||||
std::vector<X509*>* certs) {
|
||||
ClearErrorOnReturn clear_error_on_return;
|
||||
@@ -98,7 +98,7 @@ index 176c69dfe7a7d1f6dfe33fcc7ffc470e50df50d2..9fbca1812491c8a181ab791eeb33a18f
|
||||
uint32_t array_length = cert_array->Length();
|
||||
|
||||
diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc
|
||||
index 82da68d8eef06c57aae76f2b54eeb09db5b41ecf..9d3fddd63d1e333674633752b2b5243c8d9954c7 100644
|
||||
index 1bf003f830812664ad903dbdfe30366835767c0b..337cd5899f9ced88e9d2eda61ba194b7f70b910a 100644
|
||||
--- a/src/crypto/crypto_x509.cc
|
||||
+++ b/src/crypto/crypto_x509.cc
|
||||
@@ -109,7 +109,7 @@ MaybeLocal<Value> ToV8Value(Local<Context> context, BIOPointer&& bio) {
|
||||
@@ -133,10 +133,10 @@ index 31277621e92b4d3583a67140f4ab8a74a9c6df3b..caa109871b71926f3355491767b8064b
|
||||
// Recreate the buffer in the constructor.
|
||||
InternalFieldInfo* casted_info = static_cast<InternalFieldInfo*>(info);
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index c68bb8e4854a301b6899d2f7183b77dd9ff98c31..3f655793d1353619699d42b09b227c729946075f 100644
|
||||
index 7674b06f7018020f87c32316a66eebc04720ab5e..efda30eb1fb1c18bafd64eed46a6fc72e806a02b 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -1818,10 +1818,10 @@ void AsyncHooks::Deserialize(Local<Context> context) {
|
||||
@@ -1935,10 +1935,10 @@ void AsyncHooks::Deserialize(Local<Context> context) {
|
||||
context->GetDataFromSnapshotOnce<Array>(
|
||||
info_->js_execution_async_resources).ToLocalChecked();
|
||||
} else {
|
||||
@@ -149,7 +149,7 @@ index c68bb8e4854a301b6899d2f7183b77dd9ff98c31..3f655793d1353619699d42b09b227c72
|
||||
|
||||
// The native_execution_async_resources_ field requires v8::Local<> instances
|
||||
// for async calls whose resources were on the stack as JS objects when they
|
||||
@@ -1861,7 +1861,7 @@ AsyncHooks::SerializeInfo AsyncHooks::Serialize(Local<Context> context,
|
||||
@@ -1978,7 +1978,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(
|
||||
@@ -283,10 +283,10 @@ index fbcf8f0f99ccaac583040e1ecebcbf65bd03cfa6..6934e3ca3751091e6ebc7802dabf8b50
|
||||
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 952d51946d9412c376dfe305a2c5fd564b60998c..b0ba5d00ff170a61ee85d4959b879f1515e28484 100644
|
||||
index 564ba432f023ea0575bba72e1a17816faf4d830c..ff11c2ef06a720df01bbdd784746066a7c23ee5b 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -1160,7 +1160,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
||||
@@ -1168,7 +1168,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
||||
|
||||
#define NODE_DEFINE_CONSTANT(target, constant) \
|
||||
do { \
|
||||
@@ -295,7 +295,7 @@ index 952d51946d9412c376dfe305a2c5fd564b60998c..b0ba5d00ff170a61ee85d4959b879f15
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext(); \
|
||||
v8::Local<v8::String> constant_name = v8::String::NewFromUtf8Literal( \
|
||||
isolate, #constant, v8::NewStringType::kInternalized); \
|
||||
@@ -1176,7 +1176,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
||||
@@ -1184,7 +1184,7 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly",
|
||||
|
||||
#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \
|
||||
do { \
|
||||
@@ -305,10 +305,10 @@ index 952d51946d9412c376dfe305a2c5fd564b60998c..b0ba5d00ff170a61ee85d4959b879f15
|
||||
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 d05a693120f2643dc01395493d51db3d3f95f9b7..57d35358fbfd71bc0ef01f8c83f5f00f0b02b8cf 100644
|
||||
index ef148203713880ed3f56698613f9cd9c78ff1fb0..a04bc2be0ef5ab65ac39062de0549bb3e4b168c1 100644
|
||||
--- a/src/node_blob.cc
|
||||
+++ b/src/node_blob.cc
|
||||
@@ -580,7 +580,7 @@ void BlobBindingData::Deserialize(Local<Context> context,
|
||||
@@ -579,7 +579,7 @@ void BlobBindingData::Deserialize(Local<Context> context,
|
||||
int index,
|
||||
InternalFieldInfoBase* info) {
|
||||
DCHECK_IS_SNAPSHOT_SLOT(index);
|
||||
@@ -432,10 +432,10 @@ index 5550a4bee3ce9ec8759d216335a9b2b96e20c96e..b38c2f75a92f2d6c1b9c6e7b7aca9246
|
||||
Local<Array> keys;
|
||||
if (!entries->GetOwnPropertyNames(context).ToLocal(&keys))
|
||||
diff --git a/src/node_errors.cc b/src/node_errors.cc
|
||||
index d79d8d0a1ed63731147007f264541545d724980e..7b29370686a9e4d408f81d7b8bd16c3d533bf33b 100644
|
||||
index 9a7c89b22fe358808fbd9570c7239b4e040ab450..026ee86b455c327fbd5be3472cd504097bf0258b 100644
|
||||
--- a/src/node_errors.cc
|
||||
+++ b/src/node_errors.cc
|
||||
@@ -651,7 +651,7 @@ v8::ModifyCodeGenerationFromStringsResult ModifyCodeGenerationFromStrings(
|
||||
@@ -654,7 +654,7 @@ v8::ModifyCodeGenerationFromStringsResult ModifyCodeGenerationFromStrings(
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Value> source,
|
||||
bool is_code_like) {
|
||||
@@ -444,7 +444,7 @@ index d79d8d0a1ed63731147007f264541545d724980e..7b29370686a9e4d408f81d7b8bd16c3d
|
||||
|
||||
if (context->GetNumberOfEmbedderDataFields() <=
|
||||
ContextEmbedderIndex::kAllowCodeGenerationFromStrings) {
|
||||
@@ -1073,7 +1073,7 @@ const char* errno_string(int errorno) {
|
||||
@@ -1076,7 +1076,7 @@ const char* errno_string(int errorno) {
|
||||
}
|
||||
|
||||
void PerIsolateMessageListener(Local<Message> message, Local<Value> error) {
|
||||
@@ -453,7 +453,7 @@ index d79d8d0a1ed63731147007f264541545d724980e..7b29370686a9e4d408f81d7b8bd16c3d
|
||||
switch (message->ErrorLevel()) {
|
||||
case Isolate::MessageErrorLevel::kMessageWarning: {
|
||||
Environment* env = Environment::GetCurrent(isolate);
|
||||
@@ -1238,7 +1238,7 @@ void Initialize(Local<Object> target,
|
||||
@@ -1241,7 +1241,7 @@ void Initialize(Local<Object> target,
|
||||
SetMethod(
|
||||
context, target, "getErrorSourcePositions", GetErrorSourcePositions);
|
||||
|
||||
@@ -463,10 +463,10 @@ index d79d8d0a1ed63731147007f264541545d724980e..7b29370686a9e4d408f81d7b8bd16c3d
|
||||
READONLY_PROPERTY(target, "exitCodes", exit_codes);
|
||||
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index c2bc9dfaa6a0d10624362d217fe591d8465a6c3a..15a433fc2c1fde03d1e875a88c238bc36fcc6c93 100644
|
||||
index 78d98080323698dc619ebdffda7cb3849d4414bc..fb5aaa3ab08923bf9c1c4e767bad2881510633e8 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -4194,7 +4194,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||
@@ -4272,7 +4272,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||
int index,
|
||||
InternalFieldInfoBase* info) {
|
||||
DCHECK_IS_SNAPSHOT_SLOT(index);
|
||||
@@ -551,10 +551,10 @@ index a33748d360c96368fa623b31ef0711eaaa04267f..d4dd93d084d5e58f0c18ef82a51d25be
|
||||
// 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 6d2e4eb641a8ffaacf4aebd3522008a285387a30..47bd7d9f19077ac7a558c73db5f51bdf8da291e7 100644
|
||||
index 05c37067124898c306ae4eadb986cf038284730c..4444b7d6c52dff2d5ea4c5509df7d932789c8e3a 100644
|
||||
--- a/src/node_realm.cc
|
||||
+++ b/src/node_realm.cc
|
||||
@@ -22,7 +22,7 @@ using v8::String;
|
||||
@@ -20,7 +20,7 @@ using v8::TryCatch;
|
||||
using v8::Value;
|
||||
|
||||
Realm::Realm(Environment* env, v8::Local<v8::Context> context, Kind kind)
|
||||
@@ -562,7 +562,7 @@ index 6d2e4eb641a8ffaacf4aebd3522008a285387a30..47bd7d9f19077ac7a558c73db5f51bdf
|
||||
+ : 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 04c5d415c3c67ef9eba962bc15e738f0df6a005a..b8bb41e88888e426689298a611fc87cb3d8e0caf 100644
|
||||
--- a/src/node_report.cc
|
||||
@@ -577,7 +577,7 @@ index 04c5d415c3c67ef9eba962bc15e738f0df6a005a..b8bb41e88888e426689298a611fc87cb
|
||||
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 41b0773f4c37a016cfa55aff6bb03baf50905b32..c3e995adf437413fe956e45c2ccc704d8737de59 100644
|
||||
index 1d0702ba59be0653b417afc8729306b307ca6272..e773fb1ed4e777667fa677b402b20d676e9af4a2 100644
|
||||
--- a/src/node_snapshotable.cc
|
||||
+++ b/src/node_snapshotable.cc
|
||||
@@ -1675,7 +1675,7 @@ void BindingData::Deserialize(Local<Context> context,
|
||||
@@ -590,10 +590,10 @@ index 41b0773f4c37a016cfa55aff6bb03baf50905b32..c3e995adf437413fe956e45c2ccc704d
|
||||
// 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 ee6a2ece542610cb6e262cca29f9884da6bb2ae5..91ae8c9d31f5c8984c25c1030238fbe0db5c95a2 100644
|
||||
index a0a13c3537e7ae95ae1bf535ec9b50b2469e78a5..f21c7deea5edd85198bb4c015af0d38b42e7d8c9 100644
|
||||
--- a/src/node_sqlite.cc
|
||||
+++ b/src/node_sqlite.cc
|
||||
@@ -2676,7 +2676,7 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -2886,7 +2886,7 @@ bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) {
|
||||
if (args[0]->IsObject() && !args[0]->IsArrayBufferView() &&
|
||||
!args[0]->IsArrayBuffer() && !args[0]->IsSharedArrayBuffer()) {
|
||||
Local<Object> obj = args[0].As<Object>();
|
||||
@@ -688,10 +688,10 @@ index 9bebd4fb1b86b97df59aa2a04106c1916ca658bc..afd17511610cc0977874190aeca9e5e6
|
||||
Storage* storage;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&storage, info.This());
|
||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
||||
index ed3aa30caac3f47691c4a7262e671589c3bace7b..3d6e0bdaaec133e89e947971b37cf0d8bdc08e38 100644
|
||||
index b45ee62d0e13d24c013102ca2b463a2517d92907..91949db98400298ae7a770a76c387fcf2b388571 100644
|
||||
--- a/src/node_worker.cc
|
||||
+++ b/src/node_worker.cc
|
||||
@@ -1466,8 +1466,6 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -1459,8 +1459,6 @@ void GetEnvMessagePort(const FunctionCallbackInfo<Value>& args) {
|
||||
Local<Object> port = env->message_port();
|
||||
CHECK_IMPLIES(!env->is_main_thread(), !port.IsEmpty());
|
||||
if (!port.IsEmpty()) {
|
||||
|
||||
@@ -15,20 +15,20 @@ was missing gypi_values.node_pdl_files from its inputs, causing Ninja to skip
|
||||
regeneration when PDL domain files changed. Should be upstreamed.
|
||||
|
||||
diff --git a/configure.py b/configure.py
|
||||
index 3c3b5a34925b5e578aa4b507674e15b88c4035c7..65da589f59e1eb7fc82c08dc05429fb19a1772eb 100755
|
||||
index b826e24e3f474f4ec89bafd0a6db3081fadfbef8..1b35f195f7ee7547544cc954baf95c725afa8d0b 100755
|
||||
--- a/configure.py
|
||||
+++ b/configure.py
|
||||
@@ -1987,7 +1987,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.
|
||||
- o['variables']['v8_enable_sandbox'] = 0
|
||||
@@ -1955,7 +1955,7 @@ def configure_v8(o, configs):
|
||||
# Like V8's own default, the sandbox goes with the shared pointer compression
|
||||
# cage. Multi-cage builds give every IsolateGroup its own sandbox, which the
|
||||
# array buffer allocator does not know about yet.
|
||||
- o['variables']['v8_enable_sandbox'] = 1 if options.pointer_compression_shared_cage else 0
|
||||
+ o['variables']['v8_enable_sandbox'] = 1 if options.enable_pointer_compression else 0
|
||||
# We set v8_enable_pointer_compression_shared_cage to 0 always, even when
|
||||
# pointer compression is enabled so that we don't accidentally enable shared
|
||||
# cage mode when pointer compression is on.
|
||||
o['variables']['v8_enable_pointer_compression_shared_cage'] = 1 if options.pointer_compression_shared_cage else 0
|
||||
o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0
|
||||
o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
|
||||
diff --git a/node.gni b/node.gni
|
||||
index 41f200189a34e150e4c8f25da2a72c2108259720..156fee33b3813fe4d94a1c9585f217a99dbfbd5f 100644
|
||||
index 28ef444b72c139eb9253122dfaf8b14c8108eac6..0d0438ba8f478a08949ea07cad6c349d15060be9 100644
|
||||
--- a/node.gni
|
||||
+++ b/node.gni
|
||||
@@ -5,10 +5,10 @@
|
||||
@@ -70,7 +70,7 @@ index 41f200189a34e150e4c8f25da2a72c2108259720..156fee33b3813fe4d94a1c9585f217a9
|
||||
+ use_system_histogram = false
|
||||
}
|
||||
|
||||
assert(!node_enable_inspector || node_use_openssl,
|
||||
# Link against shared copies of the bundled dependencies instead of building
|
||||
diff --git a/src/node_builtins.cc b/src/node_builtins.cc
|
||||
index bf1276f82412b7321732995cfc2f93d9cce961a2..cfd8c8c9c7d8911be7b3a66f4695e54f1022a678 100644
|
||||
--- a/src/node_builtins.cc
|
||||
@@ -309,18 +309,9 @@ index 856878c33681a73d41016729dabe48b0a6a80589..91a11852d206b65485fe90fd037a0bd1
|
||||
if sys.platform == 'win32':
|
||||
files = [ x.replace('\\', '/') for x in files ]
|
||||
diff --git a/unofficial.gni b/unofficial.gni
|
||||
index aa78f9ce60c0439536eaf6e23880e30ebef0e1a9..7265e09bf7601afe76463f528ffb385db796e093 100644
|
||||
index aa35cd4664e9ed43b46e1ad62eaabcf1cfe40135..7265e09bf7601afe76463f528ffb385db796e093 100644
|
||||
--- a/unofficial.gni
|
||||
+++ b/unofficial.gni
|
||||
@@ -94,7 +94,7 @@ template("node_gn_build") {
|
||||
"-Wno-unused-function",
|
||||
]
|
||||
|
||||
- if (current_cpu == "x86") {
|
||||
+ if (target_cpu == "x86") {
|
||||
node_arch = "ia32"
|
||||
} else {
|
||||
node_arch = target_cpu
|
||||
@@ -147,32 +147,42 @@ template("node_gn_build") {
|
||||
public_configs = [
|
||||
":node_external_config",
|
||||
|
||||
@@ -7,10 +7,10 @@ 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 83e0691d4a2d86bed83a3caf24d795f14af464bd..7e67f7575c866c7628c980c77d131a4766caf58f 100644
|
||||
index bc690955d3da82216abfe73c92d5ec9c2dbaa784..00b5cea77e949befd234a474a7f109ba47d24d8b 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -93,6 +93,8 @@
|
||||
@@ -96,6 +96,8 @@
|
||||
'v8_use_perfetto': 0,
|
||||
'tsan%': 0,
|
||||
|
||||
@@ -19,7 +19,7 @@ index 83e0691d4a2d86bed83a3caf24d795f14af464bd..7e67f7575c866c7628c980c77d131a47
|
||||
##### end V8 defaults #####
|
||||
|
||||
'conditions': [
|
||||
@@ -344,7 +346,8 @@
|
||||
@@ -347,7 +349,8 @@
|
||||
'_GLIBCXX_USE_CXX11_ABI=1',
|
||||
# This help forks when building Node.js on a 32-bit arch as
|
||||
# libuv is always compiled with _FILE_OFFSET_BITS=64
|
||||
@@ -29,7 +29,7 @@ index 83e0691d4a2d86bed83a3caf24d795f14af464bd..7e67f7575c866c7628c980c77d131a47
|
||||
],
|
||||
|
||||
# Forcibly disable -Werror. We support a wide range of compilers, it's
|
||||
@@ -501,6 +504,11 @@
|
||||
@@ -504,6 +507,11 @@
|
||||
}],
|
||||
],
|
||||
}],
|
||||
@@ -42,10 +42,10 @@ index 83e0691d4a2d86bed83a3caf24d795f14af464bd..7e67f7575c866c7628c980c77d131a47
|
||||
# list in v8/BUILD.gn.
|
||||
['node_enable_experimentals == "true"', {
|
||||
diff --git a/configure.py b/configure.py
|
||||
index 65da589f59e1eb7fc82c08dc05429fb19a1772eb..443818802df9bf62c17aa783617ec5b932cedf81 100755
|
||||
index 1b35f195f7ee7547544cc954baf95c725afa8d0b..172aef2c5194574eb298462588ecf76ae2a2e366 100755
|
||||
--- a/configure.py
|
||||
+++ b/configure.py
|
||||
@@ -1959,6 +1959,7 @@ def configure_library(lib, output, pkgname=None):
|
||||
@@ -1930,6 +1930,7 @@ def configure_library(lib, output, pkgname=None):
|
||||
def configure_v8(o, configs):
|
||||
set_configuration_variable(configs, 'v8_enable_v8_checks', release=0, debug=1)
|
||||
|
||||
@@ -54,7 +54,7 @@ index 65da589f59e1eb7fc82c08dc05429fb19a1772eb..443818802df9bf62c17aa783617ec5b9
|
||||
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 d922352b19414cc6aac1ddd4cf4c6001afc2aa76..3bd4849bb93340569c0067fedd37fefeebff4eb5 100644
|
||||
index 9f9ba48eb8e2ffcac85dd2147fe631204f2a604e..cba83119bfaf88b360b2f1220611a0c642ec7364 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
@@ -14,7 +14,7 @@ and
|
||||
This patch can be removed once this is fixed upstream in simdjson.
|
||||
|
||||
diff --git a/deps/simdjson/simdjson.h b/deps/simdjson/simdjson.h
|
||||
index afcca85ad6bf7835f8f914d9d417f8347ad3db5c..a836ca8cfdb2fa7348ef7c2cf9c21f18ade5707b 100644
|
||||
index 43fe09631c0135af616f9df082c82ba87c434b72..91b0fc22e5965ddb3378887867b5c5c951ae7226 100644
|
||||
--- a/deps/simdjson/simdjson.h
|
||||
+++ b/deps/simdjson/simdjson.h
|
||||
@@ -4408,12 +4408,17 @@ private:
|
||||
@@ -35,7 +35,7 @@ index afcca85ad6bf7835f8f914d9d417f8347ad3db5c..a836ca8cfdb2fa7348ef7c2cf9c21f18
|
||||
namespace simdjson {
|
||||
namespace internal {
|
||||
|
||||
@@ -5115,6 +5120,9 @@ simdjson_inline bool padded_memory_map::is_valid() const noexcept {
|
||||
@@ -5116,6 +5121,9 @@ simdjson_inline bool padded_memory_map::is_valid() const noexcept {
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -45,7 +45,7 @@ index afcca85ad6bf7835f8f914d9d417f8347ad3db5c..a836ca8cfdb2fa7348ef7c2cf9c21f18
|
||||
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
||||
return simdjson::padded_string(str, len);
|
||||
}
|
||||
@@ -5123,6 +5131,8 @@ inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len
|
||||
@@ -5124,6 +5132,8 @@ inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len
|
||||
return simdjson::padded_string(reinterpret_cast<const char *>(str), len);
|
||||
}
|
||||
#endif
|
||||
@@ -54,7 +54,7 @@ index afcca85ad6bf7835f8f914d9d417f8347ad3db5c..a836ca8cfdb2fa7348ef7c2cf9c21f18
|
||||
|
||||
#endif // SIMDJSON_PADDED_STRING_INL_H
|
||||
/* end file simdjson/padded_string-inl.h */
|
||||
@@ -72764,12 +72774,16 @@ simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::
|
||||
@@ -72847,12 +72857,16 @@ simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::
|
||||
return parser_instance;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ index afcca85ad6bf7835f8f914d9d417f8347ad3db5c..a836ca8cfdb2fa7348ef7c2cf9c21f18
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace arm64
|
||||
@@ -86146,12 +86160,16 @@ simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::
|
||||
@@ -86238,12 +86252,16 @@ simdjson_inline simdjson_warn_unused std::unique_ptr<ondemand::parser>& parser::
|
||||
return parser_instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,18 @@ index ab7dc27de3e304f6d912d5834da47e3b4eb25495..b6c0fd4ceee989dac55c7d54e52fef18
|
||||
sources = gypi_values.ada_sources
|
||||
}
|
||||
}
|
||||
diff --git a/deps/ncrypto/unofficial.gni b/deps/ncrypto/unofficial.gni
|
||||
index dad4fbbf16f060a76bc7842135506f30aed7ffc0..d874d4b1e4079b392ba7652ea6bfc7de5e920626 100644
|
||||
--- a/deps/ncrypto/unofficial.gni
|
||||
+++ b/deps/ncrypto/unofficial.gni
|
||||
@@ -26,6 +26,7 @@ template("ncrypto_gn_build") {
|
||||
source_set(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
public_configs = [ ":ncrypto_config" ]
|
||||
+ configs += [ "//build/config/compiler:no_exit_time_destructors" ]
|
||||
defines = [
|
||||
"NCRYPTO_ENGINE_COMPAT=1",
|
||||
"OPENSSL_SUPPRESS_DEPRECATED",
|
||||
diff --git a/unofficial.gni b/unofficial.gni
|
||||
index ca6fab3f2fa162c5292687e4218f7ea2c8bd4b46..1ccb4f3274b50f74e4ea5c309db155d7e0027560 100644
|
||||
--- a/unofficial.gni
|
||||
|
||||
@@ -19,7 +19,7 @@ We're still exploring ways to upstream this. This patch can be removed
|
||||
once Node.js vendors a simdjson release that includes these headers.
|
||||
|
||||
diff --git a/deps/simdjson/simdjson.cpp b/deps/simdjson/simdjson.cpp
|
||||
index 7b8b0c44f05767da92f631d7d117936c556f0db8..975b59f6f3a0d30bdbb62ac292fd95635fab7a04 100644
|
||||
index 71f443b3d2bb4394009600cde34935ec25eff30b..505dc6406f6e14858124a823170f9fbd2fb7c7d8 100644
|
||||
--- a/deps/simdjson/simdjson.cpp
|
||||
+++ b/deps/simdjson/simdjson.cpp
|
||||
@@ -3,6 +3,12 @@
|
||||
@@ -36,7 +36,7 @@ index 7b8b0c44f05767da92f631d7d117936c556f0db8..975b59f6f3a0d30bdbb62ac292fd9563
|
||||
/* begin file base.h */
|
||||
#ifndef SIMDJSON_SRC_BASE_H
|
||||
diff --git a/deps/simdjson/simdjson.h b/deps/simdjson/simdjson.h
|
||||
index a836ca8cfdb2fa7348ef7c2cf9c21f18ade5707b..91047857bb250b5d2c2903f153ff59297b526988 100644
|
||||
index 91b0fc22e5965ddb3378887867b5c5c951ae7226..919e9532f00092997710882a8b223e7b8c1f1096 100644
|
||||
--- a/deps/simdjson/simdjson.h
|
||||
+++ b/deps/simdjson/simdjson.h
|
||||
@@ -4,6 +4,14 @@
|
||||
|
||||
+5
-5
@@ -62,7 +62,7 @@ eliminating the Node bootstrap recompile.
|
||||
config following https://chromium-review.googlesource.com/c/v8/v8/+/7808546.
|
||||
|
||||
diff --git a/node.gni b/node.gni
|
||||
index 156fee33b3813fe4d94a1c9585f217a99dbfbd5f..a443ff52ca1dda5cb2cfdfe5241076836a33b8fc 100644
|
||||
index 0d0438ba8f478a08949ea07cad6c349d15060be9..55f35c4c376e66be291631cff8b1acf266ff41a3 100644
|
||||
--- a/node.gni
|
||||
+++ b/node.gni
|
||||
@@ -31,6 +31,13 @@ declare_args() {
|
||||
@@ -110,12 +110,12 @@ index 156fee33b3813fe4d94a1c9585f217a99dbfbd5f..a443ff52ca1dda5cb2cfdfe524107683
|
||||
# Build with Amaro (TypeScript utils).
|
||||
node_use_amaro = true
|
||||
diff --git a/src/api/embed_helpers.cc b/src/api/embed_helpers.cc
|
||||
index c1bcb3948c4cf68b36dbb1ea985bfb02267ad724..b9ddc1e2139c1a3b869a27f088e6e64688efa0f0 100644
|
||||
index 051110c9c6e96b91fa966f9dc8cd3a161db6d0b2..7b78ed07d020c6553c9fdf449fa057e5daef54a3 100644
|
||||
--- a/src/api/embed_helpers.cc
|
||||
+++ b/src/api/embed_helpers.cc
|
||||
@@ -131,6 +131,15 @@ CommonEnvironmentSetup::CommonEnvironmentSetup(
|
||||
isolate = impl_->isolate = Isolate::Allocate(GetOrCreateIsolateGroup());
|
||||
platform->RegisterIsolate(isolate, loop);
|
||||
params.cpp_heap =
|
||||
v8::CppHeap::Create(platform, v8::CppHeapCreateParams{{}}).release();
|
||||
|
||||
+ // Electron: extend an existing V8 startup snapshot rather than build the
|
||||
+ // heap from scratch (Electron's V8 has external startup data / the
|
||||
@@ -238,7 +238,7 @@ index 664f878c0671db76cbf68116d224606243ddf501..4ed6d6ecf12ea92129f4d7b7fdb59bcb
|
||||
return nullptr;
|
||||
}
|
||||
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
|
||||
index ae0613fdf35efcdb4b5917b9ecb3ad12d7bf4976..bc48096932b0a1004aec4317dc0c265bd6f1c045 100644
|
||||
index 643cc0bb244c89178a499082f0532d887e18c24c..2568e857f299f058c15e41b7990412c51064767e 100644
|
||||
--- a/src/node_snapshotable.cc
|
||||
+++ b/src/node_snapshotable.cc
|
||||
@@ -866,6 +866,19 @@ const std::vector<intptr_t>& SnapshotBuilder::CollectExternalReferences() {
|
||||
|
||||
@@ -8,10 +8,10 @@ an ExternalPointerTypeTag parameter. Use kExternalPointerTypeTagDefault
|
||||
for all existing call sites.
|
||||
|
||||
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
|
||||
index 9fbca1812491c8a181ab791eeb33a18f906af66f..03a3b93f0cf60a6eab4128a8e58a240169ed2d06 100644
|
||||
index ec217aadc4a34ce09742c3b9490634727f387c1d..e857de97428bde0bcd76f486fe29f1befa076e2c 100644
|
||||
--- a/src/crypto/crypto_context.cc
|
||||
+++ b/src/crypto/crypto_context.cc
|
||||
@@ -2625,7 +2625,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
|
||||
@@ -2622,7 +2622,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
|
||||
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
|
||||
SecureContext* sc;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
|
||||
@@ -21,7 +21,7 @@ index 9fbca1812491c8a181ab791eeb33a18f906af66f..03a3b93f0cf60a6eab4128a8e58a2401
|
||||
}
|
||||
|
||||
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
||||
index 75ce4c921b5acf5d612aeb5a7720b5874b6066ac..6c87611f7cbaf8a0b4c04f812f65381ede112056 100644
|
||||
index 5c4a7b611888664ad70e48fb240be7320bac032b..29e2e1808a3f42a35d9478f2f8949037b0011880 100644
|
||||
--- a/src/js_native_api_v8.cc
|
||||
+++ b/src/js_native_api_v8.cc
|
||||
@@ -356,7 +356,7 @@ inline napi_status Unwrap(napi_env env,
|
||||
@@ -100,10 +100,10 @@ index 757d39558f7853d39ee0d574152bb3810cfa3ca5..51c097e69388a516aa7a9239053367fa
|
||||
env->compile_cache_handler()->MaybeSave(cache_entry, utf8.ToStringView());
|
||||
}
|
||||
diff --git a/src/node_util.cc b/src/node_util.cc
|
||||
index ce381c00888b032c281938a7bab334058e075ec8..6d3373caae6c5cc22e16fc32e7ea007178aa1a20 100644
|
||||
index c3a6fbed06efc92e3cc0ac59ab51c8b802033c81..39523bd256c8bf22597ba79dd06ea451025ffabb 100644
|
||||
--- a/src/node_util.cc
|
||||
+++ b/src/node_util.cc
|
||||
@@ -93,7 +93,7 @@ static void GetExternalValue(
|
||||
@@ -96,7 +96,7 @@ static void GetExternalValue(
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<External> external = args[0].As<External>();
|
||||
|
||||
@@ -113,10 +113,10 @@ index ce381c00888b032c281938a7bab334058e075ec8..6d3373caae6c5cc22e16fc32e7ea0071
|
||||
Local<BigInt> ret = BigInt::NewFromUnsigned(isolate, value);
|
||||
args.GetReturnValue().Set(ret);
|
||||
diff --git a/src/stream_base.cc b/src/stream_base.cc
|
||||
index f57f75e5f2750a8f56258c043717c15adad1cf2a..287a41b3af00ea937ca0267a230b94c9c6566f00 100644
|
||||
index ad9affc538732fcc88ef839598b9cbf7e22fd79d..74717fbae8776bdba7c288308c5c1cc7fc8393ef 100644
|
||||
--- a/src/stream_base.cc
|
||||
+++ b/src/stream_base.cc
|
||||
@@ -649,7 +649,7 @@ void StreamBase::GetExternal(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -685,7 +685,7 @@ void StreamBase::GetExternal(const FunctionCallbackInfo<Value>& args) {
|
||||
StreamBase* wrap = StreamBase::FromObject(args.This().As<Object>());
|
||||
if (wrap == nullptr) return;
|
||||
|
||||
|
||||
@@ -50,10 +50,10 @@ index e7311af43237c9459263d15c6b10749b92a5b7d3..66f71c3845361cc380d89ec50472658b
|
||||
const maybeMain = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ?
|
||||
packageConfig.main || './' : '';
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index a576b4a9d4ebbee73cd3ea038ab2d84210fcc21b..c2bc9dfaa6a0d10624362d217fe591d8465a6c3a 100644
|
||||
index acb9e9d669835a5433a47a531b79c3609070d9a0..78d98080323698dc619ebdffda7cb3849d4414bc 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -3943,13 +3943,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -4021,13 +4021,25 @@ static void CpSyncCopyDir(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
BindingData::FilePathIsFileReturnType BindingData::FilePathIsFile(
|
||||
@@ -80,7 +80,7 @@ index a576b4a9d4ebbee73cd3ea038ab2d84210fcc21b..c2bc9dfaa6a0d10624362d217fe591d8
|
||||
uv_fs_t req;
|
||||
|
||||
int rc = uv_fs_stat(env->event_loop(), &req, file_path.c_str(), nullptr);
|
||||
@@ -4007,6 +4019,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -4085,6 +4097,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
std::optional<std::string> initial_file_path;
|
||||
std::string file_path;
|
||||
|
||||
@@ -92,7 +92,7 @@ index a576b4a9d4ebbee73cd3ea038ab2d84210fcc21b..c2bc9dfaa6a0d10624362d217fe591d8
|
||||
if (args.Length() >= 2 && args[1]->IsString()) {
|
||||
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
|
||||
|
||||
@@ -4027,7 +4044,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -4105,7 +4122,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
BufferValue buff_file_path(isolate, local_file_path);
|
||||
ToNamespacedPath(env, &buff_file_path);
|
||||
|
||||
@@ -101,7 +101,7 @@ index a576b4a9d4ebbee73cd3ea038ab2d84210fcc21b..c2bc9dfaa6a0d10624362d217fe591d8
|
||||
case BindingData::FilePathIsFileReturnType::kIsFile:
|
||||
return args.GetReturnValue().Set(i);
|
||||
case BindingData::FilePathIsFileReturnType::kIsNotFile:
|
||||
@@ -4064,7 +4081,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -4142,7 +4159,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||
BufferValue buff_file_path(isolate, local_file_path);
|
||||
ToNamespacedPath(env, &buff_file_path);
|
||||
|
||||
|
||||
@@ -10,23 +10,8 @@ This should be upstreamed in some form, though it may need to be tweaked
|
||||
before it's acceptable to upstream, as this patch comments out a couple
|
||||
of tests that upstream probably cares about.
|
||||
|
||||
diff --git a/test/parallel/test-crypto-keygen-deprecation.js b/test/parallel/test-crypto-keygen-deprecation.js
|
||||
index 926dfbbc4ae987217ab404ec25a3ca0a2ef2edcf..df0b379c1b1e982b96ea97c9814f38991d734ce4 100644
|
||||
--- a/test/parallel/test-crypto-keygen-deprecation.js
|
||||
+++ b/test/parallel/test-crypto-keygen-deprecation.js
|
||||
@@ -4,6 +4,10 @@ const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
+if (process.features.openssl_is_boringssl) {
|
||||
+ common.skip('Skipping unsupported RSA-PSS key tests');
|
||||
+}
|
||||
+
|
||||
const DeprecationWarning = [];
|
||||
DeprecationWarning.push([
|
||||
'"options.hash" is deprecated, use "options.hashAlgorithm" instead.',
|
||||
diff --git a/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js b/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js
|
||||
index 883c2b7123844ede9c729809c2ac11e2c7288d72..54e7ff13547955ee7891fc493765e96aac39ba82 100644
|
||||
index 715b313849dfaed0bae244ae971b8e9cb74a5d76..f42e34900f212399099efd68c9bb2249b1d0157a 100644
|
||||
--- a/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js
|
||||
+++ b/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js
|
||||
@@ -4,6 +4,10 @@ const common = require('../common');
|
||||
@@ -37,7 +22,7 @@ index 883c2b7123844ede9c729809c2ac11e2c7288d72..54e7ff13547955ee7891fc493765e96a
|
||||
+ common.skip('Skipping unsupported ML-DSA key tests');
|
||||
+}
|
||||
+
|
||||
const { hasOpenSSL } = require('../common/crypto');
|
||||
const { hasOpenSSL, isBoringSSL } = require('../common/crypto');
|
||||
|
||||
const assert = require('assert');
|
||||
diff --git a/test/parallel/test-openssl-unreadable-config.js b/test/parallel/test-openssl-unreadable-config.js
|
||||
|
||||
@@ -13,15 +13,17 @@ Refs: https://github.com/nodejs/node/pull/59941
|
||||
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/6937664
|
||||
|
||||
diff --git a/src/node.cc b/src/node.cc
|
||||
index c977e31ab87158a527bf76d0e1f7283e6eeb40eb..f303b0c694c4c32863b15cbcabd315b4f435cd5e 100644
|
||||
index d7fa3d8fdf23610917723b0bb808e19adc002f76..eb8835d5e66c67d6727ef75636770c7cd7c27930 100644
|
||||
--- a/src/node.cc
|
||||
+++ b/src/node.cc
|
||||
@@ -790,9 +790,6 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
|
||||
@@ -790,11 +790,6 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
|
||||
v8_args.emplace_back("--js-source-phase-imports");
|
||||
}
|
||||
|
||||
-#if V8_ENABLE_WEBASSEMBLY
|
||||
- // WebAssembly JS Promise Integration
|
||||
- v8_args.emplace_back("--experimental-wasm-jspi");
|
||||
-#endif // V8_ENABLE_WEBASSEMBLY
|
||||
-
|
||||
#ifdef __POSIX__
|
||||
// Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the
|
||||
|
||||
@@ -26,7 +26,7 @@ TaskQueue<T> without a priority member since the queue became a
|
||||
priority_queue.
|
||||
|
||||
diff --git a/src/node_platform.cc b/src/node_platform.cc
|
||||
index 7f4004b4cb94b813be693818d3c4d96923442eea..c13d363cde2cf028ba3f364db489bb5d6bedf7a6 100644
|
||||
index 0598f17eeb4a15b01297eb8d26d0798ab4a4441a..6893935e7cf7bc5cc92479f553a1e4827820b71d 100644
|
||||
--- a/src/node_platform.cc
|
||||
+++ b/src/node_platform.cc
|
||||
@@ -139,6 +139,7 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
|
||||
|
||||
@@ -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 36e1f920979377ae191347b70958850a58607c1d..f85e0892133c5f97c676276751063c872e9f06b3 100644
|
||||
index 564d3fa3c7a24ccabb0dda2ca4e1d07ec9c34502..34eac82fd87afd00695f1e482dda7c8d83ff4268 100644
|
||||
--- a/src/env_properties.h
|
||||
+++ b/src/env_properties.h
|
||||
@@ -517,6 +517,7 @@
|
||||
@@ -498,6 +498,7 @@
|
||||
V(maybe_cache_generated_source_map, v8::Function) \
|
||||
V(messaging_deserialize_create_object, v8::Function) \
|
||||
V(message_port, v8::Object) \
|
||||
|
||||
@@ -16,28 +16,8 @@ Upstreams:
|
||||
- https://github.com/nodejs/node/pull/39138
|
||||
- https://github.com/nodejs/node/pull/39136
|
||||
|
||||
diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc
|
||||
index b7bbaccfc3a568b7ccfed97f01f2bc37a56b70dd..8c34bb9434284f4d25b4a472cb5496d22d47ce3e 100644
|
||||
--- a/deps/ncrypto/ncrypto.cc
|
||||
+++ b/deps/ncrypto/ncrypto.cc
|
||||
@@ -3347,6 +3347,7 @@ constexpr bool IsASN1Sequence(const unsigned char* data,
|
||||
return true;
|
||||
}
|
||||
|
||||
+#if NCRYPTO_USE_OPENSSL3_PROVIDER
|
||||
constexpr bool ReadASN1Element(const unsigned char* data,
|
||||
size_t size,
|
||||
unsigned char tag,
|
||||
@@ -3374,6 +3375,7 @@ constexpr bool ReadASN1Element(const unsigned char* data,
|
||||
*total_size = offset + length;
|
||||
return true;
|
||||
}
|
||||
+#endif // NCRYPTO_USE_OPENSSL3_PROVIDER
|
||||
|
||||
constexpr bool IsEncryptedPrivateKeyInfo(
|
||||
const Buffer<const unsigned char>& buffer) {
|
||||
diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc
|
||||
index fde12953860cd0a40d04e6342b91337045bc784e..08f567bc4bf22840756b81b8a7c8cdf7dd53326f 100644
|
||||
index ea0747511a107c96befd2dae1d7bd56759dd95b6..14dccb316ae600e55b2321e185e6d5833ba54575 100644
|
||||
--- a/src/crypto/crypto_common.cc
|
||||
+++ b/src/crypto/crypto_common.cc
|
||||
@@ -90,7 +90,7 @@ StackOfX509 CloneSSLCerts(X509Pointer&& cert,
|
||||
@@ -59,10 +39,10 @@ index fde12953860cd0a40d04e6342b91337045bc784e..08f567bc4bf22840756b81b8a7c8cdf7
|
||||
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 af8d52fbe699a1b8721f09ea53503edaa91ce60a..176c69dfe7a7d1f6dfe33fcc7ffc470e50df50d2 100644
|
||||
index 74ea622dad505586a9437097d36e84b7c11f0aa5..114b0c920882dd267f057c6414563c57e91eb236 100644
|
||||
--- a/src/crypto/crypto_context.cc
|
||||
+++ b/src/crypto/crypto_context.cc
|
||||
@@ -169,7 +169,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
|
||||
@@ -170,7 +170,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
|
||||
// the CA certificates.
|
||||
SSL_CTX_clear_extra_chain_certs(ctx);
|
||||
|
||||
@@ -71,7 +51,7 @@ index af8d52fbe699a1b8721f09ea53503edaa91ce60a..176c69dfe7a7d1f6dfe33fcc7ffc470e
|
||||
X509* ca = sk_X509_value(extra_certs, i);
|
||||
|
||||
// NOTE: Increments reference count on `ca`
|
||||
@@ -2345,7 +2345,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -2360,7 +2360,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
// Add CA certs too
|
||||
@@ -80,31 +60,11 @@ index af8d52fbe699a1b8721f09ea53503edaa91ce60a..176c69dfe7a7d1f6dfe33fcc7ffc470e
|
||||
X509* ca = sk_X509_value(extra_certs.get(), i);
|
||||
|
||||
X509_STORE_add_cert(sc->GetCertStoreOwnedByThisSecureContext(), ca);
|
||||
diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc
|
||||
index 6418283e7e4ef06a4cacb973255dd42ccbe246ab..678ae4ebde6e0f12e09a3e9c01f8b9a560186c1e 100644
|
||||
--- a/src/crypto/crypto_dh.cc
|
||||
+++ b/src/crypto/crypto_dh.cc
|
||||
@@ -458,11 +458,12 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
|
||||
if (!dh) return {};
|
||||
|
||||
key_params = EVPKeyPointer::NewDH(std::move(dh));
|
||||
- } else if (int* prime_size = std::get_if<int>(¶ms->params.prime)) {
|
||||
- auto param_ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_DH);
|
||||
+ } else if (std::holds_alternative<int>(params->params.prime)) {
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
+ auto param_ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_DH);
|
||||
if (!param_ctx.initForParamgen() ||
|
||||
- !param_ctx.setDhParameters(*prime_size, params->params.generator)) {
|
||||
+ !param_ctx.setDhParameters(std::get<int>(params->params.prime),
|
||||
+ params->params.generator)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc
|
||||
index f1a7bab16967b0b6e94e859d9a0af65ad65fd008..d250ee36017449b5081890a3af686e4ad45a1e42 100644
|
||||
index 2cf971347b9ea98bf76a8d277a46d7a6842efda6..326120e21d38ad0c78a92658353c8252db49ff28 100644
|
||||
--- a/src/crypto/crypto_hash.cc
|
||||
+++ b/src/crypto/crypto_hash.cc
|
||||
@@ -282,7 +282,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -380,7 +380,7 @@ void OneShotDigestWithMD(Environment* env,
|
||||
enum encoding output_enc = ParseEncoding(isolate, args[4], args[5], HEX);
|
||||
|
||||
bool is_xof = (EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0;
|
||||
@@ -113,19 +73,19 @@ index f1a7bab16967b0b6e94e859d9a0af65ad65fd008..d250ee36017449b5081890a3af686e4a
|
||||
|
||||
// This is to cause hash() to fail when an incorrect
|
||||
// outputLength option was passed for a non-XOF hash function.
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index c5501cd7914a7369c2b93f2b66127e6901852692..499dcb86728d83656b9283ef004b519f46cb2b24 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "v8-profiler.h"
|
||||
#include "v8.h"
|
||||
|
||||
-#if HAVE_OPENSSL
|
||||
+#if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc
|
||||
index 0050e5591e2ae0afb517500934ddfb223078bd76..944802925def832be06a05f05a9ff535b5e0d97c 100644
|
||||
--- a/src/crypto/crypto_x509.cc
|
||||
+++ b/src/crypto/crypto_x509.cc
|
||||
@@ -946,7 +946,7 @@ MaybeLocal<Object> X509Certificate::NewWithIssuers(
|
||||
}
|
||||
|
||||
Local<Object> issuer;
|
||||
- if (issuer_chain != nullptr && start < sk_X509_num(issuer_chain)) {
|
||||
+ if (issuer_chain != nullptr && start < static_cast<int>(sk_X509_num(issuer_chain))) {
|
||||
X509Pointer issuer_cert =
|
||||
X509View(sk_X509_value(issuer_chain, start)).clone();
|
||||
if (!issuer_cert) [[unlikely]] {
|
||||
diff --git a/src/node_metadata.h b/src/node_metadata.h
|
||||
index 8703e4315a999df505ff322aea05a268e017831e..18ddb44400f90f2fbea4ffad09cc1a8f986bf997 100644
|
||||
--- a/src/node_metadata.h
|
||||
@@ -140,7 +100,7 @@ index 8703e4315a999df505ff322aea05a268e017831e..18ddb44400f90f2fbea4ffad09cc1a8f
|
||||
#include <quic/guard.h>
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
diff --git a/src/node_options.h b/src/node_options.h
|
||||
index 870a6babc770b35c93ac5528ab765bae81b1f40b..4ffcdb8c1f9e1d866960c419569f3410f8e50934 100644
|
||||
index b55fae0a32175fdff7a0c3ecb479297bd035eb7e..04eaa705e8023dab7104ac4d55f9d4179b7f30d4 100644
|
||||
--- a/src/node_options.h
|
||||
+++ b/src/node_options.h
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
@@ -39,10 +39,10 @@ Three classes of fixes, all of which give the affected symbols strong
|
||||
Observed on macOS arm64 official builds; latent on Linux/Windows.
|
||||
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index 5389d6e699f32dacfd4d5710258f04f1cb9f9d12..c665e08b6d4eb3f1f772451e6bed1ae746f0d2f3 100644
|
||||
index beb700dbe9fabcfe7c154a4c9e0f3dd8c95bc52e..f86232b125d9967f3021348cf88f132c391b2e0e 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -2328,4 +2328,8 @@ v8::CpuProfile* Environment::StopCpuProfile(v8::ProfilerId profile_id) {
|
||||
@@ -2445,4 +2445,8 @@ v8::CpuProfile* Environment::StopCpuProfile(v8::ProfilerId profile_id) {
|
||||
return profile;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ index 72c1a73aa6c06f55f655cabd0416a709c31e2722..bb7519e4b984ef9915f72bdfb08414f0
|
||||
public:
|
||||
explicit JSGraph(Isolate* isolate) : isolate_(isolate) {}
|
||||
diff --git a/src/js_native_api.h b/src/js_native_api.h
|
||||
index d2375ecd32483ff57840d30f804100372f2e12db..396f7848952e941b3e667b47424c51664cac72ef 100644
|
||||
index 2a36c4e3ddf397f8df6d535bdd61e8a1fb720ebb..4d97fe40c8935f0e23a42e8e7034bcb9155600fb 100644
|
||||
--- a/src/js_native_api.h
|
||||
+++ b/src/js_native_api.h
|
||||
@@ -17,7 +17,7 @@
|
||||
@@ -126,10 +126,10 @@ index f4094b05b0122377c826828457a842cde0acb2e8..a6a0ffb0ed272b9b05acc9cb32aa7951
|
||||
|
||||
NODE_BINDING_PER_ISOLATE_INIT(
|
||||
diff --git a/src/node_http2.cc b/src/node_http2.cc
|
||||
index b6bbb1a4edc33da3b77806c095213e0d663ad1a6..426d25d13c28d0282d217a54d66549324ff875ed 100644
|
||||
index 010109791f0b3727dcf8cbad484341ae654a56f1..4ad6f6d25c8c4e326d9bcbebb43b4b663974ccb0 100644
|
||||
--- a/src/node_http2.cc
|
||||
+++ b/src/node_http2.cc
|
||||
@@ -3795,6 +3795,13 @@ void Http2Session::MaybeNotifyGracefulCloseComplete() {
|
||||
@@ -3749,6 +3749,13 @@ void Http2Session::MaybeNotifyGracefulCloseComplete() {
|
||||
return;
|
||||
}
|
||||
} // namespace http2
|
||||
@@ -144,7 +144,7 @@ index b6bbb1a4edc33da3b77806c095213e0d663ad1a6..426d25d13c28d0282d217a54d6654932
|
||||
|
||||
NODE_BINDING_CONTEXT_AWARE_INTERNAL(http2, node::http2::Initialize)
|
||||
diff --git a/src/node_http2.h b/src/node_http2.h
|
||||
index f321bf0c16018fa134202784a8e1c30e017d2de8..df19438171dbf2164e735d576036b8ea462065be 100644
|
||||
index 94e77cbc6fa62af386beb4da5de0eb93a7788174..793bc3e27eccb1037518ad0d70f748b032fb6b55 100644
|
||||
--- a/src/node_http2.h
|
||||
+++ b/src/node_http2.h
|
||||
@@ -146,6 +146,96 @@ struct Http2RcBufferPointerTraits {
|
||||
|
||||
@@ -20,10 +20,10 @@ tag ranges used by Blink and gin, which share isolates with Node.js in
|
||||
renderer processes.
|
||||
|
||||
diff --git a/src/cppgc_helpers-inl.h b/src/cppgc_helpers-inl.h
|
||||
index 0e52bf5a6f4837d0f4bfed83987c6903796fda55..68c70153b96cc3e62db1b5dc74ac4026fa306271 100644
|
||||
index 745f2c0526fafc1079b94be875a9e5a519d3a794..f81b087ad21a28ec2385cd0cfae3177a470a2850 100644
|
||||
--- a/src/cppgc_helpers-inl.h
|
||||
+++ b/src/cppgc_helpers-inl.h
|
||||
@@ -16,7 +16,7 @@ void CppgcMixin::Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj) {
|
||||
@@ -15,7 +15,7 @@ void CppgcMixin::Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj) {
|
||||
ptr->traced_reference_ = v8::TracedReference<v8::Object>(isolate, obj);
|
||||
// Note that ptr must be of concrete type T in Wrap.
|
||||
auto* wrappable = static_cast<v8::Object::Wrappable*>(ptr);
|
||||
@@ -33,7 +33,7 @@ index 0e52bf5a6f4837d0f4bfed83987c6903796fda55..68c70153b96cc3e62db1b5dc74ac4026
|
||||
obj->SetAlignedPointerInInternalField(
|
||||
kEmbedderType, realm->isolate_data()->embedder_id_for_cppgc(), 0);
|
||||
diff --git a/src/cppgc_helpers.h b/src/cppgc_helpers.h
|
||||
index fe6300a5d5d2d6602a84cbd33736c2133041d1b0..b9153306b6cbc34d076c0eb5b32ecce3c5de98de 100644
|
||||
index f1363d5da78f7a3603fb4502489ecf2ee3483fdb..7baf7b11a68c2cbb83bd67a152be74a8533ecdb0 100644
|
||||
--- a/src/cppgc_helpers.h
|
||||
+++ b/src/cppgc_helpers.h
|
||||
@@ -19,6 +19,25 @@ class Environment;
|
||||
@@ -63,10 +63,10 @@ index fe6300a5d5d2d6602a84cbd33736c2133041d1b0..b9153306b6cbc34d076c0eb5b32ecce3
|
||||
* This is a helper mixin with a BaseObject-like interface to help
|
||||
* implementing wrapper objects managed by V8's cppgc (Oilpan) library.
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index c665e08b6d4eb3f1f772451e6bed1ae746f0d2f3..ea0ff5b84f4a54a3f8efdfadb9f22e1120a9519e 100644
|
||||
index f86232b125d9967f3021348cf88f132c391b2e0e..f72aafe07c039c6d63b74c80cd252f830930d121 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -643,8 +643,7 @@ IsolateData::~IsolateData() {}
|
||||
@@ -644,8 +644,7 @@ IsolateData::~IsolateData() {}
|
||||
void SetCppgcReference(Isolate* isolate,
|
||||
Local<Object> object,
|
||||
v8::Object::Wrappable* wrappable) {
|
||||
|
||||
@@ -20,7 +20,7 @@ allowing contentTracing to remain the sole owner of category filtering,
|
||||
recording sessions, output, and lifecycle.
|
||||
|
||||
diff --git a/node.gni b/node.gni
|
||||
index a443ff52ca1dda5cb2cfdfe5241076836a33b8fc..7d764d56c5e6318f8faf085b029c994d29ad37ce 100644
|
||||
index 55f35c4c376e66be291631cff8b1acf266ff41a3..102e27726b7bd7f4adb290c43ceadc1559b27e54 100644
|
||||
--- a/node.gni
|
||||
+++ b/node.gni
|
||||
@@ -57,6 +57,10 @@ declare_args() {
|
||||
@@ -49,10 +49,10 @@ index b7d0041d0737f7e0315216748e3a5908428c7d1c..b48efd7e1a611dddb5724d65d623c8a2
|
||||
get_trigger_async_id());
|
||||
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(TRACING_CATEGORY_NODE1(async_hooks),
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index ea0ff5b84f4a54a3f8efdfadb9f22e1120a9519e..d5f6d6b07a95dcca1fa00e899e5ad416b4fa626a 100644
|
||||
index f72aafe07c039c6d63b74c80cd252f830930d121..65df49c367c6a378ffe1931bf8afa6315388a446 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -685,8 +685,8 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {
|
||||
@@ -686,8 +686,8 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ index ea0ff5b84f4a54a3f8efdfadb9f22e1120a9519e..d5f6d6b07a95dcca1fa00e899e5ad416
|
||||
|
||||
Isolate* isolate = env_->isolate();
|
||||
HandleScope handle_scope(isolate);
|
||||
@@ -945,8 +945,7 @@ Environment::Environment(IsolateData* isolate_data,
|
||||
@@ -1053,8 +1053,7 @@ Environment::Environment(IsolateData* isolate_data,
|
||||
time_origin_timestamp_,
|
||||
MAYBE_FIELD_PTR(env_info, performance_state));
|
||||
|
||||
@@ -74,7 +74,7 @@ index ea0ff5b84f4a54a3f8efdfadb9f22e1120a9519e..d5f6d6b07a95dcca1fa00e899e5ad416
|
||||
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(TRACING_CATEGORY_NODE1(environment),
|
||||
"Environment",
|
||||
diff --git a/src/node.cc b/src/node.cc
|
||||
index 838106acff8fda886a11a28e9f23f47588a2e8d4..c977e31ab87158a527bf76d0e1f7283e6eeb40eb 100644
|
||||
index 92c5fd8cb66f063e7cb4084b98500f28c60ec29a..d7fa3d8fdf23610917723b0bb808e19adc002f76 100644
|
||||
--- a/src/node.cc
|
||||
+++ b/src/node.cc
|
||||
@@ -47,6 +47,10 @@
|
||||
@@ -88,7 +88,7 @@ index 838106acff8fda886a11a28e9f23f47588a2e8d4..c977e31ab87158a527bf76d0e1f7283e
|
||||
#if HAVE_OPENSSL
|
||||
#include "ncrypto.h"
|
||||
#include "node_crypto.h"
|
||||
@@ -1135,6 +1139,14 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
|
||||
@@ -1137,6 +1141,14 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ index 952161d9e2cf1c92c3600fc2da0af594cc3f53bd..17976d01e4f4f2bf87a38a4fdb36fc70
|
||||
if (GET_TRACE_ENABLED) { \
|
||||
TRACE_EVENT0(TRACING_CATEGORY_NODE2(fs_dir, sync), TRACE_NAME(syscall)); \
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index 06bafaea64e7fbb2b5f32e92fd7dc79be875ac68..d995103234649e9ac2c4dd9fbcc7869a483cc855 100644
|
||||
index b6e2d325e338aedcab3e7fa2038e773930f56fcd..b74809f65c60e7c9f5c13b39f7d11a8c49b59fd0 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -147,8 +147,7 @@ static const char* get_fs_func_name_by_type(uv_fs_type req_type) {
|
||||
@@ -146,7 +146,7 @@ index 06bafaea64e7fbb2b5f32e92fd7dc79be875ac68..d995103234649e9ac2c4dd9fbcc7869a
|
||||
if (GET_TRACE_ENABLED) \
|
||||
TRACE_EVENT_BEGIN( \
|
||||
diff --git a/src/node_internals.h b/src/node_internals.h
|
||||
index 24c5dbe405d69ceb0e515aeaa6b26233bb2943a9..3504c170e0c335274166a5666695b49d4a06c957 100644
|
||||
index 39e8312ddd7167ee235927e1772f6d4dff98a5ad..7b6a516eab2239428368357aec177ea7d9b50ded 100644
|
||||
--- a/src/node_internals.h
|
||||
+++ b/src/node_internals.h
|
||||
@@ -315,7 +315,14 @@ class ThreadPoolWork {
|
||||
@@ -177,7 +177,7 @@ index 24c5dbe405d69ceb0e515aeaa6b26233bb2943a9..3504c170e0c335274166a5666695b49d
|
||||
// Functions defined in node.cc that are exposed via the bootstrapper object
|
||||
|
||||
diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc
|
||||
index 412b5b67b35dfd192af04485e9c858f9862e9e0a..2fc6f4d338ffcbdb57236af5d121279e61156299 100644
|
||||
index c8f2a58734ee6d2ab440cd2439574cbd09d6fc00..ca49f05085161c6ffa9661d5da7c80a28bfe1412 100644
|
||||
--- a/src/node_trace_events.cc
|
||||
+++ b/src/node_trace_events.cc
|
||||
@@ -75,7 +75,6 @@ void NodeCategorySet::New(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -219,7 +219,7 @@ index 412b5b67b35dfd192af04485e9c858f9862e9e0a..2fc6f4d338ffcbdb57236af5d121279e
|
||||
category_set->enabled_ = true;
|
||||
}
|
||||
}
|
||||
@@ -107,16 +109,19 @@ void NodeCategorySet::Disable(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -107,8 +109,10 @@ void NodeCategorySet::Disable(const FunctionCallbackInfo<Value>& args) {
|
||||
const auto& categories = category_set->GetCategories();
|
||||
if (category_set->enabled_ && !categories.empty()) {
|
||||
auto* agent = tracing::Agent::GetInstance();
|
||||
@@ -232,6 +232,7 @@ index 412b5b67b35dfd192af04485e9c858f9862e9e0a..2fc6f4d338ffcbdb57236af5d121279e
|
||||
category_set->enabled_ = false;
|
||||
}
|
||||
}
|
||||
@@ -119,8 +123,9 @@ static void HasAgent(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
void GetEnabledCategories(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
@@ -242,7 +243,7 @@ index 412b5b67b35dfd192af04485e9c858f9862e9e0a..2fc6f4d338ffcbdb57236af5d121279e
|
||||
Local<Value> ret;
|
||||
if (!categories.empty() &&
|
||||
ToV8Value(env->context(), categories, env->isolate()).ToLocal(&ret)) {
|
||||
@@ -137,8 +142,12 @@ static void GetCategoryEnabledBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -141,8 +146,12 @@ static void GetCategoryEnabledBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
node::Utf8Value category_name(isolate, args[0]);
|
||||
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Sparsh :)" <76697238+SparshGarg999@users.noreply.github.com>
|
||||
Date: Tue, 8 Sep 2026 10:23:09 +0530
|
||||
Subject: fs: support removing read-only files in rmSync on Windows
|
||||
|
||||
On Windows, libc++ std::filesystem::remove and remove_all do not
|
||||
automatically clear the read-only attribute before deleting a file
|
||||
(unlike MSVC STL). This causes fs.rmSync to fail with EPERM when
|
||||
trying to remove read-only files in environments where Node.js is
|
||||
built using clang libc++ (such as Electron).
|
||||
|
||||
This commit introduces a Windows-specific helper
|
||||
ClearReadOnlyAttributeW which clears the FILE_ATTRIBUTE_READONLY
|
||||
attribute recursively (or for a single file) when
|
||||
operation_not_permitted is returned, allowing rmSync to
|
||||
successfully delete read-only files/folders.
|
||||
|
||||
Fixes: https://github.com/nodejs/node/issues/64374
|
||||
|
||||
Signed-off-by: SparshGarg999 <sparshgarg999@gmail.com>
|
||||
PR-URL: https://github.com/nodejs/node/pull/64453
|
||||
Fixes: https://github.com/nodejs/node/issues/64374
|
||||
Reviewed-By: Stefan Stojanovic <stefan.stojanovic@janeasystems.com>
|
||||
(cherry picked from commit 2987a5965f1f5c6d9f0023406389c57002e63629)
|
||||
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index d995103234649e9ac2c4dd9fbcc7869a483cc855..e6b22eebaf07589ab0ad17a49067e65078fe9376 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -1750,6 +1750,41 @@ static void RMDir(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef _WIN32
|
||||
+static void ClearReadOnlyAttributeWHelper(const wchar_t* path) {
|
||||
+ DWORD attrs = GetFileAttributesW(path);
|
||||
+ if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_READONLY)) {
|
||||
+ SetFileAttributesW(path, attrs & ~FILE_ATTRIBUTE_READONLY);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ClearReadOnlyAttributeW(const std::filesystem::path& path,
|
||||
+ bool recursive) {
|
||||
+ std::error_code ec;
|
||||
+ auto file_status = std::filesystem::symlink_status(path, ec);
|
||||
+ if (ec) return;
|
||||
+
|
||||
+ if (recursive &&
|
||||
+ file_status.type() == std::filesystem::file_type::directory) {
|
||||
+ for (const auto& entry : std::filesystem::recursive_directory_iterator(
|
||||
+ path,
|
||||
+ std::filesystem::directory_options::skip_permission_denied,
|
||||
+ ec)) {
|
||||
+ std::error_code entry_ec;
|
||||
+ auto entry_status = entry.symlink_status(entry_ec);
|
||||
+ if (entry_ec) continue;
|
||||
+ if (entry_status.type() != std::filesystem::file_type::symlink) {
|
||||
+ ClearReadOnlyAttributeWHelper(entry.path().c_str());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (file_status.type() != std::filesystem::file_type::symlink) {
|
||||
+ ClearReadOnlyAttributeWHelper(path.c_str());
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static void RmSync(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
Isolate* isolate = env->isolate();
|
||||
@@ -1797,6 +1832,9 @@ static void RmSync(const FunctionCallbackInfo<Value>& args) {
|
||||
};
|
||||
|
||||
int i = 1;
|
||||
+#ifdef _WIN32
|
||||
+ bool cleared_readonly = false;
|
||||
+#endif
|
||||
|
||||
while (maxRetries >= 0) {
|
||||
if (recursive) {
|
||||
@@ -1805,6 +1843,22 @@ static void RmSync(const FunctionCallbackInfo<Value>& args) {
|
||||
std::filesystem::remove(file_path, error);
|
||||
}
|
||||
|
||||
+#ifdef _WIN32
|
||||
+ // On Windows, libc++ does not clear the read-only attribute before
|
||||
+ // removing a file (unlike MSVC STL which does). Attempt to clear it
|
||||
+ // manually when we get EPERM (operation_not_permitted) so that read-only
|
||||
+ // files can be deleted, matching the behavior of official Node.js builds.
|
||||
+ if (error == std::errc::operation_not_permitted && !cleared_readonly) {
|
||||
+ cleared_readonly = true;
|
||||
+ ClearReadOnlyAttributeW(file_path, recursive);
|
||||
+ if (recursive) {
|
||||
+ std::filesystem::remove_all(file_path, error);
|
||||
+ } else {
|
||||
+ std::filesystem::remove(file_path, error);
|
||||
+ }
|
||||
+ }
|
||||
+#endif // _WIN32
|
||||
+
|
||||
if (!error || error == std::errc::no_such_file_or_directory) {
|
||||
return;
|
||||
} else if (!can_omit_error(error)) {
|
||||
diff --git a/test/parallel/test-fs-rm.js b/test/parallel/test-fs-rm.js
|
||||
index b15118fc9aa0d63688cdac07e8004f452d86d08e..6a2607ad57ece1e9a0b82dded7bf46bb722e18d9 100644
|
||||
--- a/test/parallel/test-fs-rm.js
|
||||
+++ b/test/parallel/test-fs-rm.js
|
||||
@@ -632,3 +632,30 @@ if (isGitPresent) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+{
|
||||
+ // Test that rmSync can delete read-only files (and directories containing read-only files recursively)
|
||||
+ const dirname = nextDirPath();
|
||||
+ const filePath = path.join(dirname, 'readonly-file.txt');
|
||||
+ const recursiveDir = path.join(dirname, 'subdir');
|
||||
+ const recursiveFilePath = path.join(recursiveDir, 'readonly-nested.txt');
|
||||
+
|
||||
+ fs.mkdirSync(recursiveDir, { recursive: true });
|
||||
+ fs.writeFileSync(filePath, 'hello');
|
||||
+ fs.writeFileSync(recursiveFilePath, 'world');
|
||||
+
|
||||
+ // Make files read-only
|
||||
+ fs.chmodSync(filePath, 0o444);
|
||||
+ fs.chmodSync(recursiveFilePath, 0o444);
|
||||
+
|
||||
+ // rmSync without recursive option on a file
|
||||
+ fs.rmSync(filePath);
|
||||
+ assert.strictEqual(fs.existsSync(filePath), false);
|
||||
+
|
||||
+ // rmSync with recursive option on a directory containing a read-only file
|
||||
+ fs.rmSync(recursiveDir, { recursive: true });
|
||||
+ assert.strictEqual(fs.existsSync(recursiveDir), false);
|
||||
+
|
||||
+ // Clean up parent directory
|
||||
+ fs.rmSync(dirname, { recursive: true, force: true });
|
||||
+}
|
||||
@@ -13,10 +13,10 @@ FallThrough method was also removed upstream; drop it here too.
|
||||
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7885632
|
||||
|
||||
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
|
||||
index 1f86e4bfc2652c7526af1582ac05b8b7a224a47a..55fe49c1e3058c366ede37a7698aefae82ea3f75 100644
|
||||
index 31277a74d1f3d3c8b733bfe0a21b25b2d19a4bc4..351033ebc10879a440f99667eddd4cc1cfe604a5 100644
|
||||
--- a/src/inspector_agent.cc
|
||||
+++ b/src/inspector_agent.cc
|
||||
@@ -321,21 +321,16 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
@@ -328,21 +328,16 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
|
||||
std::vector<uint8_t> cbor_buffer;
|
||||
ConvertJSONToCBOR(crdtp::SpanFrom(raw_message), &cbor_buffer);
|
||||
@@ -42,7 +42,7 @@ index 1f86e4bfc2652c7526af1582ac05b8b7a224a47a..55fe49c1e3058c366ede37a7698aefae
|
||||
}
|
||||
|
||||
void schedulePauseOnNextStatement(const std::string& reason) {
|
||||
@@ -428,13 +423,6 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
@@ -435,13 +430,6 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
sendMessageToFrontend(json);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ call into JS from an interrupt.
|
||||
Upstreamed at https://github.com/nodejs/node/pull/65397.
|
||||
|
||||
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
|
||||
index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d45b56c60b 100644
|
||||
index 351033ebc10879a440f99667eddd4cc1cfe604a5..c22d6fc36b9cef4c15fe579bc3f9acf979528e8e 100644
|
||||
--- a/src/inspector_agent.cc
|
||||
+++ b/src/inspector_agent.cc
|
||||
@@ -54,6 +54,7 @@ using crdtp::UberDispatcher;
|
||||
@@ -27,9 +27,9 @@ index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d4
|
||||
using v8::Function;
|
||||
using v8::HandleScope;
|
||||
using v8::Isolate;
|
||||
@@ -77,6 +78,53 @@ static std::atomic_bool start_io_thread_async_initialized { false };
|
||||
// Protects the Agent* stored in start_io_thread_async.data.
|
||||
static Mutex start_io_thread_async_mutex;
|
||||
@@ -77,6 +78,53 @@ static Mutex start_io_thread_agents_mutex;
|
||||
static std::vector<Agent*> start_io_thread_agents;
|
||||
static bool debug_signal_handler_started = false;
|
||||
|
||||
+template <typename Defer, typename OnFailure>
|
||||
+void SyncJavaScriptHookState(Environment* env,
|
||||
@@ -78,10 +78,10 @@ index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d4
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// Called on the main thread.
|
||||
void StartIoThreadAsyncCallback(uv_async_t* handle) {
|
||||
static_cast<Agent*>(handle->data)->StartIoThread();
|
||||
@@ -455,6 +503,15 @@ class SameThreadInspectorSession : public InspectorSession {
|
||||
static void RequestIoThreadStartOnAgents() {
|
||||
Mutex::ScopedLock lock(start_io_thread_agents_mutex);
|
||||
for (Agent* agent : start_io_thread_agents) agent->RequestIoThreadStart();
|
||||
@@ -462,6 +510,15 @@ class SameThreadInspectorSession : public InspectorSession {
|
||||
|
||||
void NotifyClusterWorkersDebugEnabled(Environment* env) {
|
||||
Isolate* isolate = env->isolate();
|
||||
@@ -97,7 +97,7 @@ index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d4
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
// Send message to enable debug in cluster workers
|
||||
@@ -959,54 +1016,40 @@ void Agent::SetupNetworkTracking(Local<Function> enable_function,
|
||||
@@ -974,54 +1031,40 @@ void Agent::SetupNetworkTracking(Local<Function> enable_function,
|
||||
Local<Function> disable_function) {
|
||||
parent_env_->set_inspector_enable_network_tracking(enable_function);
|
||||
parent_env_->set_inspector_disable_network_tracking(disable_function);
|
||||
@@ -177,7 +177,7 @@ index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d4
|
||||
}
|
||||
|
||||
void Agent::WaitForDisconnect() {
|
||||
@@ -1057,7 +1100,7 @@ void Agent::RegisterAsyncHook(Isolate* isolate,
|
||||
@@ -1072,7 +1115,7 @@ void Agent::RegisterAsyncHook(Isolate* isolate,
|
||||
}
|
||||
|
||||
void Agent::SetAsyncHookTrackingEnabled(bool enabled) {
|
||||
@@ -186,7 +186,7 @@ index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d4
|
||||
SyncAsyncHookState();
|
||||
}
|
||||
|
||||
@@ -1071,52 +1114,25 @@ void Agent::SetAsyncHookTrackingEnabled(bool enabled) {
|
||||
@@ -1086,52 +1129,25 @@ void Agent::SetAsyncHookTrackingEnabled(bool enabled) {
|
||||
// When it's not safe to call into JS, this is a no-op and we'll try again in
|
||||
// RegisterAsyncHook() (for 1) or from a scheduled immediate (for 2).
|
||||
void Agent::SyncAsyncHookState() {
|
||||
@@ -257,10 +257,10 @@ index 55fe49c1e3058c366ede37a7698aefae82ea3f75..7329990ebf6a0bcb64b18069b67a61d4
|
||||
|
||||
void Agent::AsyncTaskScheduled(const StringView& task_name, void* task,
|
||||
diff --git a/src/inspector_agent.h b/src/inspector_agent.h
|
||||
index 932e4e8dce899101a17d978dfc5065de5eb06758..6e1a622aa6d95be198165f521f82513c8552606e 100644
|
||||
index 5a1d1de26547bb437f4f86c2e1825d6eaf709e9d..bf76578e8c06a062b991937a2cca02b62d3f4c5a 100644
|
||||
--- a/src/inspector_agent.h
|
||||
+++ b/src/inspector_agent.h
|
||||
@@ -28,6 +28,12 @@ class ParentInspectorHandle;
|
||||
@@ -29,6 +29,12 @@ class ParentInspectorHandle;
|
||||
class NodeInspectorClient;
|
||||
class WorkerManager;
|
||||
|
||||
@@ -273,7 +273,7 @@ index 932e4e8dce899101a17d978dfc5065de5eb06758..6e1a622aa6d95be198165f521f82513c
|
||||
class InspectorSession {
|
||||
public:
|
||||
virtual ~InspectorSession() = default;
|
||||
@@ -132,7 +138,7 @@ class Agent {
|
||||
@@ -134,7 +140,7 @@ class Agent {
|
||||
|
||||
private:
|
||||
void SyncAsyncHookState();
|
||||
@@ -282,7 +282,7 @@ index 932e4e8dce899101a17d978dfc5065de5eb06758..6e1a622aa6d95be198165f521f82513c
|
||||
|
||||
node::Environment* parent_env_;
|
||||
// Encapsulates majority of the Inspector functionality
|
||||
@@ -152,13 +158,11 @@ class Agent {
|
||||
@@ -154,9 +160,7 @@ class Agent {
|
||||
// The state of the async hook used for async stack traces that the protocol
|
||||
// last requested, and the state JS currently has. SyncAsyncHookState()
|
||||
// reconciles the two when it is possible and safe to call into JS.
|
||||
@@ -291,6 +291,12 @@ index 932e4e8dce899101a17d978dfc5065de5eb06758..6e1a622aa6d95be198165f521f82513c
|
||||
- bool syncing_async_hook_state_ = false;
|
||||
+ JavaScriptHookState async_hook_state_;
|
||||
|
||||
// Woken by the SIGUSR1 watchdog; closed by the cleanup hook or ~Agent(),
|
||||
// whichever runs first, and freed by its close callback.
|
||||
@@ -164,9 +168,9 @@ class Agent {
|
||||
void StopAcceptingIoThreadStarts();
|
||||
static void StopAcceptingIoThreadStartsHook(void* agent);
|
||||
|
||||
- bool network_tracking_enabled_ = false;
|
||||
- bool pending_enable_network_tracking = false;
|
||||
- bool pending_disable_network_tracking = false;
|
||||
|
||||
@@ -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 4969c908c487a96fd6da80741d70d11b10dea131..4dea08fafee4379066a7d8af66fb07c7e7a3490c 100644
|
||||
index 4debed160e1abf8d3d4ecdd3d5e7d11f0a091cc1..312a857537867e408fe2bd1b1a0d1061c41ccf3b 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -320,6 +320,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
|
||||
@@ -349,6 +349,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params,
|
||||
MultiIsolatePlatform* platform,
|
||||
const SnapshotData* snapshot_data,
|
||||
const IsolateSettings& settings) {
|
||||
@@ -32,7 +32,7 @@ index 4969c908c487a96fd6da80741d70d11b10dea131..4dea08fafee4379066a7d8af66fb07c7
|
||||
IsolateGroup group = GetOrCreateIsolateGroup();
|
||||
Isolate* isolate = Isolate::Allocate(group);
|
||||
if (isolate == nullptr) return nullptr;
|
||||
@@ -370,9 +374,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator,
|
||||
@@ -382,9 +386,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator,
|
||||
uv_loop_t* event_loop,
|
||||
MultiIsolatePlatform* platform,
|
||||
const EmbedderSnapshotData* snapshot_data,
|
||||
@@ -47,10 +47,10 @@ index 4969c908c487a96fd6da80741d70d11b10dea131..4dea08fafee4379066a7d8af66fb07c7
|
||||
event_loop,
|
||||
platform,
|
||||
diff --git a/src/cppgc_helpers-inl.h b/src/cppgc_helpers-inl.h
|
||||
index 745ecab746f7c7540733d31a94f52809dcddd5be..0e52bf5a6f4837d0f4bfed83987c6903796fda55 100644
|
||||
index f81dfb9bf60d52b225479c3a7a00b93225a9d10f..745f2c0526fafc1079b94be875a9e5a519d3a794 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) {
|
||||
@@ -14,11 +14,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.
|
||||
@@ -63,10 +63,10 @@ index 745ecab746f7c7540733d31a94f52809dcddd5be..0e52bf5a6f4837d0f4bfed83987c6903
|
||||
- obj->SetAlignedPointerInInternalField(kSlot, ptr);
|
||||
+ kEmbedderType, realm->isolate_data()->embedder_id_for_cppgc(), 0);
|
||||
+ obj->SetAlignedPointerInInternalField(kSlot, ptr, 0);
|
||||
realm->TrackCppgcWrapper(ptr);
|
||||
ptr->list_node_ = realm->TrackCppgcWrapper(ptr);
|
||||
}
|
||||
|
||||
@@ -40,7 +41,7 @@ T* CppgcMixin::Unwrap(v8::Local<v8::Object> obj) {
|
||||
@@ -39,7 +40,7 @@ T* CppgcMixin::Unwrap(v8::Local<v8::Object> obj) {
|
||||
if (obj->InternalFieldCount() != T::kInternalFieldCount) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -75,29 +75,11 @@ index 745ecab746f7c7540733d31a94f52809dcddd5be..0e52bf5a6f4837d0f4bfed83987c6903
|
||||
return ptr;
|
||||
}
|
||||
|
||||
diff --git a/src/cppgc_helpers.cc b/src/cppgc_helpers.cc
|
||||
index 7c557a822d2028aa88adbdca63677a44afd1a120..ae7e45fbc26317a53207c267865ea4db553f5a8a 100644
|
||||
--- a/src/cppgc_helpers.cc
|
||||
+++ b/src/cppgc_helpers.cc
|
||||
@@ -4,11 +4,12 @@
|
||||
namespace node {
|
||||
|
||||
void CppgcWrapperList::Cleanup() {
|
||||
- for (auto node : *this) {
|
||||
+ while (CppgcWrapperListNode* node = PopFront()) {
|
||||
CppgcMixin* ptr = node->persistent.Get();
|
||||
if (ptr != nullptr) {
|
||||
ptr->Finalize();
|
||||
}
|
||||
+ delete node;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/cppgc_helpers.h b/src/cppgc_helpers.h
|
||||
index fb2af584a4ae777022c9ef8c20ada1edcbbbefdc..fe6300a5d5d2d6602a84cbd33736c2133041d1b0 100644
|
||||
index df6b4836c676d468a97371f804ffe53606e7d171..f1363d5da78f7a3603fb4502489ecf2ee3483fdb 100644
|
||||
--- a/src/cppgc_helpers.h
|
||||
+++ b/src/cppgc_helpers.h
|
||||
@@ -155,7 +155,7 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
|
||||
@@ -149,7 +149,7 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
|
||||
*/
|
||||
#define CPPGC_MIXIN(Klass) \
|
||||
public /* NOLINT(whitespace/indent) */ \
|
||||
@@ -107,10 +89,10 @@ index fb2af584a4ae777022c9ef8c20ada1edcbbbefdc..fe6300a5d5d2d6602a84cbd33736c213
|
||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index 84957de5cb0149e518c92ca0608f6e16faf5e5e6..c68bb8e4854a301b6899d2f7183b77dd9ff98c31 100644
|
||||
index 3495479752fb8957ea4d89ca76f2c2dcddecf100..7674b06f7018020f87c32316a66eebc04720ab5e 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -642,7 +642,7 @@ IsolateData::~IsolateData() {}
|
||||
@@ -643,7 +643,7 @@ IsolateData::~IsolateData() {}
|
||||
// Deprecated API, embedders should use v8::Object::Wrap() directly instead.
|
||||
void SetCppgcReference(Isolate* isolate,
|
||||
Local<Object> object,
|
||||
@@ -120,7 +102,7 @@ index 84957de5cb0149e518c92ca0608f6e16faf5e5e6..c68bb8e4854a301b6899d2f7183b77dd
|
||||
isolate, object, wrappable);
|
||||
}
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 3bd4849bb93340569c0067fedd37fefeebff4eb5..952d51946d9412c376dfe305a2c5fd564b60998c 100644
|
||||
index cba83119bfaf88b360b2f1220611a0c642ec7364..564ba432f023ea0575bba72e1a17816faf4d830c 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -78,6 +78,7 @@
|
||||
@@ -131,7 +113,7 @@ index 3bd4849bb93340569c0067fedd37fefeebff4eb5..952d51946d9412c376dfe305a2c5fd56
|
||||
|
||||
#include "v8-platform.h" // NOLINT(build/include_order)
|
||||
#include "node_version.h" // NODE_MODULE_VERSION
|
||||
@@ -597,7 +598,8 @@ NODE_EXTERN v8::Isolate* NewIsolate(
|
||||
@@ -599,7 +600,8 @@ NODE_EXTERN v8::Isolate* NewIsolate(
|
||||
struct uv_loop_s* event_loop,
|
||||
MultiIsolatePlatform* platform,
|
||||
const EmbedderSnapshotData* snapshot_data = nullptr,
|
||||
@@ -141,7 +123,7 @@ index 3bd4849bb93340569c0067fedd37fefeebff4eb5..952d51946d9412c376dfe305a2c5fd56
|
||||
NODE_EXTERN v8::Isolate* NewIsolate(
|
||||
std::shared_ptr<ArrayBufferAllocator> allocator,
|
||||
struct uv_loop_s* event_loop,
|
||||
@@ -1720,9 +1722,10 @@ void RegisterSignalHandler(int signal,
|
||||
@@ -1728,9 +1730,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()",
|
||||
@@ -156,7 +138,7 @@ index 3bd4849bb93340569c0067fedd37fefeebff4eb5..952d51946d9412c376dfe305a2c5fd56
|
||||
namespace crypto {
|
||||
|
||||
diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc
|
||||
index 6f674df3ed0dc1b4e5cd3a249fb787a9fc98361d..90f9eb84b6835c36a91ce23d77722812ce173c0f 100644
|
||||
index bc07d6aaf42678d935c28659c8b1d7adc6475194..6faf7569f7323fa1c85b19ba6e2f7583cd63b848 100644
|
||||
--- a/src/node_main_instance.cc
|
||||
+++ b/src/node_main_instance.cc
|
||||
@@ -44,6 +44,8 @@ NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
|
||||
@@ -169,7 +151,7 @@ index 6f674df3ed0dc1b4e5cd3a249fb787a9fc98361d..90f9eb84b6835c36a91ce23d77722812
|
||||
isolate_ =
|
||||
NewIsolate(isolate_params_.get(), event_loop, platform, snapshot_data);
|
||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
||||
index e743cb45359a2e1e3151f17dc80ada639a9db3e0..ed3aa30caac3f47691c4a7262e671589c3bace7b 100644
|
||||
index fd6a0d90afaa7195564b09b81a24cb155aca81ae..b45ee62d0e13d24c013102ca2b463a2517d92907 100644
|
||||
--- a/src/node_worker.cc
|
||||
+++ b/src/node_worker.cc
|
||||
@@ -182,6 +182,9 @@ class WorkerThreadData {
|
||||
|
||||
@@ -41,10 +41,10 @@ index f308232804352a72f81aa75dc42487b7a0697a47..077b8bff2c29cf35291e30b1bbfc8bdb
|
||||
bench.end(n);
|
||||
}
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index 7e67f7575c866c7628c980c77d131a4766caf58f..b1802a5fa1742f1896bcdfaca644245051cf7841 100644
|
||||
index 00b5cea77e949befd234a474a7f109ba47d24d8b..49771334b41b2c6488a64ca17bbd46f62ccab45a 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -90,7 +90,7 @@
|
||||
@@ -93,7 +93,7 @@
|
||||
'v8_enable_sandbox%': 0,
|
||||
'v8_enable_v8_checks%': 0,
|
||||
'v8_enable_zone_compression%': 0,
|
||||
@@ -54,10 +54,10 @@ index 7e67f7575c866c7628c980c77d131a4766caf58f..b1802a5fa1742f1896bcdfaca6442450
|
||||
|
||||
'using_electron_config_gypi%': 0,
|
||||
diff --git a/configure.py b/configure.py
|
||||
index 443818802df9bf62c17aa783617ec5b932cedf81..be0707fa1781201959fa0f4b3712021657dbfee8 100755
|
||||
index 172aef2c5194574eb298462588ecf76ae2a2e366..80d5362e0037664aa98c02ff5568682bf5d3143b 100755
|
||||
--- a/configure.py
|
||||
+++ b/configure.py
|
||||
@@ -1031,6 +1031,12 @@ parser.add_argument('--without-inspector',
|
||||
@@ -1004,6 +1004,12 @@ parser.add_argument('--without-inspector',
|
||||
default=None,
|
||||
help='disable the V8 inspector protocol')
|
||||
|
||||
@@ -70,7 +70,7 @@ index 443818802df9bf62c17aa783617ec5b932cedf81..be0707fa1781201959fa0f4b37120216
|
||||
parser.add_argument('--shared',
|
||||
action='store_true',
|
||||
dest='shared',
|
||||
@@ -1997,6 +2003,7 @@ def configure_v8(o, configs):
|
||||
@@ -1962,6 +1968,7 @@ def configure_v8(o, configs):
|
||||
o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
|
||||
o['variables']['v8_enable_extensible_ro_snapshot'] = 0
|
||||
o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0
|
||||
@@ -402,7 +402,7 @@ index 06a4f8a239855571dcc67cd81e7da7a255a9ebfd..1cb3ba4df520e782037d63bf1aeaef8b
|
||||
let debugLogCategoryEnabled = false;
|
||||
let timerFlags = kNone;
|
||||
diff --git a/node.gyp b/node.gyp
|
||||
index 5df80c48e7c747a49bd2e86ea7706de757fff32e..8aa3652277db2aef5e9ac5f0febdd08a44853fa0 100644
|
||||
index 14f14c79630f19bbf7d319b669614123ef94b148..e9a73b3b5cf580d559d1cac60082c1022fcdc3ac 100644
|
||||
--- a/node.gyp
|
||||
+++ b/node.gyp
|
||||
@@ -193,10 +193,9 @@
|
||||
@@ -432,7 +432,7 @@ index 5df80c48e7c747a49bd2e86ea7706de757fff32e..8aa3652277db2aef5e9ac5f0febdd08a
|
||||
'src/tracing/traced_value.h',
|
||||
'src/timer_wrap.h',
|
||||
'src/timer_wrap-inl.h',
|
||||
@@ -1387,6 +1384,14 @@
|
||||
@@ -1339,6 +1336,14 @@
|
||||
}, {
|
||||
'sources!': [ '<@(node_cctest_quic_sources)' ],
|
||||
}],
|
||||
@@ -447,7 +447,7 @@ index 5df80c48e7c747a49bd2e86ea7706de757fff32e..8aa3652277db2aef5e9ac5f0febdd08a
|
||||
['v8_enable_inspector==1', {
|
||||
'defines': [
|
||||
'HAVE_INSPECTOR=1',
|
||||
@@ -1709,6 +1714,14 @@
|
||||
@@ -1661,6 +1666,14 @@
|
||||
'NODE_USE_NODE_CODE_CACHE=1',
|
||||
],
|
||||
}],
|
||||
@@ -463,10 +463,10 @@ index 5df80c48e7c747a49bd2e86ea7706de757fff32e..8aa3652277db2aef5e9ac5f0febdd08a
|
||||
'defines': [
|
||||
'HAVE_INSPECTOR=1',
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index c81ef82c5a23d30ec7430b8726bd28e1be2f225e..75fc97a581b79c87a51adcbe999b937262b422db 100644
|
||||
index 4126d4b9f6caf6cbddba403189858c7f0ec60abb..885b9d9e6f9cc4497f27492f5eabcdbbe7f1e902 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -759,14 +759,6 @@ MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env) {
|
||||
@@ -777,14 +777,6 @@ MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env) {
|
||||
return env->platform();
|
||||
}
|
||||
|
||||
@@ -530,7 +530,7 @@ index a493f59465d207b4b89d8941807d4ff6acff82ac..88e8a2f401cac75810e3b0fdb776b41e
|
||||
+ ],
|
||||
}
|
||||
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
|
||||
index 7329990ebf6a0bcb64b18069b67a61d45b56c60b..37c86da997097240e381c79dbfd00b17937167af 100644
|
||||
index c22d6fc36b9cef4c15fe579bc3f9acf979528e8e..8ef5de4b47bf8d98a4fbbb8aa91ed639b3ae0e27 100644
|
||||
--- a/src/inspector_agent.cc
|
||||
+++ b/src/inspector_agent.cc
|
||||
@@ -14,7 +14,9 @@
|
||||
@@ -543,7 +543,7 @@ index 7329990ebf6a0bcb64b18069b67a61d45b56c60b..37c86da997097240e381c79dbfd00b17
|
||||
#include "inspector/worker_agent.h"
|
||||
#include "inspector/worker_inspector.h"
|
||||
#include "inspector_io.h"
|
||||
@@ -286,9 +288,11 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
@@ -293,9 +295,11 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
StringView(),
|
||||
V8Inspector::ClientTrustLevel::kFullyTrusted);
|
||||
node_dispatcher_ = std::make_unique<UberDispatcher>(this);
|
||||
@@ -555,7 +555,7 @@ index 7329990ebf6a0bcb64b18069b67a61d45b56c60b..37c86da997097240e381c79dbfd00b17
|
||||
if (worker_manager) {
|
||||
worker_agent_ = std::make_unique<protocol::WorkerAgent>(worker_manager);
|
||||
worker_agent_->Wire(node_dispatcher_.get());
|
||||
@@ -322,8 +326,10 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
@@ -329,8 +333,10 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
}
|
||||
|
||||
~ChannelImpl() override {
|
||||
@@ -566,7 +566,7 @@ index 7329990ebf6a0bcb64b18069b67a61d45b56c60b..37c86da997097240e381c79dbfd00b17
|
||||
if (worker_agent_) {
|
||||
worker_agent_->disable();
|
||||
worker_agent_.reset(); // Dispose before the dispatchers
|
||||
@@ -472,7 +478,9 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
@@ -479,7 +485,9 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
|
||||
}
|
||||
|
||||
std::unique_ptr<protocol::RuntimeAgent> runtime_agent_;
|
||||
@@ -691,7 +691,7 @@ index c9173d404c79a69743fc75ddb6bba0ac9579c1ef..952161d9e2cf1c92c3600fc2da0af594
|
||||
return env->ThrowUVException(err, "opendir");
|
||||
}
|
||||
diff --git a/src/node_file.cc b/src/node_file.cc
|
||||
index 15a433fc2c1fde03d1e875a88c238bc36fcc6c93..06bafaea64e7fbb2b5f32e92fd7dc79be875ac68 100644
|
||||
index fb5aaa3ab08923bf9c1c4e767bad2881510633e8..b6e2d325e338aedcab3e7fa2038e773930f56fcd 100644
|
||||
--- a/src/node_file.cc
|
||||
+++ b/src/node_file.cc
|
||||
@@ -153,10 +153,16 @@ static const char* get_fs_func_name_by_type(uv_fs_type req_type) {
|
||||
@@ -712,7 +712,7 @@ index 15a433fc2c1fde03d1e875a88c238bc36fcc6c93..06bafaea64e7fbb2b5f32e92fd7dc79b
|
||||
#define FS_ASYNC_TRACE_BEGIN0(fs_type, id) \
|
||||
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(TRACING_CATEGORY_NODE2(fs, async), \
|
||||
diff --git a/src/node_internals.h b/src/node_internals.h
|
||||
index 8e930a6fecd6589b858293d91b2454ea14ae7c73..24c5dbe405d69ceb0e515aeaa6b26233bb2943a9 100644
|
||||
index dc228f8e1e245d9f4fca8f2f948619304bfed5d5..39e8312ddd7167ee235927e1772f6d4dff98a5ad 100644
|
||||
--- a/src/node_internals.h
|
||||
+++ b/src/node_internals.h
|
||||
@@ -315,6 +315,7 @@ class ThreadPoolWork {
|
||||
@@ -732,7 +732,7 @@ index 8e930a6fecd6589b858293d91b2454ea14ae7c73..24c5dbe405d69ceb0e515aeaa6b26233
|
||||
// Functions defined in node.cc that are exposed via the bootstrapper object
|
||||
|
||||
diff --git a/src/node_options.h b/src/node_options.h
|
||||
index 4ffcdb8c1f9e1d866960c419569f3410f8e50934..04ca2785b9da5cd4083c6dee200cfaeb6e06bfc6 100644
|
||||
index 04eaa705e8023dab7104ac4d55f9d4179b7f30d4..575f4b23b58d9d2ea863d3209e3b9abaa6cfce7c 100644
|
||||
--- a/src/node_options.h
|
||||
+++ b/src/node_options.h
|
||||
@@ -333,7 +333,11 @@ class PerProcessOptions : public Options {
|
||||
@@ -748,7 +748,7 @@ index 4ffcdb8c1f9e1d866960c419569f3410f8e50934..04ca2785b9da5cd4083c6dee200cfaeb
|
||||
bool zero_fill_all_buffers = false;
|
||||
bool debug_arraybuffer_allocations = false;
|
||||
diff --git a/src/node_platform.cc b/src/node_platform.cc
|
||||
index c13d363cde2cf028ba3f364db489bb5d6bedf7a6..1f235cdd171ed4d00bdfd3ed25acbbfdfd172d2f 100644
|
||||
index 6893935e7cf7bc5cc92479f553a1e4827820b71d..bf2dac8f5d9e11f52603c562ff049cabc67eb91e 100644
|
||||
--- a/src/node_platform.cc
|
||||
+++ b/src/node_platform.cc
|
||||
@@ -477,7 +477,8 @@ NodePlatform::NodePlatform(int thread_pool_size,
|
||||
@@ -784,7 +784,7 @@ index f47e2a46b66b84938bcbf5b34ffc4a4a4a39af3f..665d2a467e08084837217482f65bb626
|
||||
v8::PageAllocator* page_allocator_;
|
||||
std::shared_ptr<WorkerThreadsTaskRunner> worker_thread_task_runner_;
|
||||
diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc
|
||||
index 49c457cae2b3da603a548874f63dbdf9f50580d9..412b5b67b35dfd192af04485e9c858f9862e9e0a 100644
|
||||
index f2d766b8b192dfbbd40af1f8ffaee624b747bb1d..c8f2a58734ee6d2ab440cd2439574cbd09d6fc00 100644
|
||||
--- a/src/node_trace_events.cc
|
||||
+++ b/src/node_trace_events.cc
|
||||
@@ -7,7 +7,7 @@
|
||||
@@ -811,7 +811,7 @@ index 49c457cae2b3da603a548874f63dbdf9f50580d9..412b5b67b35dfd192af04485e9c858f9
|
||||
// Starts the Tracing Agent if it wasn't started already (e.g. through
|
||||
// a command line flag.)
|
||||
auto* agent = tracing::Agent::GetInstance();
|
||||
@@ -205,6 +204,14 @@ void NodeCategorySet::Initialize(Local<Object> target,
|
||||
@@ -210,6 +209,14 @@ void NodeCategorySet::Initialize(Local<Object> target,
|
||||
.Check();
|
||||
target->Set(context, trace,
|
||||
binding->Get(context, trace).ToLocalChecked()).Check();
|
||||
@@ -1747,7 +1747,7 @@ index 0bc9df81d87562243817a6618641a49b602654e3..e04ffff48efbc55cc2221c22be7fd2e0
|
||||
|
||||
// Do not use this class directly. Define a custom structured class to provide
|
||||
diff --git a/test/common/index.js b/test/common/index.js
|
||||
index 9d15b57bf6b85bb006496069149f41110a2664b5..309c7301f2bbf842aad00c31f57c8a455e6b2228 100755
|
||||
index 0f2d695bbc5a6476d0e87bc79eb94485398e6e6b..15f3c1fa796f3ce11b62b8437469a5ae83c9c389 100755
|
||||
--- a/test/common/index.js
|
||||
+++ b/test/common/index.js
|
||||
@@ -58,6 +58,7 @@ const hasCrypto = Boolean(process.versions.openssl) &&
|
||||
@@ -1777,7 +1777,7 @@ index 9d15b57bf6b85bb006496069149f41110a2664b5..309c7301f2bbf842aad00c31f57c8a45
|
||||
function getArrayBufferViews(buf) {
|
||||
const { buffer, byteOffset, byteLength } = buf;
|
||||
|
||||
@@ -1006,6 +1019,8 @@ const common = {
|
||||
@@ -1007,6 +1020,8 @@ const common = {
|
||||
skipIfEslintMissing,
|
||||
skipIfInspectorDisabled,
|
||||
skipIfSQLiteMissing,
|
||||
@@ -2231,10 +2231,10 @@ index 844b3769ce201c615b2daaaaa85c8dd01a13c8f1..2e6c20255ce75f94c83e9238bc90a50b
|
||||
const CODE = 'const { Worker } = require(\'worker_threads\'); ' +
|
||||
`new Worker(${JSON.stringify(__filename)})`;
|
||||
diff --git a/tools/v8_gypfiles/features.gypi b/tools/v8_gypfiles/features.gypi
|
||||
index 53886830721c46b3ea1df7aaf7180ed19c3288eb..56f2ec123d22250ac1c7bcf368c4ea640114eb09 100644
|
||||
index 373448fccfb22ca2ec16df321a387fc710319cc4..d911d9f01b0c02e154358ccd812f324850655b56 100644
|
||||
--- a/tools/v8_gypfiles/features.gypi
|
||||
+++ b/tools/v8_gypfiles/features.gypi
|
||||
@@ -205,8 +205,7 @@
|
||||
@@ -208,8 +208,7 @@
|
||||
# Enable seeded array index hash.
|
||||
'v8_enable_seeded_array_index_hash%': 1,
|
||||
|
||||
@@ -2244,7 +2244,7 @@ index 53886830721c46b3ea1df7aaf7180ed19c3288eb..56f2ec123d22250ac1c7bcf368c4ea64
|
||||
'v8_use_perfetto%': 0,
|
||||
|
||||
# Enable map packing & unpacking (sets -dV8_MAP_PACKING).
|
||||
@@ -465,7 +464,10 @@
|
||||
@@ -484,7 +483,10 @@
|
||||
'defines': ['ENABLE_VERIFY_CSA',],
|
||||
}],
|
||||
['v8_use_perfetto==1', {
|
||||
@@ -2257,7 +2257,7 @@ index 53886830721c46b3ea1df7aaf7180ed19c3288eb..56f2ec123d22250ac1c7bcf368c4ea64
|
||||
['v8_enable_map_packing==1', {
|
||||
'defines': ['V8_MAP_PACKING',],
|
||||
diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp
|
||||
index f90a29d102ac0246a9261e223f0b5f69ec6d328b..71a7c40efa061afa954874ac97820be97e50463c 100644
|
||||
index 370001847ee8b43c0e83e516f65856c85eff3f41..60d630702b95d786d9634c0ffda40ba7f8374a1d 100644
|
||||
--- a/tools/v8_gypfiles/v8.gyp
|
||||
+++ b/tools/v8_gypfiles/v8.gyp
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
@@ -1,465 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 3 Sep 2026 04:13:45 +0000
|
||||
Subject: src: detach cppgc wrappers from their Realm before it is freed
|
||||
|
||||
`Realm::RunCleanup()` finalizes the cppgc-managed wrappers it tracks
|
||||
so that none of them touches the Realm once it is gone, but it reaches
|
||||
them through weak persistents, and the GC clears those as soon as it
|
||||
finds a wrapper dead. With lazy and concurrent sweeping the destructor
|
||||
can run much later, so a wrapper collected shortly before
|
||||
`FreeEnvironment()` and swept after it was skipped by the cleanup and
|
||||
kept its `realm_`: `~CppgcMixin()` then wrote
|
||||
`should_purge_empty_cppgc_wrappers_` into the freed Realm, and a
|
||||
subclass destructor calling `Finalize()` as documented would have
|
||||
called `Clean()` with a dangling Realm. A Worker that compiles a few
|
||||
`vm.Script`s, gets a full GC from external memory pressure and calls
|
||||
`process.exit()` is enough to hit the first case.
|
||||
|
||||
Move the Realm pointer into the list node, which the wrapper now owns
|
||||
and deletes in its destructor. `CppgcWrapperList::Cleanup()` unlinks
|
||||
every node, finalizing the wrappers that are still alive and clearing
|
||||
the Realm pointer for the collected ones, which only their own
|
||||
destructor may still touch. `Realm::PendingCleanup()` accounts for the
|
||||
list so it is always drained. The purge flag, its GC epilogue callback
|
||||
and `PurgeEmpty()` are no longer needed, and removing them also stops
|
||||
the list nodes of wrappers that are alive at `FreeEnvironment()` from
|
||||
leaking.
|
||||
|
||||
Refs: https://github.com/nodejs/node/pull/56534
|
||||
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
PR-URL: https://github.com/nodejs/node/pull/65778
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
|
||||
Cherry-picked from upstream commit c909c63be392b4c9ffdc2108e64371b9fa83e472;
|
||||
remove this patch once a Node.js release containing it is rolled in.
|
||||
|
||||
diff --git a/src/cppgc_helpers-inl.h b/src/cppgc_helpers-inl.h
|
||||
index 68c70153b96cc3e62db1b5dc74ac4026fa306271..f81b087ad21a28ec2385cd0cfae3177a470a2850 100644
|
||||
--- a/src/cppgc_helpers-inl.h
|
||||
+++ b/src/cppgc_helpers-inl.h
|
||||
@@ -11,7 +11,6 @@ namespace node {
|
||||
template <typename T>
|
||||
void CppgcMixin::Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj) {
|
||||
CHECK_GE(obj->InternalFieldCount(), T::kInternalFieldCount);
|
||||
- ptr->realm_ = realm;
|
||||
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.
|
||||
@@ -21,7 +20,7 @@ void CppgcMixin::Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj) {
|
||||
obj->SetAlignedPointerInInternalField(
|
||||
kEmbedderType, realm->isolate_data()->embedder_id_for_cppgc(), 0);
|
||||
obj->SetAlignedPointerInInternalField(kSlot, ptr, 0);
|
||||
- realm->TrackCppgcWrapper(ptr);
|
||||
+ ptr->list_node_ = realm->TrackCppgcWrapper(ptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -46,17 +45,26 @@ T* CppgcMixin::Unwrap(v8::Local<v8::Object> obj) {
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> CppgcMixin::object() const {
|
||||
- return traced_reference_.Get(realm_->isolate());
|
||||
+ return traced_reference_.Get(realm()->isolate());
|
||||
}
|
||||
|
||||
Environment* CppgcMixin::env() const {
|
||||
- return realm_->env();
|
||||
+ return realm()->env();
|
||||
+}
|
||||
+
|
||||
+Realm* CppgcMixin::realm() const {
|
||||
+ return list_node_ == nullptr ? nullptr : list_node_->realm;
|
||||
+}
|
||||
+
|
||||
+void CppgcMixin::Finalize() {
|
||||
+ Realm* current_realm = realm();
|
||||
+ if (current_realm == nullptr) return;
|
||||
+ this->Clean(current_realm);
|
||||
+ list_node_->realm = nullptr;
|
||||
}
|
||||
|
||||
CppgcMixin::~CppgcMixin() {
|
||||
- if (realm_ != nullptr) {
|
||||
- realm_->set_should_purge_empty_cppgc_wrappers(true);
|
||||
- }
|
||||
+ delete list_node_;
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
diff --git a/src/cppgc_helpers.cc b/src/cppgc_helpers.cc
|
||||
index ae7e45fbc26317a53207c267865ea4db553f5a8a..9424904c0ea82d14102a47a6f4915210ef39fc76 100644
|
||||
--- a/src/cppgc_helpers.cc
|
||||
+++ b/src/cppgc_helpers.cc
|
||||
@@ -1,15 +1,14 @@
|
||||
-#include "cppgc_helpers.h"
|
||||
-#include "env-inl.h"
|
||||
+#include "cppgc_helpers.h" // NOLINT(build/include_inline)
|
||||
+#include "cppgc_helpers-inl.h"
|
||||
|
||||
namespace node {
|
||||
|
||||
void CppgcWrapperList::Cleanup() {
|
||||
- while (CppgcWrapperListNode* node = PopFront()) {
|
||||
- CppgcMixin* ptr = node->persistent.Get();
|
||||
- if (ptr != nullptr) {
|
||||
- ptr->Finalize();
|
||||
- }
|
||||
- delete node;
|
||||
+ while (!IsEmpty()) {
|
||||
+ CppgcWrapperListNode* node = PopFront();
|
||||
+ CppgcMixin* wrapper = node->persistent.Get();
|
||||
+ if (wrapper != nullptr) wrapper->Finalize();
|
||||
+ node->realm = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,18 +23,4 @@ void CppgcWrapperList::MemoryInfo(MemoryTracker* tracker) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
-void CppgcWrapperList::PurgeEmpty() {
|
||||
- for (auto weak_it = begin(); weak_it != end();) {
|
||||
- CppgcWrapperListNode* node = *weak_it;
|
||||
- auto next_it = ++weak_it;
|
||||
- // The underlying cppgc wrapper has already been garbage collected.
|
||||
- // Remove it from the list.
|
||||
- if (!node->persistent) {
|
||||
- node->persistent.Clear();
|
||||
- delete node;
|
||||
- }
|
||||
- weak_it = next_it;
|
||||
- }
|
||||
-}
|
||||
} // namespace node
|
||||
diff --git a/src/cppgc_helpers.h b/src/cppgc_helpers.h
|
||||
index b9153306b6cbc34d076c0eb5b32ecce3c5de98de..7baf7b11a68c2cbb83bd67a152be74a8533ecdb0 100644
|
||||
--- a/src/cppgc_helpers.h
|
||||
+++ b/src/cppgc_helpers.h
|
||||
@@ -66,9 +66,9 @@ static_assert(
|
||||
* cleanup relies on a living Node.js `Realm`, it should implement a
|
||||
* pattern like this:
|
||||
*
|
||||
- * ~MyWrap() { this->Destroy(); }
|
||||
+ * ~MyWrap() { this->Finalize(); }
|
||||
* void Clean(Realm* env) override {
|
||||
- * // Do cleanup that relies on a living Environemnt.
|
||||
+ * // Do cleanup that relies on a living Realm.
|
||||
* }
|
||||
*/
|
||||
class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
|
||||
@@ -87,7 +87,7 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
|
||||
|
||||
inline v8::Local<v8::Object> object() const;
|
||||
inline Environment* env() const;
|
||||
- inline Realm* realm() const { return realm_; }
|
||||
+ inline Realm* realm() const;
|
||||
inline v8::Local<v8::Object> object(v8::Isolate* isolate) const {
|
||||
return traced_reference_.Get(isolate);
|
||||
}
|
||||
@@ -114,11 +114,7 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
|
||||
// destructor. Outside of Finalize(), subclasses should avoid calling
|
||||
// into JavaScript or perform any operation that can trigger garbage
|
||||
// collection during the destruction.
|
||||
- void Finalize() {
|
||||
- if (realm_ == nullptr) return;
|
||||
- this->Clean(realm_);
|
||||
- realm_ = nullptr;
|
||||
- }
|
||||
+ inline void Finalize();
|
||||
|
||||
// The default implementation of Clean() is a no-op. If subclasses wish
|
||||
// to perform cleanup that require a living Realm, they should
|
||||
@@ -129,10 +125,8 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {
|
||||
|
||||
inline ~CppgcMixin();
|
||||
|
||||
- friend class CppgcWrapperListNode;
|
||||
-
|
||||
private:
|
||||
- Realm* realm_ = nullptr;
|
||||
+ CppgcWrapperListNode* list_node_ = nullptr;
|
||||
v8::TracedReference<v8::Object> traced_reference_;
|
||||
};
|
||||
|
||||
diff --git a/src/node_realm-inl.h b/src/node_realm-inl.h
|
||||
index c01cef477aaba52f9894943acede7fb22ed17dcb..97756edfce15b2f3647646146683727b36c0eec3 100644
|
||||
--- a/src/node_realm-inl.h
|
||||
+++ b/src/node_realm-inl.h
|
||||
@@ -136,11 +136,13 @@ void Realm::TrackBaseObject(BaseObject* bo) {
|
||||
++base_object_count_;
|
||||
}
|
||||
|
||||
-CppgcWrapperListNode::CppgcWrapperListNode(CppgcMixin* ptr) : persistent(ptr) {}
|
||||
+CppgcWrapperListNode::CppgcWrapperListNode(Realm* realm, CppgcMixin* wrapper)
|
||||
+ : realm(realm), persistent(wrapper) {}
|
||||
|
||||
-void Realm::TrackCppgcWrapper(CppgcMixin* handle) {
|
||||
- DCHECK_EQ(handle->realm(), this);
|
||||
- cppgc_wrapper_list_.PushFront(new CppgcWrapperListNode(handle));
|
||||
+CppgcWrapperListNode* Realm::TrackCppgcWrapper(CppgcMixin* handle) {
|
||||
+ CppgcWrapperListNode* node = new CppgcWrapperListNode(this, handle);
|
||||
+ cppgc_wrapper_list_.PushFront(node);
|
||||
+ return node;
|
||||
}
|
||||
|
||||
void Realm::UntrackBaseObject(BaseObject* bo) {
|
||||
@@ -149,7 +151,7 @@ void Realm::UntrackBaseObject(BaseObject* bo) {
|
||||
}
|
||||
|
||||
bool Realm::PendingCleanup() const {
|
||||
- return !base_object_list_.IsEmpty();
|
||||
+ return !base_object_list_.IsEmpty() || !cppgc_wrapper_list_.IsEmpty();
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
diff --git a/src/node_realm.cc b/src/node_realm.cc
|
||||
index 47bd7d9f19077ac7a558c73db5f51bdf8da291e7..17c3dd754bda13413e7cac6fc2fb55f6a4866a66 100644
|
||||
--- a/src/node_realm.cc
|
||||
+++ b/src/node_realm.cc
|
||||
@@ -10,8 +10,6 @@ namespace node {
|
||||
|
||||
using v8::Context;
|
||||
using v8::EscapableHandleScope;
|
||||
-using v8::GCCallbackFlags;
|
||||
-using v8::GCType;
|
||||
using v8::HandleScope;
|
||||
using v8::Isolate;
|
||||
using v8::Local;
|
||||
@@ -25,26 +23,11 @@ Realm::Realm(Environment* env, v8::Local<v8::Context> context, Kind kind)
|
||||
: 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,
|
||||
- // though that may be a bit excessive depending on usage patterns.
|
||||
- // For now using the GC epilogue is adequate.
|
||||
- isolate_->AddGCEpilogueCallback(PurgeEmptyCppgcWrappers, this);
|
||||
}
|
||||
|
||||
Realm::~Realm() {
|
||||
- isolate_->RemoveGCEpilogueCallback(PurgeEmptyCppgcWrappers, this);
|
||||
CHECK_EQ(base_object_count_, 0);
|
||||
-}
|
||||
-
|
||||
-void Realm::PurgeEmptyCppgcWrappers(Isolate* isolate,
|
||||
- GCType type,
|
||||
- GCCallbackFlags flags,
|
||||
- void* data) {
|
||||
- Realm* realm = static_cast<Realm*>(data);
|
||||
- if (realm->should_purge_empty_cppgc_wrappers_) {
|
||||
- realm->cppgc_wrapper_list_.PurgeEmpty();
|
||||
- realm->should_purge_empty_cppgc_wrappers_ = false;
|
||||
- }
|
||||
+ CHECK(cppgc_wrapper_list_.IsEmpty());
|
||||
}
|
||||
|
||||
void Realm::MemoryInfo(MemoryTracker* tracker) const {
|
||||
diff --git a/src/node_realm.h b/src/node_realm.h
|
||||
index 2ed04aa271b4c49db5be56d7a0e1969a0182cde6..4cb20d151d4dc94370eac7a17b56f8da2e6e418a 100644
|
||||
--- a/src/node_realm.h
|
||||
+++ b/src/node_realm.h
|
||||
@@ -27,16 +27,16 @@ using BindingDataStore =
|
||||
static_cast<size_t>(BindingDataType::kBindingDataTypeCount)>;
|
||||
|
||||
/**
|
||||
- * This is a wrapper around a weak persistent of CppgcMixin, used in the
|
||||
- * CppgcWrapperList to avoid accessing already garbage collected CppgcMixins.
|
||||
+ * Owned by a CppgcMixin and linked into its Realm's list until the Realm
|
||||
+ * cleans up and clears `realm`. The Realm only calls into wrappers the GC
|
||||
+ * still considers alive (the weak persistent); a collected wrapper whose
|
||||
+ * destructor runs later sees `realm == nullptr` instead of a freed Realm.
|
||||
*/
|
||||
class CppgcWrapperListNode {
|
||||
public:
|
||||
- explicit inline CppgcWrapperListNode(CppgcMixin* ptr);
|
||||
- inline explicit operator bool() const { return !persistent; }
|
||||
- inline CppgcMixin* operator->() const { return persistent.Get(); }
|
||||
- inline CppgcMixin* operator*() const { return persistent.Get(); }
|
||||
+ inline CppgcWrapperListNode(Realm* realm, CppgcMixin* wrapper);
|
||||
|
||||
+ Realm* realm;
|
||||
cppgc::WeakPersistent<CppgcMixin> persistent;
|
||||
// Used by ContainerOf in the ListNode implementation for fast manipulation of
|
||||
// CppgcWrapperList.
|
||||
@@ -53,7 +53,6 @@ class CppgcWrapperList
|
||||
public MemoryRetainer {
|
||||
public:
|
||||
void Cleanup();
|
||||
- void PurgeEmpty();
|
||||
|
||||
SET_MEMORY_INFO_NAME(CppgcWrapperList)
|
||||
SET_SELF_SIZE(CppgcWrapperList)
|
||||
@@ -148,7 +147,7 @@ class Realm : public MemoryRetainer {
|
||||
// Base object count created after the bootstrap of the realm.
|
||||
inline int64_t base_object_created_after_bootstrap() const;
|
||||
|
||||
- inline void TrackCppgcWrapper(CppgcMixin* handle);
|
||||
+ inline CppgcWrapperListNode* TrackCppgcWrapper(CppgcMixin* handle);
|
||||
inline CppgcWrapperList* cppgc_wrapper_list() { return &cppgc_wrapper_list_; }
|
||||
|
||||
#define V(PropertyName, TypeName) \
|
||||
@@ -164,14 +163,6 @@ class Realm : public MemoryRetainer {
|
||||
// it's only used for tests.
|
||||
std::vector<std::string> builtins_in_snapshot;
|
||||
|
||||
- // This used during the destruction of cppgc wrappers to inform a GC epilogue
|
||||
- // callback to clean up the weak persistents used to track cppgc wrappers if
|
||||
- // the wrappers are already garbage collected to prevent holding on to
|
||||
- // excessive useless persistents.
|
||||
- inline void set_should_purge_empty_cppgc_wrappers(bool value) {
|
||||
- should_purge_empty_cppgc_wrappers_ = value;
|
||||
- }
|
||||
-
|
||||
protected:
|
||||
~Realm();
|
||||
|
||||
@@ -181,17 +172,11 @@ class Realm : public MemoryRetainer {
|
||||
// Shorthand for isolate pointer.
|
||||
v8::Isolate* isolate_;
|
||||
v8::Global<v8::Context> context_;
|
||||
- bool should_purge_empty_cppgc_wrappers_ = false;
|
||||
|
||||
#define V(PropertyName, TypeName) v8::Global<TypeName> PropertyName##_;
|
||||
PER_REALM_STRONG_PERSISTENT_VALUES(V)
|
||||
#undef V
|
||||
|
||||
- static void PurgeEmptyCppgcWrappers(v8::Isolate* isolate,
|
||||
- v8::GCType type,
|
||||
- v8::GCCallbackFlags flags,
|
||||
- void* data);
|
||||
-
|
||||
private:
|
||||
void InitializeContext(v8::Local<v8::Context> context,
|
||||
const RealmSerializeInfo* realm_info);
|
||||
diff --git a/test/cctest/test_cppgc.cc b/test/cctest/test_cppgc.cc
|
||||
index 21f981f9ab229ffeb99fa0e903ece7f973cc9b50..030f369ab45e823ae65c07d6e7ec414dfecf6f26 100644
|
||||
--- a/test/cctest/test_cppgc.cc
|
||||
+++ b/test/cctest/test_cppgc.cc
|
||||
@@ -3,8 +3,11 @@
|
||||
#include <cppgc/heap.h>
|
||||
#include <node.h>
|
||||
#include <v8-cppgc.h>
|
||||
+#include <v8-external-memory-accounter.h>
|
||||
#include <v8-sandbox.h>
|
||||
#include <v8.h>
|
||||
+#include "cppgc_helpers-inl.h"
|
||||
+#include "node_realm-inl.h"
|
||||
#include "node_test_fixture.h"
|
||||
|
||||
// This tests that Node.js can work with an existing CppHeap.
|
||||
@@ -106,3 +109,114 @@ TEST_F(NodeZeroIsolateTestFixture, ExistingCppHeapTest) {
|
||||
// heap can be reclaimed. So just check at least some of them are traced.
|
||||
EXPECT_GT(CppGCed::kTraceCount, 0);
|
||||
}
|
||||
+
|
||||
+class CppgcTest : public EnvironmentTestFixture {
|
||||
+ protected:
|
||||
+ // Above the external memory hard limit, so V8 runs a full GC synchronously
|
||||
+ // and leaves sweeping (and cppgc destructors) for later.
|
||||
+ static constexpr size_t kExternalMemoryPressure = size_t{8} << 30;
|
||||
+
|
||||
+ void CollectGarbageLeavingSweepingPending() {
|
||||
+ v8::ExternalMemoryAccounter pressure;
|
||||
+ pressure.Increase(isolate_, kExternalMemoryPressure);
|
||||
+ pressure.Decrease(isolate_, kExternalMemoryPressure);
|
||||
+ }
|
||||
+
|
||||
+ void FinishSweeping() {
|
||||
+ isolate_->LowMemoryNotification();
|
||||
+ platform->DrainTasks(isolate_);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+using node::CppgcMixin;
|
||||
+
|
||||
+class RealmBoundWrap final : CPPGC_MIXIN(RealmBoundWrap) {
|
||||
+ public:
|
||||
+ SET_CPPGC_NAME(RealmBoundWrap)
|
||||
+ DEFAULT_CPPGC_TRACE()
|
||||
+ SET_NO_MEMORY_INFO()
|
||||
+
|
||||
+ static node::Realm* live_realm;
|
||||
+ static int clean_count;
|
||||
+ static int clean_with_dead_realm_count;
|
||||
+ static int destructor_count;
|
||||
+
|
||||
+ RealmBoundWrap(node::Environment* env, v8::Local<v8::Object> object) {
|
||||
+ CppgcMixin::Wrap(this, env, object);
|
||||
+ }
|
||||
+ ~RealmBoundWrap() {
|
||||
+ Finalize();
|
||||
+ destructor_count++;
|
||||
+ }
|
||||
+ void Clean(node::Realm* realm) override {
|
||||
+ clean_count++;
|
||||
+ if (realm != live_realm) clean_with_dead_realm_count++;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+node::Realm* RealmBoundWrap::live_realm = nullptr;
|
||||
+int RealmBoundWrap::clean_count = 0;
|
||||
+int RealmBoundWrap::clean_with_dead_realm_count = 0;
|
||||
+int RealmBoundWrap::destructor_count = 0;
|
||||
+
|
||||
+TEST_F(CppgcTest, CleanIsNotCalledWithFreedRealm) {
|
||||
+ constexpr int kCount = 32;
|
||||
+ {
|
||||
+ const v8::HandleScope handle_scope(isolate_);
|
||||
+ Env env{handle_scope, Argv()};
|
||||
+ RealmBoundWrap::live_realm = (*env)->principal_realm();
|
||||
+
|
||||
+ v8::Local<v8::FunctionTemplate> ctor = v8::FunctionTemplate::New(isolate_);
|
||||
+ ctor->InstanceTemplate()->SetInternalFieldCount(
|
||||
+ node::CppgcMixin::kInternalFieldCount);
|
||||
+ v8::Local<v8::Function> fn =
|
||||
+ ctor->GetFunction(env.context()).ToLocalChecked();
|
||||
+ {
|
||||
+ v8::HandleScope inner_scope(isolate_);
|
||||
+ for (int i = 0; i <= kCount; i++) {
|
||||
+ v8::Local<v8::Object> obj =
|
||||
+ fn->NewInstance(env.context()).ToLocalChecked();
|
||||
+ cppgc::MakeGarbageCollected<RealmBoundWrap>(
|
||||
+ (*env)->cppgc_allocation_handle(), *env, obj);
|
||||
+ if (i < kCount) continue;
|
||||
+ env.context()
|
||||
+ ->Global()
|
||||
+ ->Set(env.context(),
|
||||
+ v8::String::NewFromUtf8Literal(isolate_, "kept"),
|
||||
+ obj)
|
||||
+ .Check();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ CollectGarbageLeavingSweepingPending();
|
||||
+ EXPECT_LT(RealmBoundWrap::destructor_count, kCount);
|
||||
+ }
|
||||
+ RealmBoundWrap::live_realm = nullptr;
|
||||
+ FinishSweeping();
|
||||
+
|
||||
+ EXPECT_GE(RealmBoundWrap::clean_count, 1);
|
||||
+ EXPECT_EQ(RealmBoundWrap::clean_with_dead_realm_count, 0);
|
||||
+}
|
||||
+
|
||||
+TEST_F(CppgcTest, WrappersAliveAtFreeEnvironmentDoNotLeak) {
|
||||
+ const v8::HandleScope handle_scope(isolate_);
|
||||
+ Env env{handle_scope, Argv()};
|
||||
+ node::LoadEnvironment(*env,
|
||||
+ "globalThis.script = new (require('vm').Script)('1');"
|
||||
+ "globalThis.context = require('vm').createContext();")
|
||||
+ .ToLocalChecked();
|
||||
+}
|
||||
+
|
||||
+TEST_F(CppgcTest, VmScriptCollectedBeforeFreeEnvironmentSweptAfter) {
|
||||
+ {
|
||||
+ const v8::HandleScope handle_scope(isolate_);
|
||||
+ Env env{handle_scope, Argv()};
|
||||
+ node::LoadEnvironment(*env,
|
||||
+ "const { Script } = require('vm');"
|
||||
+ "for (let i = 0; i < 64; i++) new Script('1');"
|
||||
+ "undefined;")
|
||||
+ .ToLocalChecked();
|
||||
+ CollectGarbageLeavingSweepingPending();
|
||||
+ }
|
||||
+ FinishSweeping();
|
||||
+}
|
||||
@@ -1,112 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Everett <everett.caleb@gmail.com>
|
||||
Date: Mon, 10 Aug 2026 10:58:05 -0400
|
||||
Subject: src: fix use-after-free in CleanupHookThunkRun
|
||||
|
||||
CleanupHookThunkRun() read thunk->isolate/fun/arg from the
|
||||
CleanupHookThunk after invoking thunk->fun(). For every
|
||||
node::ObjectWrap alive at teardown, thunk->fun is
|
||||
ObjectWrap::CleanupHook, which deletes the wrap; ~ObjectWrap() calls
|
||||
RemoveEnvironmentCleanupHook() itself, erasing the CleanupHookThunk
|
||||
from the registry and freeing the node it lives in. The subsequent
|
||||
read of thunk->isolate/fun/arg to make the (now redundant) second
|
||||
RemoveEnvironmentCleanupHook() call was therefore a use-after-free.
|
||||
|
||||
Cache the fields before running the hook so nothing is read from
|
||||
`thunk` once it may have been freed, and add a cctest that registers a
|
||||
cleanup hook which removes itself while the queue is drained.
|
||||
|
||||
Backport of nodejs/node#65630. This patch can be removed when Electron
|
||||
updates to a Node.js release that contains it.
|
||||
|
||||
Co-authored-by: Sreehari Annam <sreehari.annam@gmail.com>
|
||||
Co-authored-by: nsavoire <19255994+nsavoire@users.noreply.github.com>
|
||||
Signed-off-by: Caleb Everett <everett.caleb@gmail.com>
|
||||
|
||||
diff --git a/src/api/hooks.cc b/src/api/hooks.cc
|
||||
index 07efb145a29eecc3e701f4c7b62ca96ea4555050..3213a30a7bc734a6626d0f93d4ce2ac7ddc747f6 100644
|
||||
--- a/src/api/hooks.cc
|
||||
+++ b/src/api/hooks.cc
|
||||
@@ -157,8 +157,15 @@ static ExclusiveAccess<CleanupHookRegistry> cleanup_hook_registry;
|
||||
|
||||
static void CleanupHookThunkRun(void* arg) {
|
||||
const CleanupHookThunk* thunk = static_cast<CleanupHookThunk*>(arg);
|
||||
- thunk->fun(thunk->arg);
|
||||
- RemoveEnvironmentCleanupHook(thunk->isolate, thunk->fun, thunk->arg);
|
||||
+ // `thunk->fun` may itself remove and free this CleanupHookThunk (e.g. via
|
||||
+ // ~ObjectWrap(), which calls RemoveEnvironmentCleanupHook()), so cache the
|
||||
+ // fields we still need before invoking it rather than reading them from
|
||||
+ // `thunk` afterwards.
|
||||
+ Isolate* isolate = thunk->isolate;
|
||||
+ CleanupHook fun = thunk->fun;
|
||||
+ void* fun_arg = thunk->arg;
|
||||
+ fun(fun_arg);
|
||||
+ RemoveEnvironmentCleanupHook(isolate, fun, fun_arg);
|
||||
}
|
||||
|
||||
void AddEnvironmentCleanupHook(Isolate* isolate,
|
||||
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
|
||||
index 3e846a672900807ba8df19e626837ce18be503c4..27c1556db02fac99b5f9b23427933c7a243d02c4 100644
|
||||
--- a/test/cctest/test_environment.cc
|
||||
+++ b/test/cctest/test_environment.cc
|
||||
@@ -27,6 +27,12 @@ static void at_exit_callback_ordered2(void* arg);
|
||||
static void at_exit_js(void* arg);
|
||||
static std::string cb_1_arg; // NOLINT(runtime/string)
|
||||
|
||||
+struct SelfRemovingCleanupHookState {
|
||||
+ v8::Isolate* isolate;
|
||||
+ bool ran = false;
|
||||
+};
|
||||
+static void self_removing_cleanup_hook(void* arg);
|
||||
+
|
||||
class EnvironmentTest : public EnvironmentTestFixture {
|
||||
private:
|
||||
void TearDown() override {
|
||||
@@ -309,6 +315,27 @@ TEST_F(EnvironmentTest, AtExitRunsJS) {
|
||||
EXPECT_TRUE(called_at_exit_js);
|
||||
}
|
||||
|
||||
+// A cleanup hook that removes itself while the environment cleanup queue is
|
||||
+// being drained must not cause a use-after-free. This registers such a hook
|
||||
+// directly rather than through node::ObjectWrap, whose destructor removes
|
||||
+// its own hook and is what makes this reachable for addons since #63642.
|
||||
+// The use-after-free is silent in ordinary builds; it is caught by the
|
||||
+// ASan/Valgrind CI, which is also how the original assertion (#63923)
|
||||
+// surfaced. Regression test for https://github.com/nodejs/node/issues/65195.
|
||||
+TEST_F(EnvironmentTest, RemoveEnvironmentCleanupHookDuringCleanup) {
|
||||
+ const v8::HandleScope handle_scope(isolate_);
|
||||
+ const Argv argv;
|
||||
+ SelfRemovingCleanupHookState state{isolate_};
|
||||
+ {
|
||||
+ Env env{handle_scope, argv};
|
||||
+ node::AddEnvironmentCleanupHook(
|
||||
+ isolate_, self_removing_cleanup_hook, &state);
|
||||
+ // Destroying `env` runs FreeEnvironment() -> RunCleanup(), which drains
|
||||
+ // the cleanup queue and invokes CleanupHookThunkRun() for the hook above.
|
||||
+ }
|
||||
+ EXPECT_TRUE(state.ran);
|
||||
+}
|
||||
+
|
||||
TEST_F(EnvironmentTest, MultipleEnvironmentsPerIsolate) {
|
||||
const v8::HandleScope handle_scope(isolate_);
|
||||
const Argv argv;
|
||||
@@ -392,6 +419,19 @@ static void at_exit_js(void* arg) {
|
||||
called_at_exit_js = true;
|
||||
}
|
||||
|
||||
+// Reproduces the sequence node::ObjectWrap performs since
|
||||
+// https://github.com/nodejs/node/pull/63642, without using ObjectWrap
|
||||
+// itself: the hook removes its own environment cleanup hook. When that runs
|
||||
+// while the cleanup queue is being drained, CleanupHookThunkRun() must not
|
||||
+// read the CleanupHookThunk after invoking the hook -- the hook has already
|
||||
+// erased and freed it. See https://github.com/nodejs/node/issues/65195.
|
||||
+static void self_removing_cleanup_hook(void* arg) {
|
||||
+ auto* state = static_cast<SelfRemovingCleanupHookState*>(arg);
|
||||
+ state->ran = true;
|
||||
+ node::RemoveEnvironmentCleanupHook(
|
||||
+ state->isolate, self_removing_cleanup_hook, state);
|
||||
+}
|
||||
+
|
||||
TEST_F(EnvironmentTest, SetImmediateCleanup) {
|
||||
int called = 0;
|
||||
int called_unref = 0;
|
||||
@@ -1,167 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anna Henningsen <anna@addaleax.net>
|
||||
Date: Thu, 18 Jun 2026 17:38:03 +0200
|
||||
Subject: src: keep global list of addon-provided cleanup hooks
|
||||
|
||||
A recent change, 215027c8eded2e, introduced flakiness into our
|
||||
test suite that exposed an issue with the cleanup hook API design.
|
||||
|
||||
Specifically, the signatures of `AddEnvironmentCleanupHook()` and
|
||||
`RemoveEnvironmentCleanupHook()` are problematic. Both functions
|
||||
take `Isolate*` arguments, as addons are not generally expected
|
||||
to have to care about the Node.js `Environment` as a first-class
|
||||
scope provider.
|
||||
|
||||
However, this model made the incorrect assumption that in the
|
||||
situations in which `RemoveEnvironmentCleanupHook()` would be
|
||||
invoked an `Environment` would always be associated with the
|
||||
current `Isolate` (via the current V8 `Context`, if there is one).
|
||||
|
||||
This occasionally breaks down when `RemoveEnvironmentCleanupHook()`
|
||||
is called during garbage collection -- which would be an expected
|
||||
use case of the functionality, but one that has not been covered
|
||||
through our tests before 215027c8eded2e.
|
||||
|
||||
Since Node.js guarantees API and ABI stability within a major version,
|
||||
and this is a bug that is independent from the aforementioned change,
|
||||
this commit resolves it by adding global mutable state to keep track
|
||||
off cleanup hooks registered through the Node.js public API.
|
||||
|
||||
Obviously, this solution does not represent a desirable long-term
|
||||
state, and a semver-minor follow up should add an API that does not
|
||||
require modifications to these data structures, likely based on
|
||||
the async cleanup hook API which already solves this issue properly.
|
||||
|
||||
Refs: https://github.com/nodejs/node/pull/63642
|
||||
Fixes: https://github.com/nodejs/node/issues/63923
|
||||
Signed-off-by: Anna Henningsen <anna@addaleax.net>
|
||||
PR-URL: https://github.com/nodejs/node/pull/63985
|
||||
Reviewed-By: James M Snell <jasnell@gmail.com>
|
||||
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
Backport of https://github.com/nodejs/node/pull/63985 for
|
||||
https://github.com/electron/electron/issues/53387: Node.js 24.19.0 made
|
||||
node::ObjectWrap register an environment cleanup hook, and removing it
|
||||
from ~ObjectWrap() during GC (no current context) hit CHECK_NOT_NULL(env)
|
||||
and aborted native addons. Conflict in test/addons/worker-addon/binding.cc
|
||||
resolved by deriving `isolate` from the module context, since v24.x does
|
||||
not carry the upstream refactor that introduced that local.
|
||||
|
||||
(cherry picked from commit 68321eff80918e324e9fdaf1aa8cee6db14b84f7)
|
||||
|
||||
diff --git a/src/api/hooks.cc b/src/api/hooks.cc
|
||||
index 86132d5eec29ce1fea946e233a96c2ba9cc64471..07efb145a29eecc3e701f4c7b62ca96ea4555050 100644
|
||||
--- a/src/api/hooks.cc
|
||||
+++ b/src/api/hooks.cc
|
||||
@@ -127,20 +127,71 @@ struct ACHHandle final {
|
||||
// this.
|
||||
void DeleteACHHandle::operator ()(ACHHandle* handle) const { delete handle; }
|
||||
|
||||
+// TODO(addaleax): Having this extra set of data structures is far from
|
||||
+// ideal, but unfortunately the public synchronous cleanup hook API was
|
||||
+// slightly mis-designed; in particular, RemoveEnvironmentCleanupHook() needs
|
||||
+// to keep working when the Isolate either has no active context (such as
|
||||
+// during GC) or that context is associated with another Node.js Environment.
|
||||
+// We should align this with the asynchronous API, which handles this properly
|
||||
+// through an explicit reference to the cleanup hook instead of requiring
|
||||
+// lookups in internal maps.
|
||||
+struct CleanupHookThunk final {
|
||||
+ Isolate* isolate;
|
||||
+ Environment* env;
|
||||
+ CleanupHook fun;
|
||||
+ void* arg;
|
||||
+
|
||||
+ bool operator==(const CleanupHookThunk& other) const {
|
||||
+ // `env` is intentionally not part of this comparison
|
||||
+ return isolate == other.isolate && fun == other.fun && arg == other.arg;
|
||||
+ }
|
||||
+};
|
||||
+struct CleanupHookThunkHash {
|
||||
+ size_t operator()(const CleanupHookThunk& thunk) const {
|
||||
+ return std::hash<void*>()(thunk.arg);
|
||||
+ }
|
||||
+};
|
||||
+using CleanupHookRegistry =
|
||||
+ std::unordered_set<CleanupHookThunk, CleanupHookThunkHash>;
|
||||
+static ExclusiveAccess<CleanupHookRegistry> cleanup_hook_registry;
|
||||
+
|
||||
+static void CleanupHookThunkRun(void* arg) {
|
||||
+ const CleanupHookThunk* thunk = static_cast<CleanupHookThunk*>(arg);
|
||||
+ thunk->fun(thunk->arg);
|
||||
+ RemoveEnvironmentCleanupHook(thunk->isolate, thunk->fun, thunk->arg);
|
||||
+}
|
||||
+
|
||||
void AddEnvironmentCleanupHook(Isolate* isolate,
|
||||
CleanupHook fun,
|
||||
void* arg) {
|
||||
Environment* env = Environment::GetCurrent(isolate);
|
||||
CHECK_NOT_NULL(env);
|
||||
- env->AddCleanupHook(fun, arg);
|
||||
+ void* wrapped_arg;
|
||||
+ {
|
||||
+ ExclusiveAccess<CleanupHookRegistry>::Scoped registry(
|
||||
+ &cleanup_hook_registry);
|
||||
+ auto result = registry->insert({isolate, env, fun, arg});
|
||||
+ CHECK(result.second);
|
||||
+ wrapped_arg = const_cast<CleanupHookThunk*>(&*result.first);
|
||||
+ }
|
||||
+ env->AddCleanupHook(CleanupHookThunkRun, wrapped_arg);
|
||||
}
|
||||
|
||||
void RemoveEnvironmentCleanupHook(Isolate* isolate,
|
||||
CleanupHook fun,
|
||||
void* arg) {
|
||||
- Environment* env = Environment::GetCurrent(isolate);
|
||||
- CHECK_NOT_NULL(env);
|
||||
- env->RemoveCleanupHook(fun, arg);
|
||||
+ CleanupHookThunk thunk;
|
||||
+ void* wrapped_arg;
|
||||
+ {
|
||||
+ ExclusiveAccess<CleanupHookRegistry>::Scoped registry(
|
||||
+ &cleanup_hook_registry);
|
||||
+ auto result = registry->find({isolate, nullptr, fun, arg});
|
||||
+ if (result == registry->end()) return;
|
||||
+ wrapped_arg = const_cast<CleanupHookThunk*>(&*result);
|
||||
+ thunk = *result;
|
||||
+ registry->erase(result);
|
||||
+ }
|
||||
+ thunk.env->RemoveCleanupHook(CleanupHookThunkRun, wrapped_arg);
|
||||
}
|
||||
|
||||
static void FinishAsyncCleanupHook(void* arg) {
|
||||
diff --git a/test/addons/worker-addon/binding.cc b/test/addons/worker-addon/binding.cc
|
||||
index a5f9d8b3f835d8926d55d06b57a523617afc6e65..183cad371c3286d872f681015585cc80d57fd0b5 100644
|
||||
--- a/test/addons/worker-addon/binding.cc
|
||||
+++ b/test/addons/worker-addon/binding.cc
|
||||
@@ -51,12 +51,26 @@ void Cleanup(void* str) {
|
||||
void Initialize(Local<Object> exports,
|
||||
Local<Value> module,
|
||||
Local<Context> context) {
|
||||
+ Isolate* isolate = context->GetIsolate();
|
||||
node::AddEnvironmentCleanupHook(
|
||||
- context->GetIsolate(),
|
||||
- Cleanup,
|
||||
- const_cast<void*>(static_cast<const void*>("cleanup")));
|
||||
- node::AddEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr);
|
||||
- node::RemoveEnvironmentCleanupHook(context->GetIsolate(), Dummy, nullptr);
|
||||
+ isolate, Cleanup, const_cast<void*>(static_cast<const void*>("cleanup")));
|
||||
+
|
||||
+ // Test that adding and removing a cleanup hook works as expected
|
||||
+ {
|
||||
+ node::AddEnvironmentCleanupHook(isolate, Dummy, nullptr);
|
||||
+ node::RemoveEnvironmentCleanupHook(isolate, Dummy, nullptr);
|
||||
+ }
|
||||
+
|
||||
+ // Test that adding and removing a cleanup hook also works if there
|
||||
+ // is no active context during removal
|
||||
+ {
|
||||
+ node::AddEnvironmentCleanupHook(isolate, Dummy, nullptr);
|
||||
+ {
|
||||
+ context->Exit();
|
||||
+ node::RemoveEnvironmentCleanupHook(isolate, Dummy, nullptr);
|
||||
+ context->Enter();
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (getenv("addExtraItemToEventLoop") != nullptr) {
|
||||
// Add an item to the event loop that we do not clean up in order to make
|
||||
@@ -172,10 +172,10 @@ index 5f5af63486a556f00b1cc3d44ec731f414904626..3132a96abb87f9275080ca0d8b2015b1
|
||||
int32_t port = value->Int32Value(env->context()).FromMaybe(0);
|
||||
|
||||
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
|
||||
index a44d310411b1de86f72f2d817c046fc11b558f71..fc7d4a826b4e34f684e8371f112a79cafa6e9abd 100644
|
||||
index 0b32b2a8be3650da0d46f72ee344363fb341b81d..ebdc0e049dd95c388a8e9465c0132d03afcf746a 100644
|
||||
--- a/src/node_sqlite.cc
|
||||
+++ b/src/node_sqlite.cc
|
||||
@@ -791,7 +791,7 @@ Intercepted DatabaseSyncLimits::LimitsGetter(
|
||||
@@ -853,7 +853,7 @@ Intercepted DatabaseSyncLimits::LimitsGetter(
|
||||
Intercepted DatabaseSyncLimits::LimitsSetter(
|
||||
Local<Name> property,
|
||||
Local<Value> value,
|
||||
@@ -185,10 +185,10 @@ index a44d310411b1de86f72f2d817c046fc11b558f71..fc7d4a826b4e34f684e8371f112a79ca
|
||||
return Intercepted::kNo;
|
||||
}
|
||||
diff --git a/src/node_sqlite.h b/src/node_sqlite.h
|
||||
index 9c7a4380dcf55762a1a21f971075c0a5aaae85ee..d77c7fc6362343db0c0cda60b9036fe69cbc78b3 100644
|
||||
index 442f291b05d65168b4fe6383adca703cb40f510d..998ac3b098752e70f00ce38ac014306346750586 100644
|
||||
--- a/src/node_sqlite.h
|
||||
+++ b/src/node_sqlite.h
|
||||
@@ -441,7 +441,7 @@ class DatabaseSyncLimits : public BaseObject {
|
||||
@@ -565,7 +565,7 @@ class DatabaseSyncLimits : public BaseObject {
|
||||
static v8::Intercepted LimitsSetter(
|
||||
v8::Local<v8::Name> property,
|
||||
v8::Local<v8::Value> value,
|
||||
|
||||
@@ -11,10 +11,10 @@ which now have the V2 semantics. Rename the call sites accordingly.
|
||||
https://chromium-review.googlesource.com/c/v8/v8/+/7955758
|
||||
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index 90d40720a4faad865cf6584bee73e5739d534f36..c81ef82c5a23d30ec7430b8726bd28e1be2f225e 100644
|
||||
index 6313d5ce1839fafb175c0e0c74eb39445baed467..4126d4b9f6caf6cbddba403189858c7f0ec60abb 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -971,7 +971,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||
@@ -989,7 +989,7 @@ MaybeLocal<Object> InitializePrivateSymbols(Local<Context> context,
|
||||
|
||||
Local<Object> private_symbols_object;
|
||||
if (!private_symbols->NewInstance(context).ToLocal(&private_symbols_object) ||
|
||||
@@ -23,7 +23,7 @@ index 90d40720a4faad865cf6584bee73e5739d534f36..c81ef82c5a23d30ec7430b8726bd28e1
|
||||
.IsNothing()) {
|
||||
return MaybeLocal<Object>();
|
||||
}
|
||||
@@ -997,7 +997,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||
@@ -1015,7 +1015,7 @@ MaybeLocal<Object> InitializePerIsolateSymbols(Local<Context> context,
|
||||
Local<Object> per_isolate_symbols_object;
|
||||
if (!per_isolate_symbols->NewInstance(context).ToLocal(
|
||||
&per_isolate_symbols_object) ||
|
||||
@@ -48,7 +48,7 @@ index 6a3c4e6952a8f3250bf1b57652a1622e9f63ec52..487b8b7adfd35646d20fdb15be5fd6f2
|
||||
}
|
||||
return false;
|
||||
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
||||
index 6c87611f7cbaf8a0b4c04f812f65381ede112056..da2ed4bae5a552117ad808c19a2e57f884b037ae 100644
|
||||
index 29e2e1808a3f42a35d9478f2f8949037b0011880..33ac5632781134d76f11143b24db1bc2db5b581a 100644
|
||||
--- a/src/js_native_api_v8.cc
|
||||
+++ b/src/js_native_api_v8.cc
|
||||
@@ -1579,7 +1579,7 @@ napi_status NAPI_CDECL node_api_set_prototype(napi_env env,
|
||||
@@ -135,10 +135,10 @@ index 51c097e69388a516aa7a9239053367faa4f7595e..d2337033fc1bf538f84c619add57bcc7
|
||||
THROW_ERR_INVALID_INVOCATION(isolate);
|
||||
return;
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index 5cbb2e7c593f08a18e670a49c1025a25c2511e7c..d4dffb1093f7a792b0e9cef2756b530cbc78ce88 100644
|
||||
index 9ccad939f1aefe38bcd7fa1f906c0e40dfc0adfd..d78133e65c275219a38976d4cde4e81901d906e3 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -1820,7 +1820,7 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -1847,7 +1847,7 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
Local<Map> options = Map::New(isolate);
|
||||
if (options
|
||||
@@ -147,7 +147,7 @@ index 5cbb2e7c593f08a18e670a49c1025a25c2511e7c..d4dffb1093f7a792b0e9cef2756b530c
|
||||
env->primordials_safe_map_prototype_object())
|
||||
.IsNothing()) {
|
||||
return;
|
||||
@@ -1861,7 +1861,7 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -1888,7 +1888,7 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
if (!ToV8Value(context, _ppop_instance.aliases_).ToLocal(&aliases)) return;
|
||||
|
||||
if (aliases.As<Object>()
|
||||
@@ -157,10 +157,10 @@ index 5cbb2e7c593f08a18e670a49c1025a25c2511e7c..d4dffb1093f7a792b0e9cef2756b530c
|
||||
.IsNothing()) {
|
||||
return;
|
||||
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
|
||||
index a04c7b97e743d75a53e8e01f31e40f601a207572..a44d310411b1de86f72f2d817c046fc11b558f71 100644
|
||||
index d1ef4d06f73bcb23686d91df2a0a3d5141e1ba70..0b32b2a8be3650da0d46f72ee344363fb341b81d 100644
|
||||
--- a/src/node_sqlite.cc
|
||||
+++ b/src/node_sqlite.cc
|
||||
@@ -765,7 +765,7 @@ Intercepted DatabaseSyncLimits::LimitsGetter(
|
||||
@@ -827,7 +827,7 @@ Intercepted DatabaseSyncLimits::LimitsGetter(
|
||||
}
|
||||
|
||||
DatabaseSyncLimits* limits;
|
||||
@@ -169,7 +169,7 @@ index a04c7b97e743d75a53e8e01f31e40f601a207572..a44d310411b1de86f72f2d817c046fc1
|
||||
|
||||
Environment* env = limits->env();
|
||||
Isolate* isolate = env->isolate();
|
||||
@@ -797,7 +797,7 @@ Intercepted DatabaseSyncLimits::LimitsSetter(
|
||||
@@ -859,7 +859,7 @@ Intercepted DatabaseSyncLimits::LimitsSetter(
|
||||
}
|
||||
|
||||
DatabaseSyncLimits* limits;
|
||||
@@ -178,7 +178,7 @@ index a04c7b97e743d75a53e8e01f31e40f601a207572..a44d310411b1de86f72f2d817c046fc1
|
||||
|
||||
Environment* env = limits->env();
|
||||
Isolate* isolate = env->isolate();
|
||||
@@ -3039,9 +3039,9 @@ BaseObjectPtr<StatementSyncIterator> StatementExecutionHelper::Iterate(
|
||||
@@ -3253,9 +3253,9 @@ BaseObjectPtr<StatementSyncIterator> StatementExecutionHelper::Iterate(
|
||||
}
|
||||
|
||||
if (iter->object()
|
||||
@@ -191,10 +191,10 @@ index a04c7b97e743d75a53e8e01f31e40f601a207572..a44d310411b1de86f72f2d817c046fc1
|
||||
return BaseObjectPtr<StatementSyncIterator>();
|
||||
}
|
||||
diff --git a/src/node_util.cc b/src/node_util.cc
|
||||
index 6d3373caae6c5cc22e16fc32e7ea007178aa1a20..ad979ff1c223b571486265d27b35cb617dfc82a9 100644
|
||||
index 39523bd256c8bf22597ba79dd06ea451025ffabb..04217d6dce9333cf0e5a1c6de711f49b93c46663 100644
|
||||
--- a/src/node_util.cc
|
||||
+++ b/src/node_util.cc
|
||||
@@ -366,7 +366,7 @@ static void DefineLazyPropertiesGetter(
|
||||
@@ -369,7 +369,7 @@ static void DefineLazyPropertiesGetter(
|
||||
// When this getter is invoked in a vm context, the `Realm::GetCurrent(info)`
|
||||
// returns a nullptr and retrieve the creation context via `this` object and
|
||||
// get the creation Realm.
|
||||
@@ -203,6 +203,15 @@ index 6d3373caae6c5cc22e16fc32e7ea007178aa1a20..ad979ff1c223b571486265d27b35cb61
|
||||
if (!receiver_val->IsObject()) {
|
||||
THROW_ERR_INVALID_INVOCATION(isolate);
|
||||
return;
|
||||
@@ -522,7 +522,7 @@ void Initialize(Local<Object> target,
|
||||
|
||||
{
|
||||
const Local<Object> prototype =
|
||||
- SharedArrayBuffer::New(isolate, 0)->GetPrototypeV2().As<Object>();
|
||||
+ SharedArrayBuffer::New(isolate, 0)->GetPrototype().As<Object>();
|
||||
const Local<Object> descriptor =
|
||||
prototype
|
||||
->GetOwnPropertyDescriptor(
|
||||
diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc
|
||||
index 8a058f19834134ca65b7a763b7c41fe850642980..3856e9cdaa305f4919c315060bae8d1a5f17cb80 100644
|
||||
--- a/src/node_webstorage.cc
|
||||
|
||||
@@ -76,10 +76,10 @@ index 53d4de01666271e6bb84b04d3386b7b1cb193cdd..757d39558f7853d39ee0d574152bb381
|
||||
THROW_ERR_INVALID_INVOCATION(isolate);
|
||||
return;
|
||||
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
|
||||
index 91ae8c9d31f5c8984c25c1030238fbe0db5c95a2..a04c7b97e743d75a53e8e01f31e40f601a207572 100644
|
||||
index f21c7deea5edd85198bb4c015af0d38b42e7d8c9..d1ef4d06f73bcb23686d91df2a0a3d5141e1ba70 100644
|
||||
--- a/src/node_sqlite.cc
|
||||
+++ b/src/node_sqlite.cc
|
||||
@@ -765,7 +765,7 @@ Intercepted DatabaseSyncLimits::LimitsGetter(
|
||||
@@ -827,7 +827,7 @@ Intercepted DatabaseSyncLimits::LimitsGetter(
|
||||
}
|
||||
|
||||
DatabaseSyncLimits* limits;
|
||||
@@ -88,7 +88,7 @@ index 91ae8c9d31f5c8984c25c1030238fbe0db5c95a2..a04c7b97e743d75a53e8e01f31e40f60
|
||||
|
||||
Environment* env = limits->env();
|
||||
Isolate* isolate = env->isolate();
|
||||
@@ -797,7 +797,7 @@ Intercepted DatabaseSyncLimits::LimitsSetter(
|
||||
@@ -859,7 +859,7 @@ Intercepted DatabaseSyncLimits::LimitsSetter(
|
||||
}
|
||||
|
||||
DatabaseSyncLimits* limits;
|
||||
@@ -98,10 +98,10 @@ index 91ae8c9d31f5c8984c25c1030238fbe0db5c95a2..a04c7b97e743d75a53e8e01f31e40f60
|
||||
Environment* env = limits->env();
|
||||
Isolate* isolate = env->isolate();
|
||||
diff --git a/src/node_util.cc b/src/node_util.cc
|
||||
index 027f668c21944308d021e8eb10ee3898c8b482a7..ce381c00888b032c281938a7bab334058e075ec8 100644
|
||||
index 96c0c9397546afc420f3649b5d5ba9f636364bb9..c3a6fbed06efc92e3cc0ac59ab51c8b802033c81 100644
|
||||
--- a/src/node_util.cc
|
||||
+++ b/src/node_util.cc
|
||||
@@ -366,7 +366,7 @@ static void DefineLazyPropertiesGetter(
|
||||
@@ -369,7 +369,7 @@ static void DefineLazyPropertiesGetter(
|
||||
// When this getter is invoked in a vm context, the `Realm::GetCurrent(info)`
|
||||
// returns a nullptr and retrieve the creation context via `this` object and
|
||||
// get the creation Realm.
|
||||
|
||||
@@ -7,7 +7,7 @@ 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/node.gyp b/node.gyp
|
||||
index 988838e85858ef1ca87662a024c278f811477179..5df80c48e7c747a49bd2e86ea7706de757fff32e 100644
|
||||
index 62c748b130c7ddec9e429d48925e79d5a395bd73..14f14c79630f19bbf7d319b669614123ef94b148 100644
|
||||
--- a/node.gyp
|
||||
+++ b/node.gyp
|
||||
@@ -152,6 +152,7 @@
|
||||
@@ -19,10 +19,10 @@ index 988838e85858ef1ca87662a024c278f811477179..5df80c48e7c747a49bd2e86ea7706de7
|
||||
'src/node_snapshotable.cc',
|
||||
'src/node_sockaddr.cc',
|
||||
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
|
||||
index 3f5f70bf320040bafa479279c163d7c74d3decc6..2023f913eae6661768c09d80fffa9ce58396da9d 100644
|
||||
index 19a087770f7ef98b5a93429f785a45281446d3d5..70392a2e29ac85012a11f517e103e24b0a0439d0 100644
|
||||
--- a/src/crypto/crypto_util.cc
|
||||
+++ b/src/crypto/crypto_util.cc
|
||||
@@ -403,24 +403,30 @@ std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore(
|
||||
@@ -765,24 +765,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);
|
||||
@@ -69,7 +69,7 @@ index 3f5f70bf320040bafa479279c163d7c74d3decc6..2023f913eae6661768c09d80fffa9ce5
|
||||
#else
|
||||
std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
|
||||
allocated_data_,
|
||||
@@ -793,19 +799,13 @@ namespace {
|
||||
@@ -1155,19 +1161,13 @@ namespace {
|
||||
// using OPENSSL_malloc. However, if the secure heap is
|
||||
// initialized, SecureBuffer will automatically use it.
|
||||
void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -95,7 +95,7 @@ index 3f5f70bf320040bafa479279c163d7c74d3decc6..2023f913eae6661768c09d80fffa9ce5
|
||||
|
||||
auto data = DataPointer::SecureAlloc(len);
|
||||
diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc
|
||||
index be4067df0e226636cb6d876c41aa830343069f86..82da68d8eef06c57aae76f2b54eeb09db5b41ecf 100644
|
||||
index 944802925def832be06a05f05a9ff535b5e0d97c..1bf003f830812664ad903dbdfe30366835767c0b 100644
|
||||
--- a/src/crypto/crypto_x509.cc
|
||||
+++ b/src/crypto/crypto_x509.cc
|
||||
@@ -141,19 +141,17 @@ MaybeLocal<Value> ToBuffer(Environment* env, BIOPointer* bio) {
|
||||
@@ -425,10 +425,10 @@ index 0000000000000000000000000000000000000000..44bc180778a23ce611b570c91242a1b1
|
||||
+
|
||||
+#endif // SRC_NODE_SERDES_UTILS_H_
|
||||
diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc
|
||||
index 5e01f64a5039235447101d0d8cfbdba3da4ddbc1..49c457cae2b3da603a548874f63dbdf9f50580d9 100644
|
||||
index 08eb71c5122d749bd499d55a7cd878b50ca321a0..f2d766b8b192dfbbd40af1f8ffaee624b747bb1d 100644
|
||||
--- a/src/node_trace_events.cc
|
||||
+++ b/src/node_trace_events.cc
|
||||
@@ -141,12 +141,28 @@ static void GetCategoryEnabledBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -145,12 +145,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);
|
||||
|
||||
@@ -19,7 +19,7 @@ user with ordinary permissions.
|
||||
Refs: https://github.com/nodejs/node/pull/57103
|
||||
|
||||
diff --git a/test/parallel/test-fs-rm.js b/test/parallel/test-fs-rm.js
|
||||
index e92bf8c079715fc97f491f83be09a606769eba18..b15118fc9aa0d63688cdac07e8004f452d86d08e 100644
|
||||
index 1d0578e3004da463d30cdb9ff2bd28477d4318f5..6a2607ad57ece1e9a0b82dded7bf46bb722e18d9 100644
|
||||
--- a/test/parallel/test-fs-rm.js
|
||||
+++ b/test/parallel/test-fs-rm.js
|
||||
@@ -491,7 +491,8 @@ if (isGitPresent) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sam Attard <sattard@anthropic.com>
|
||||
Date: Thu, 15 Oct 2026 18:02:58 +0000
|
||||
Subject: test: drop removed wasm rab integration flag
|
||||
|
||||
Chromium's V8 shipped resizable ArrayBuffer / WebAssembly integration and
|
||||
removed the --experimental-wasm-rab-integration flag, so passing it makes
|
||||
the test exit with "bad option". Node.js v24.22.0 added the flag to
|
||||
test-internal-webidl-buffer-source.js.
|
||||
|
||||
This patch can be removed once Node.js's bundled V8 no longer has the
|
||||
flag and the test stops passing it.
|
||||
|
||||
Refs: https://github.com/nodejs/node/pull/65845
|
||||
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/7708297
|
||||
|
||||
diff --git a/test/parallel/test-internal-webidl-buffer-source.js b/test/parallel/test-internal-webidl-buffer-source.js
|
||||
index b3158bd7d3481e3257fc97a1ed584cd27e8d0c9b..8e81f42a9456054d95dd60fca6c99f4ebcf21736 100644
|
||||
--- a/test/parallel/test-internal-webidl-buffer-source.js
|
||||
+++ b/test/parallel/test-internal-webidl-buffer-source.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-// Flags: --expose-internals --experimental-wasm-rab-integration
|
||||
+// Flags: --expose-internals
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sam Attard <sattard@anthropic.com>
|
||||
Date: Thu, 15 Oct 2026 19:31:39 +0000
|
||||
Subject: test: skip rmSync permission error test when running as root
|
||||
|
||||
test-fs-rmSync-special-char-additional-error.js (new in v24.22.0) makes
|
||||
a directory read-only and expects rmSync() to fail with EACCES. Root
|
||||
ignores directory permissions, so the removal succeeds and the cleanup
|
||||
chmod then throws ENOENT. Electron's Linux CI runs the Node.js suite as
|
||||
root; skip there like test-fs-rm.js already guards its permission block
|
||||
with process.getuid() !== 0.
|
||||
|
||||
This should be upstreamed; remove the patch once Node.js carries the
|
||||
guard.
|
||||
|
||||
Refs: https://github.com/nodejs/node/pull/64453
|
||||
|
||||
diff --git a/test/parallel/test-fs-rmSync-special-char-additional-error.js b/test/parallel/test-fs-rmSync-special-char-additional-error.js
|
||||
index 9b4de3c84d626fbbc4d537bd539276dc42d5f5c4..615a6128302efb9906bfce0bea93f93020477953 100644
|
||||
--- a/test/parallel/test-fs-rmSync-special-char-additional-error.js
|
||||
+++ b/test/parallel/test-fs-rmSync-special-char-additional-error.js
|
||||
@@ -6,6 +6,9 @@ const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
+if (!common.isWindows && process.getuid() === 0)
|
||||
+ common.skip('as this test checks permission errors, it cannot run as root');
|
||||
+
|
||||
tmpdir.refresh(); // Prepare a clean temporary directory
|
||||
|
||||
function countOccurrences(haystack, needle) {
|
||||
@@ -70,10 +70,10 @@ index 1066633daf65d430b5f46e1b226ee3cf70979c33..c7c39ae8c0632695d8b22023b8e6b1d1
|
||||
|
||||
class ContextifyScript final : CPPGC_MIXIN(ContextifyScript) {
|
||||
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
|
||||
index a219d512570136a9b1e940942b8426bf19d0d1f1..3e846a672900807ba8df19e626837ce18be503c4 100644
|
||||
index 6a48db67baad3d97e3bc8a469e65fc5b07548ffd..6a0cbefdb84b26ac0f37a90742c25a10662eaf41 100644
|
||||
--- a/test/cctest/test_environment.cc
|
||||
+++ b/test/cctest/test_environment.cc
|
||||
@@ -706,15 +706,16 @@ TEST_F(EnvironmentTest, NestedMicrotaskQueue) {
|
||||
@@ -806,15 +806,16 @@ TEST_F(EnvironmentTest, NestedMicrotaskQueue) {
|
||||
const v8::HandleScope handle_scope(isolate_);
|
||||
const Argv argv;
|
||||
|
||||
|
||||
+4
-10
@@ -302,8 +302,9 @@ int NodeMain() {
|
||||
// bootstrapped environment) from the snapshot instead of running the
|
||||
// bootstrap -- the same path the browser process takes in
|
||||
// NodeBindings::CreateEnvironment.
|
||||
auto snapshot_wrapper = snapshot ? snapshot->AsEmbedderWrapper()
|
||||
: node::EmbedderSnapshotData::Pointer{};
|
||||
auto snapshot_wrapper =
|
||||
snapshot ? node::EmbedderSnapshotData::BuiltinSnapshotData()
|
||||
: node::EmbedderSnapshotData::Pointer{};
|
||||
isolate_data = node::CreateIsolateData(isolate, loop, gin_env.platform(),
|
||||
/*allocator=*/nullptr,
|
||||
snapshot_wrapper.get());
|
||||
@@ -323,21 +324,14 @@ int NodeMain() {
|
||||
static_cast<node::EnvironmentFlags::Flags>(env_flags));
|
||||
CHECK_NE(nullptr, env);
|
||||
|
||||
node::IsolateSettings isolate_settings;
|
||||
if (snapshot) {
|
||||
// The snapshot's main context was created inside CreateEnvironment and
|
||||
// is not entered yet; enter it for the lifetime of the process, as
|
||||
// JavascriptEnvironment does for the context it creates itself (its
|
||||
// destructor exits the current context).
|
||||
env->context()->Enter();
|
||||
// node::CreateEnvironment already installed the per-isolate message
|
||||
// listener while deserializing (SetIsolateErrorHandlers, snapshot path
|
||||
// only). Listeners are additive, so don't let SetIsolateUpForNode add a
|
||||
// second one -- every uncaught exception would be reported twice.
|
||||
isolate_settings.flags &=
|
||||
~node::IsolateSettingsFlags::MESSAGE_LISTENER_WITH_ERROR_LEVEL;
|
||||
}
|
||||
node::SetIsolateUpForNode(isolate, isolate_settings);
|
||||
node::SetIsolateUpForNode(isolate, node::IsolateSettings{});
|
||||
|
||||
gin_helper::Dictionary process(isolate, env->process_object());
|
||||
process.SetMethod<&ElectronBindings::Crash>("crash");
|
||||
|
||||
@@ -799,9 +799,6 @@ void NodeBindings::SetUpIsolate(v8::Isolate* const isolate) {
|
||||
browser_env_ == BrowserEnvironment::kUtility) {
|
||||
// Node.js requires that microtask checkpoints be explicitly invoked.
|
||||
is.policy = v8::MicrotasksPolicy::kExplicit;
|
||||
// node::CreateEnvironment already added Node's listener if it built the
|
||||
// environment from the Node snapshot; keep exactly one.
|
||||
isolate->RemoveMessageListeners(node::errors::PerIsolateMessageListener);
|
||||
} else {
|
||||
// Blink expects the microtasks policy to be kScoped, but Node.js expects it
|
||||
// to be kExplicit. In the renderer, there can be many contexts within the
|
||||
@@ -871,10 +868,9 @@ std::shared_ptr<node::Environment> NodeBindings::CreateEnvironment(
|
||||
|
||||
// The Node startup snapshot's per-isolate data (templates, primordials)
|
||||
// is fed to CreateIsolateData so the bootstrap is deserialized.
|
||||
auto snapshot_wrapper = from_snapshot
|
||||
? node::SnapshotBuilder::GetEmbeddedSnapshotData()
|
||||
->AsEmbedderWrapper()
|
||||
: node::EmbedderSnapshotData::Pointer{};
|
||||
auto snapshot_wrapper =
|
||||
from_snapshot ? node::EmbedderSnapshotData::BuiltinSnapshotData()
|
||||
: node::EmbedderSnapshotData::Pointer{};
|
||||
auto* isolate_data =
|
||||
node::CreateIsolateData(isolate, uv_loop_, platform,
|
||||
/*allocator=*/nullptr, snapshot_wrapper.get());
|
||||
|
||||
Reference in new issue
Block a user