fix: crash when attempting to resolve modules during process exit (#49090)

* fix: crash when attempting to resolve modules during process exit

* chore: fix build
This commit is contained in:
Robo
2025-11-27 18:30:09 +09:00
committed by GitHub
parent 640c7bb908
commit 4adfc212b3
4 changed files with 39 additions and 20 deletions

View File

@@ -586,10 +586,10 @@ index 57e068ae249d618c2658638f9f3b03e1fedb6524..8c51ae4e0a435971c6d0288af8781087
data_.Reset(); data_.Reset();
return ret; return ret;
diff --git a/src/node_modules.cc b/src/node_modules.cc diff --git a/src/node_modules.cc b/src/node_modules.cc
index eea4ba313d8dbcf7b88b79f5a3e9ba2eb39d7c3e..529b7cfc15536c3fe5e7798c0f82698121751f2a 100644 index 6b1a9e257b0ce52820838f88c44ec546068fe419..5355f2f96e9c9f6548ae43fd38b0d89a825e6b60 100644
--- a/src/node_modules.cc --- a/src/node_modules.cc
+++ b/src/node_modules.cc +++ b/src/node_modules.cc
@@ -69,7 +69,7 @@ void BindingData::Deserialize(v8::Local<v8::Context> context, @@ -70,7 +70,7 @@ void BindingData::Deserialize(v8::Local<v8::Context> context,
int index, int index,
InternalFieldInfoBase* info) { InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index); DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -598,7 +598,7 @@ index eea4ba313d8dbcf7b88b79f5a3e9ba2eb39d7c3e..529b7cfc15536c3fe5e7798c0f826981
Realm* realm = Realm::GetCurrent(context); Realm* realm = Realm::GetCurrent(context);
BindingData* binding = realm->AddBindingData<BindingData>(holder); BindingData* binding = realm->AddBindingData<BindingData>(holder);
CHECK_NOT_NULL(binding); CHECK_NOT_NULL(binding);
@@ -696,7 +696,7 @@ void BindingData::CreatePerContextProperties(Local<Object> target, @@ -709,7 +709,7 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
Realm* realm = Realm::GetCurrent(context); Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(target); realm->AddBindingData<BindingData>(target);

View File

@@ -8,10 +8,10 @@ resource path. This commit ensures that the TraverseParent function
bails out if the parent path is outside of the resource path. bails out if the parent path is outside of the resource path.
diff --git a/src/node_modules.cc b/src/node_modules.cc diff --git a/src/node_modules.cc b/src/node_modules.cc
index cbc3283fc2d511cce2eae0048cc9bf0fa917d38a..3b4d82da2ad30cafa96611eaa2d68ddf1badeac0 100644 index 15686c00524b6e9a31d6d27069605b1d9ebd5d38..98d4dec64c904f45ae09bf3cd8ec9b18b275bc44 100644
--- a/src/node_modules.cc --- a/src/node_modules.cc
+++ b/src/node_modules.cc +++ b/src/node_modules.cc
@@ -320,8 +320,41 @@ const BindingData::PackageConfig* BindingData::TraverseParent( @@ -333,8 +333,41 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
Realm* realm, const std::filesystem::path& check_path) { Realm* realm, const std::filesystem::path& check_path) {
std::filesystem::path current_path = check_path; std::filesystem::path current_path = check_path;
auto env = realm->env(); auto env = realm->env();
@@ -53,7 +53,7 @@ index cbc3283fc2d511cce2eae0048cc9bf0fa917d38a..3b4d82da2ad30cafa96611eaa2d68ddf
do { do {
current_path = current_path.parent_path(); current_path = current_path.parent_path();
@@ -341,6 +374,12 @@ const BindingData::PackageConfig* BindingData::TraverseParent( @@ -354,6 +387,12 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
} }
} }

View File

@@ -20,10 +20,10 @@ index 39803ae466fc81a6b2ff6e12093cdf2082790a9f..29ce687a03ccc8e45881f70d34e009e0
V(performance_entry_callback, v8::Function) \ V(performance_entry_callback, v8::Function) \
V(prepare_stack_trace_callback, v8::Function) \ V(prepare_stack_trace_callback, v8::Function) \
diff --git a/src/node_modules.cc b/src/node_modules.cc diff --git a/src/node_modules.cc b/src/node_modules.cc
index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2eb39d7c3e 100644 index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..6b1a9e257b0ce52820838f88c44ec546068fe419 100644
--- a/src/node_modules.cc --- a/src/node_modules.cc
+++ b/src/node_modules.cc +++ b/src/node_modules.cc
@@ -23,6 +23,7 @@ namespace modules { @@ -23,12 +23,14 @@ namespace modules {
using v8::Array; using v8::Array;
using v8::Context; using v8::Context;
using v8::External; using v8::External;
@@ -31,7 +31,14 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
using v8::FunctionCallbackInfo; using v8::FunctionCallbackInfo;
using v8::HandleScope; using v8::HandleScope;
using v8::Integer; using v8::Integer;
@@ -94,6 +95,7 @@ Local<Array> BindingData::PackageConfig::Serialize(Realm* realm) const { using v8::Isolate;
using v8::Local;
using v8::LocalVector;
+using v8::MaybeLocal;
using v8::Name;
using v8::NewStringType;
using v8::Null;
@@ -94,6 +96,7 @@ Local<Array> BindingData::PackageConfig::Serialize(Realm* realm) const {
const BindingData::PackageConfig* BindingData::GetPackageJSON( const BindingData::PackageConfig* BindingData::GetPackageJSON(
Realm* realm, std::string_view path, ErrorContext* error_context) { Realm* realm, std::string_view path, ErrorContext* error_context) {
@@ -39,28 +46,40 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
auto binding_data = realm->GetBindingData<BindingData>(); auto binding_data = realm->GetBindingData<BindingData>();
auto cache_entry = binding_data->package_configs_.find(path.data()); auto cache_entry = binding_data->package_configs_.find(path.data());
@@ -103,8 +105,36 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON( @@ -103,8 +106,48 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
PackageConfig package_config{}; PackageConfig package_config{};
package_config.file_path = path; package_config.file_path = path;
+ +
+ Local<Function> modules_read_file_sync = realm->modules_read_file_sync(); + Local<Function> modules_read_file_sync = realm->modules_read_file_sync();
+ +
+ int read_err; + int read_err = -1;
// No need to exclude BOM since simdjson will skip it. // No need to exclude BOM since simdjson will skip it.
- if (ReadFileSync(&package_config.raw_json, path.data()) < 0) { - if (ReadFileSync(&package_config.raw_json, path.data()) < 0) {
+ if (modules_read_file_sync.IsEmpty()) { + if (modules_read_file_sync.IsEmpty()) {
+ read_err = ReadFileSync(&package_config.raw_json, path.data()); + read_err = ReadFileSync(&package_config.raw_json, path.data());
+ } else { + } else if (realm->env()->can_call_into_js()) {
+ v8::TryCatch try_catch(isolate);
+ Local<Value> args[] = { + Local<Value> args[] = {
+ v8::String::NewFromUtf8(isolate, path.data()).ToLocalChecked(), + v8::String::NewFromUtf8(isolate, path.data()).ToLocalChecked(),
+ }; + };
+ Local<Value> result = modules_read_file_sync->Call( + MaybeLocal<Value> maybe_result = modules_read_file_sync->Call(
+ realm->context(), + realm->context(),
+ Undefined(isolate), + Undefined(isolate),
+ arraysize(args), + arraysize(args),
+ args).ToLocalChecked(); + args);
+ +
+ if (maybe_result.IsEmpty()) {
+ CHECK(try_catch.HasCaught());
+ }
+
+ if (try_catch.HasCaught()) {
+ if (!try_catch.HasTerminated())
+ try_catch.ReThrow();
+ return nullptr;
+ }
+
+ Local<Value> result = maybe_result.ToLocalChecked();
+ if (result->IsUndefined()) { + if (result->IsUndefined()) {
+ // Fallback + // Fallback
+ read_err = ReadFileSync(&package_config.raw_json, path.data()); + read_err = ReadFileSync(&package_config.raw_json, path.data());
@@ -77,7 +96,7 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
return nullptr; return nullptr;
} }
simdjson::ondemand::document document; simdjson::ondemand::document document;
@@ -242,6 +272,12 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON( @@ -242,6 +285,12 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
return &cached.first->second; return &cached.first->second;
} }
@@ -90,7 +109,7 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
void BindingData::ReadPackageJSON(const FunctionCallbackInfo<Value>& args) { void BindingData::ReadPackageJSON(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1); // path, [is_esm, base, specifier] CHECK_GE(args.Length(), 1); // path, [is_esm, base, specifier]
CHECK(args[0]->IsString()); // path CHECK(args[0]->IsString()); // path
@@ -635,6 +671,8 @@ void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) { @@ -635,6 +684,8 @@ void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<ObjectTemplate> target) { Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate(); Isolate* isolate = isolate_data->isolate();
@@ -99,7 +118,7 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
SetMethod(isolate, target, "readPackageJSON", ReadPackageJSON); SetMethod(isolate, target, "readPackageJSON", ReadPackageJSON);
SetMethod(isolate, SetMethod(isolate,
target, target,
@@ -694,6 +732,8 @@ void BindingData::CreatePerContextProperties(Local<Object> target, @@ -694,6 +745,8 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
void BindingData::RegisterExternalReferences( void BindingData::RegisterExternalReferences(
ExternalReferenceRegistry* registry) { ExternalReferenceRegistry* registry) {

View File

@@ -136,10 +136,10 @@ index 969e7d08086f8442bed476feaf15599b8c79db7c..e7459654401c275dfb86207831016ed7
std::make_error_code(std::errc::file_exists), std::make_error_code(std::errc::file_exists),
"cp", "cp",
diff --git a/src/node_modules.cc b/src/node_modules.cc diff --git a/src/node_modules.cc b/src/node_modules.cc
index 529b7cfc15536c3fe5e7798c0f82698121751f2a..cbc3283fc2d511cce2eae0048cc9bf0fa917d38a 100644 index 5355f2f96e9c9f6548ae43fd38b0d89a825e6b60..15686c00524b6e9a31d6d27069605b1d9ebd5d38 100644
--- a/src/node_modules.cc --- a/src/node_modules.cc
+++ b/src/node_modules.cc +++ b/src/node_modules.cc
@@ -332,22 +332,24 @@ const BindingData::PackageConfig* BindingData::TraverseParent( @@ -345,22 +345,24 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
// Stop the search when the process doesn't have permissions // Stop the search when the process doesn't have permissions
// to walk upwards // to walk upwards
@@ -172,7 +172,7 @@ index 529b7cfc15536c3fe5e7798c0f82698121751f2a..cbc3283fc2d511cce2eae0048cc9bf0f
if (package_json != nullptr) { if (package_json != nullptr) {
return package_json; return package_json;
} }
@@ -369,20 +371,12 @@ void BindingData::GetNearestParentPackageJSONType( @@ -382,20 +384,12 @@ void BindingData::GetNearestParentPackageJSONType(
ToNamespacedPath(realm->env(), &path_value); ToNamespacedPath(realm->env(), &path_value);