Browse Source

fix: crash when drag-dropping some files

Shelley Vohr 3 weeks ago
parent
commit
8a2d165b4b
1 changed files with 44 additions and 0 deletions
  1. 44 0
      shell/renderer/api/electron_api_context_bridge.cc

+ 44 - 0
shell/renderer/api/electron_api_context_bridge.cc

@@ -417,6 +417,50 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContextInner(
       return v8::MaybeLocal<v8::Value>(
           blob.ToV8Value(destination_context->GetIsolate()));
     }
+
+    // Custom logic to "clone" FileList references
+    auto object_value = value.As<v8::Object>();
+    v8::Maybe<bool> has_length = object_value->Has(
+        source_context,
+        gin::StringToV8(source_context->GetIsolate(), "length"));
+    v8::Maybe<bool> has_item = object_value->Has(
+        source_context, gin::StringToV8(source_context->GetIsolate(), "item"));
+    if (has_length.FromJust() && has_item.FromJust()) {
+      v8::Local<v8::Value> length, item_fn;
+      if (object_value
+              ->Get(source_context,
+                    gin::StringToV8(source_context->GetIsolate(), "length"))
+              .ToLocal(&length) &&
+          length->IsNumber() &&
+          object_value
+              ->Get(source_context,
+                    gin::StringToV8(source_context->GetIsolate(), "item"))
+              .ToLocal(&item_fn) &&
+          item_fn->IsFunction()) {
+        v8::Context::Scope destination_scope(destination_context);
+        uint32_t item_count = length->Uint32Value(source_context).FromJust();
+        v8::Local<v8::Array> array =
+            v8::Array::New(destination_context->GetIsolate(), item_count);
+
+        for (uint32_t i = 0; i < item_count; i++) {
+          v8::Local<v8::Value> file;
+          if (object_value->Get(source_context, i).ToLocal(&file)) {
+            auto passed_file = PassValueToOtherContextInner(
+                source_context, source_execution_context, destination_context,
+                file, value, object_cache, support_dynamic_properties,
+                recursion_depth + 1, error_target);
+
+            if (!passed_file.IsEmpty() &&
+                !IsTrue(array->Set(destination_context, i,
+                                   passed_file.ToLocalChecked())))
+              return {};
+          }
+        }
+
+        object_cache->CacheProxiedObject(value, array);
+        return v8::MaybeLocal<v8::Value>(array);
+      }
+    }
   }
 
   // Proxy all objects