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 65bed98ed5597736f9b0a97989ce3fd4a3d93c01..61c9ccc51460824a71e76d363cd5dbec2ffc8bd5 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -271,6 +271,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 c2760ba7a404a4f3f1053712b728e1b222b83198..ee1175595a24f202b873a82f8744d3da8dd38779 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -438,6 +438,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..7a985067b1371604644d48159f2f5aa7a7abb88d 100644
--- a/third_party/blink/public/web/web_script_execution_callback.h
+++ b/third_party/blink/public/web/web_script_execution_callback.h
@@ -14,8 +14,17 @@ class TimeTicks;
 class Value;
 }
 
+namespace v8 {
+class Value;
+template <class T>
+class Local;
+}
+
 namespace blink {
 
+template <typename T>
+class WebVector;
+
 // Non-nullopt `base::Value` is passed to the callback if
 // -`WantResultOption::kWantResult` or
 //  `WantResultOption::kWantResultDateAndRegexpAllowed` is used,
@@ -43,6 +52,9 @@ namespace blink {
 using WebScriptExecutionCallback =
     base::OnceCallback<void(std::optional<base::Value>, base::TimeTicks)>;
 
+using WebScriptExecutionCallbackUnmodified =
+    base::OnceCallback<void(const WebVector<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 0ba08a946155ee4d04a693cf26840a95f315b9a3..2c6203cf838b6c988e49ffffe147264919d312c9 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2991,6 +2991,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) {
@@ -3024,7 +3025,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 fe3a87df88b5959cdc388123738d836625ccfaad..328cd42b4c7595181f6477a9d6b3a63af8939e7b 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -825,6 +825,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 1e7c9c5e99d33b1153cdf3af41a5abc58cbcbafb..d07c5b65c70236c5739186b6d3b32882b1bf330e 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
@@ -969,6 +969,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 3b31917c7225b5ad6b4e8c2c04e50354cb79c6d9..db6536dad37ddae6552c8d5b195d95e308065498 100644
--- a/third_party/blink/renderer/core/frame/pausable_script_executor.cc
+++ b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -250,7 +250,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>(
               script_state->GetIsolate(), function, receiver, argc, argv));
   executor->Run();
@@ -265,10 +265,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) {
@@ -290,6 +291,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(Vector<v8::Local<v8::Value>>());
+  }
   Dispose();
 }
 
@@ -300,10 +309,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),
@@ -427,6 +438,9 @@ void PausableScriptExecutor::HandleResults(
     std::move(callback_).Run(std::move(value), start_time_);
   }
 
+  if (raw_callback_)
+    std::move(raw_callback_).Run(results);
+
   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 7b3adb5b23720dd597698c7ea7672d63a926eb6c..e34095fcd5c025d3d27421b07cd41e2c4dacf98f 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -286,6 +286,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 da1a3ea87b51810f340b0673c10b29ab1f7d9328..20aa0ea69f6689c648604c2822bc6a798d5b5230 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
@@ -1120,14 +1120,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);
 }
 
 v8::MaybeLocal<v8::Value> WebLocalFrameImpl::CallFunctionEvenIfScriptDisabled(
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 df5fe9ff02ef2d2e964b2acc16976adff0e83756..7e381d75342471ec905bab0fd86cd6f6c9cac4a6 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
@@ -193,6 +193,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 5b633b529b13213cb95865d0116395cf8c40d573..cf861f130b3426d1da6c37f1efd5cd8984dee9dc 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
@@ -58,6 +58,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);
