From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Mon, 5 Sep 2022 19:07:54 +0900
Subject: fix: return v8::Value from LocalFrame::RequestExecuteScript

Allows api::WebFrame::ExecuteJavaScript(InIsolateWorld) to work with
v8::Value instead of base::Value.
Refs https://bugs.chromium.org/p/chromium/issues/detail?id=1323953

diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index fc9cb7e68bdad4c40fab63f70243e09ad005ab80..199fbceda530da31aab9126d78b4bd213cbd3cf9 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -317,6 +317,7 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
       blink::mojom::LoadEventBlockingOption::kBlock,
       base::BindOnce(&ScriptInjection::OnJsInjectionCompleted,
                      weak_ptr_factory_.GetWeakPtr()),
+      base::NullCallback(),
       blink::BackForwardCacheAware::kPossiblyDisallow,
       injector_->ExpectsResults(), injector_->ShouldWaitForPromise());
 }
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index ca8fa39d6a28efd602f064c68da33d562aab744a..589183918468cfd09ad4333e1118cfa5382de67f 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -462,6 +462,7 @@ class BLINK_EXPORT WebLocalFrame : public WebFrame {
                                     mojom::EvaluationTiming,
                                     mojom::LoadEventBlockingOption,
                                     WebScriptExecutionCallback,
+                                    WebScriptExecutionCallbackUnmodified,
                                     BackForwardCacheAware,
                                     mojom::WantResultOption,
                                     mojom::PromiseResultOption) = 0;
diff --git a/third_party/blink/public/web/web_script_execution_callback.h b/third_party/blink/public/web/web_script_execution_callback.h
index cba373664bec3a32abad6fe0396bd67b53b7e67f..a54f1b3351efd2d8f324436f7f35cd4344bbcbf0 100644
--- a/third_party/blink/public/web/web_script_execution_callback.h
+++ b/third_party/blink/public/web/web_script_execution_callback.h
@@ -14,6 +14,12 @@ class TimeTicks;
 class Value;
 }
 
+namespace v8 {
+class Value;
+template <class T>
+class Local;
+}
+
 namespace blink {
 
 // Non-nullopt `base::Value` is passed to the callback if
@@ -43,6 +49,9 @@ namespace blink {
 using WebScriptExecutionCallback =
     base::OnceCallback<void(std::optional<base::Value>, base::TimeTicks)>;
 
+using WebScriptExecutionCallbackUnmodified =
+    base::OnceCallback<void(const std::vector<v8::Local<v8::Value>>&)>;
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_SCRIPT_EXECUTION_CALLBACK_H_
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 800a904a8fa47e0a36d8393e11b3e7d7c4a3550e..3b161ce6b69a32bb283be3ef92c0b7da9e5b8320 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -3180,6 +3180,7 @@ void LocalFrame::RequestExecuteScript(
     mojom::blink::EvaluationTiming evaluation_timing,
     mojom::blink::LoadEventBlockingOption blocking_option,
     WebScriptExecutionCallback callback,
+    WebScriptExecutionCallbackUnmodified raw_callback,
     BackForwardCacheAware back_forward_cache_aware,
     mojom::blink::WantResultOption want_result_option,
     mojom::blink::PromiseResultOption promise_behavior) {
@@ -3212,7 +3213,7 @@ void LocalFrame::RequestExecuteScript(
   PausableScriptExecutor::CreateAndRun(
       script_state, std::move(script_sources), execute_script_policy,
       user_gesture, evaluation_timing, blocking_option, want_result_option,
-      promise_behavior, std::move(callback));
+      promise_behavior, std::move(callback), std::move(raw_callback));
 }
 
 void LocalFrame::SetEvictCachedSessionStorageOnFreezeOrUnload() {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index ee7cca8f64d4dfddb3eabdfb18c9f25c3d0776fe..3f2dc5242814eb27b7655aef360e12038de42ede 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -835,6 +835,7 @@ class CORE_EXPORT LocalFrame final
                             mojom::blink::EvaluationTiming,
                             mojom::blink::LoadEventBlockingOption,
                             WebScriptExecutionCallback,
+                            WebScriptExecutionCallbackUnmodified,
                             BackForwardCacheAware back_forward_cache_aware,
                             mojom::blink::WantResultOption,
                             mojom::blink::PromiseResultOption);
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
index a7d638b474011b564f326b128183278fd3fdb6e2..11a49018d7c004f34897d1a7f21c7e4705da023c 100644
--- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -968,6 +968,7 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
             std::move(callback).Run(value ? std::move(*value) : base::Value());
           },
           std::move(callback)),
+      base::NullCallback(),
       BackForwardCacheAware::kAllow,
       wants_result
           ? mojom::blink::WantResultOption::kWantResultDateAndRegExpAllowed
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.cc b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
index 19e5c838cc17844092df5652542a767316bc03b2..105f61bf14cdcfbf9cd284d80ba7bde756d5fcf2 100644
--- a/third_party/blink/renderer/core/frame/pausable_script_executor.cc
+++ b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -243,7 +243,7 @@ void PausableScriptExecutor::CreateAndRun(
           script_state, mojom::blink::UserActivationOption::kDoNotActivate,
           mojom::blink::LoadEventBlockingOption::kDoNotBlock,
           want_result_option, mojom::blink::PromiseResultOption::kDoNotWait,
-          std::move(callback),
+          std::move(callback), base::NullCallback(),
           MakeGarbageCollected<V8FunctionExecutor>(isolate, function, receiver,
                                                    argc, argv));
   executor->Run();
@@ -258,10 +258,11 @@ void PausableScriptExecutor::CreateAndRun(
     mojom::blink::LoadEventBlockingOption blocking_option,
     mojom::blink::WantResultOption want_result_option,
     mojom::blink::PromiseResultOption promise_result_option,
-    WebScriptExecutionCallback callback) {
+    WebScriptExecutionCallback callback,
+    WebScriptExecutionCallbackUnmodified raw_callback) {
   auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
       script_state, user_activation_option, blocking_option, want_result_option,
-      promise_result_option, std::move(callback),
+      promise_result_option, std::move(callback), std::move(raw_callback),
       MakeGarbageCollected<WebScriptExecutor>(std::move(sources),
                                               execute_script_policy));
   switch (evaluation_timing) {
@@ -283,6 +284,14 @@ void PausableScriptExecutor::ContextDestroyed() {
     ScriptState::Scope script_scope(script_state_);
     std::move(callback_).Run({}, {});
   }
+  if (raw_callback_) {
+    // Though the context is (about to be) destroyed, the callback is invoked
+    // with a vector of v8::Local<>s, which implies that creating v8::Locals
+    // is permitted. Ensure a valid scope is present for the callback.
+    // See https://crbug.com/840719.
+    ScriptState::Scope script_scope(script_state_);
+    std::move(raw_callback_).Run(std::vector<v8::Local<v8::Value>>());
+  }
   Dispose();
 }
 
@@ -293,10 +302,12 @@ PausableScriptExecutor::PausableScriptExecutor(
     mojom::blink::WantResultOption want_result_option,
     mojom::blink::PromiseResultOption promise_result_option,
     WebScriptExecutionCallback callback,
+    WebScriptExecutionCallbackUnmodified raw_callback,
     Executor* executor)
     : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
       script_state_(script_state),
       callback_(std::move(callback)),
+      raw_callback_(std::move(raw_callback)),
       user_activation_option_(user_activation_option),
       blocking_option_(blocking_option),
       want_result_option_(want_result_option),
@@ -420,6 +431,13 @@ void PausableScriptExecutor::HandleResults(
     std::move(callback_).Run(std::move(value), start_time_);
   }
 
+  if (raw_callback_) {
+    // TODO: use `v8::LocalVector` instead of `std::vector<v8::Local<...>>`
+    // (see https://crbug.com/40272194)
+    std::move(raw_callback_)
+        .Run(std::vector<v8::Local<v8::Value>>(results.begin(), results.end()));
+  }
+
   Dispose();
 }
 
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.h b/third_party/blink/renderer/core/frame/pausable_script_executor.h
index fa65331f40b90d812b71a489fd560e9359152d2b..390714d631dc88ef92d59ef9618a5706b4b52f22 100644
--- a/third_party/blink/renderer/core/frame/pausable_script_executor.h
+++ b/third_party/blink/renderer/core/frame/pausable_script_executor.h
@@ -48,7 +48,8 @@ class CORE_EXPORT PausableScriptExecutor final
                            mojom::blink::LoadEventBlockingOption,
                            mojom::blink::WantResultOption,
                            mojom::blink::PromiseResultOption,
-                           WebScriptExecutionCallback);
+                           WebScriptExecutionCallback,
+                           WebScriptExecutionCallbackUnmodified);
 
   class Executor : public GarbageCollected<Executor> {
    public:
@@ -65,6 +66,7 @@ class CORE_EXPORT PausableScriptExecutor final
                          mojom::blink::WantResultOption,
                          mojom::blink::PromiseResultOption,
                          WebScriptExecutionCallback,
+                         WebScriptExecutionCallbackUnmodified,
                          Executor*);
   ~PausableScriptExecutor() override;
 
@@ -83,6 +85,7 @@ class CORE_EXPORT PausableScriptExecutor final
 
   Member<ScriptState> script_state_;
   WebScriptExecutionCallback callback_;
+  WebScriptExecutionCallbackUnmodified raw_callback_;
   base::TimeTicks start_time_;
   const mojom::blink::UserActivationOption user_activation_option_;
   const mojom::blink::LoadEventBlockingOption blocking_option_;
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc
index dad0c67f5dced044d4c20bd17c9b1925c41007c6..2078a8339f9fcba15c8e0f381794572478c99e21 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -299,6 +299,7 @@ void ExecuteScriptsInMainWorld(
       DOMWrapperWorld::kMainWorldId, sources, user_gesture,
       mojom::blink::EvaluationTiming::kSynchronous,
       mojom::blink::LoadEventBlockingOption::kDoNotBlock, std::move(callback),
+      base::NullCallback(),
       BackForwardCacheAware::kAllow,
       mojom::blink::WantResultOption::kWantResult, wait_for_promise);
 }
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index c4aceecbb08cada3486ccb551fca0cabae134d7f..d6b8bf14ab4bac1b167ca7ffa4c242af27dac491 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1121,14 +1121,15 @@ void WebLocalFrameImpl::RequestExecuteScript(
     mojom::blink::EvaluationTiming evaluation_timing,
     mojom::blink::LoadEventBlockingOption blocking_option,
     WebScriptExecutionCallback callback,
+    WebScriptExecutionCallbackUnmodified raw_callback,
     BackForwardCacheAware back_forward_cache_aware,
     mojom::blink::WantResultOption want_result_option,
     mojom::blink::PromiseResultOption promise_behavior) {
   DCHECK(GetFrame());
   GetFrame()->RequestExecuteScript(
       world_id, sources, user_gesture, evaluation_timing, blocking_option,
-      std::move(callback), back_forward_cache_aware, want_result_option,
-      promise_behavior);
+      std::move(callback), std::move(raw_callback), back_forward_cache_aware,
+      want_result_option, promise_behavior);
 }
 
 bool WebLocalFrameImpl::IsInspectorConnected() {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index 3a3fcb811fa3657c0af80d851a848855c9caf91d..b7a667d468e8b8d89488c8d5a7a05c41e93c625d 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -199,6 +199,7 @@ class CORE_EXPORT WebLocalFrameImpl final
                             mojom::blink::EvaluationTiming,
                             mojom::blink::LoadEventBlockingOption,
                             WebScriptExecutionCallback,
+                            WebScriptExecutionCallbackUnmodified,
                             BackForwardCacheAware back_forward_cache_aware,
                             mojom::blink::WantResultOption,
                             mojom::blink::PromiseResultOption) override;
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc
index 5e66719cf6d8170039c011ad03d56ea55ee8f2cb..5a71dd5172c88aed1498dea02f790a7f278ac174 100644
--- a/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc
+++ b/third_party/blink/renderer/core/scheduler_integration_tests/virtual_time_test.cc
@@ -59,6 +59,7 @@ class VirtualTimeTest : public SimTest {
         mojom::blink::LoadEventBlockingOption::kDoNotBlock,
         WTF::BindOnce(&ScriptExecutionCallbackHelper::Completed,
                       base::Unretained(&callback_helper)),
+        base::NullCallback(),
         BackForwardCacheAware::kAllow,
         mojom::blink::WantResultOption::kWantResult,
         mojom::blink::PromiseResultOption::kDoNotWait);
