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();
return ret;
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
+++ 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,
InternalFieldInfoBase* info) {
DCHECK_IS_SNAPSHOT_SLOT(index);
@@ -598,7 +598,7 @@ index eea4ba313d8dbcf7b88b79f5a3e9ba2eb39d7c3e..529b7cfc15536c3fe5e7798c0f826981
Realm* realm = Realm::GetCurrent(context);
BindingData* binding = realm->AddBindingData<BindingData>(holder);
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->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.
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
+++ 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) {
std::filesystem::path current_path = check_path;
auto env = realm->env();
@@ -53,7 +53,7 @@ index cbc3283fc2d511cce2eae0048cc9bf0fa917d38a..3b4d82da2ad30cafa96611eaa2d68ddf
do {
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(prepare_stack_trace_callback, v8::Function) \
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
+++ b/src/node_modules.cc
@@ -23,6 +23,7 @@ namespace modules {
@@ -23,12 +23,14 @@ namespace modules {
using v8::Array;
using v8::Context;
using v8::External;
@@ -31,7 +31,14 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
using v8::FunctionCallbackInfo;
using v8::HandleScope;
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(
Realm* realm, std::string_view path, ErrorContext* error_context) {
@@ -39,28 +46,40 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
auto binding_data = realm->GetBindingData<BindingData>();
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{};
package_config.file_path = path;
+
+ 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.
- if (ReadFileSync(&package_config.raw_json, path.data()) < 0) {
+ if (modules_read_file_sync.IsEmpty()) {
+ 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[] = {
+ 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(),
+ Undefined(isolate),
+ 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()) {
+ // Fallback
+ read_err = ReadFileSync(&package_config.raw_json, path.data());
@@ -77,7 +96,7 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
return nullptr;
}
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;
}
@@ -90,7 +109,7 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
void BindingData::ReadPackageJSON(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1); // path, [is_esm, base, specifier]
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,
Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();
@@ -99,7 +118,7 @@ index 9eec93f52f0d0b2e45ae04ff357b4ced0770782f..eea4ba313d8dbcf7b88b79f5a3e9ba2e
SetMethod(isolate, target, "readPackageJSON", ReadPackageJSON);
SetMethod(isolate,
target,
@@ -694,6 +732,8 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
@@ -694,6 +745,8 @@ void BindingData::CreatePerContextProperties(Local<Object> target,
void BindingData::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {

View File

@@ -136,10 +136,10 @@ index 969e7d08086f8442bed476feaf15599b8c79db7c..e7459654401c275dfb86207831016ed7
std::make_error_code(std::errc::file_exists),
"cp",
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
+++ 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
// to walk upwards
@@ -172,7 +172,7 @@ index 529b7cfc15536c3fe5e7798c0f82698121751f2a..cbc3283fc2d511cce2eae0048cc9bf0f
if (package_json != nullptr) {
return package_json;
}
@@ -369,20 +371,12 @@ void BindingData::GetNearestParentPackageJSONType(
@@ -382,20 +384,12 @@ void BindingData::GetNearestParentPackageJSONType(
ToNamespacedPath(realm->env(), &path_value);