Repository: electron/electron
Pull request: fix: crash when attempting to resolve modules during process exit

Backport of #49090

See that PR for details.

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

Changed files:
filename: patches/node/api_remove_deprecated_getisolate.patch
patch: @@ -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);
  

filename: patches/node/fix_ensure_traverseparent_bails_on_resource_path_exit.patch
patch: @@ -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(
        }
      }
  

filename: patches/node/fix_expose_readfilesync_override_for_modules.patch
patch: @@ -20,47 +20,66 @@ 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;
 +using v8::Function;
  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) {
 +  auto isolate = realm->isolate();
    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) {

filename: patches/node/src_use_cp_utf8_for_wide_file_names_on_win32.patch
patch: @@ -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);