1 /*
2  * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_CONTROLLER_H_
32 #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_CONTROLLER_H_
33 
34 #include <memory>
35 
36 #include "base/macros.h"
37 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
38 #include "third_party/blink/renderer/bindings/core/v8/script_source_location_type.h"
39 #include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
40 #include "third_party/blink/renderer/core/core_export.h"
41 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
42 #include "third_party/blink/renderer/platform/heap/handle.h"
43 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
44 #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
45 #include "third_party/blink/renderer/platform/wtf/text/text_position.h"
46 #include "third_party/blink/renderer/platform/wtf/vector.h"
47 #include "v8/include/v8.h"
48 
49 namespace blink {
50 
51 class DOMWrapperWorld;
52 class ExecutionContext;
53 class KURL;
54 class LocalDOMWindow;
55 class ScriptSourceCode;
56 class SecurityOrigin;
57 
58 // This class exposes methods to run script in a frame (in the main world and
59 // in isolated worlds). An instance can be obtained by using
60 // LocalDOMWindow::GetScriptController().
61 class CORE_EXPORT ScriptController final
62     : public GarbageCollected<ScriptController> {
63  public:
64   enum ExecuteScriptPolicy {
65     kExecuteScriptWhenScriptsDisabled,
66     kDoNotExecuteScriptWhenScriptsDisabled
67   };
68 
ScriptController(LocalDOMWindow & window,LocalWindowProxyManager & window_proxy_manager)69   ScriptController(LocalDOMWindow& window,
70                    LocalWindowProxyManager& window_proxy_manager)
71       : window_(&window), window_proxy_manager_(&window_proxy_manager) {}
72   void Trace(Visitor*) const;
73 
74   // This returns an initialized window proxy. (If the window proxy is not
75   // yet initialized, it's implicitly initialized at the first access.)
WindowProxy(DOMWrapperWorld & world)76   LocalWindowProxy* WindowProxy(DOMWrapperWorld& world) {
77     return window_proxy_manager_->WindowProxy(world);
78   }
79 
80   v8::Local<v8::Value> ExecuteScriptAndReturnValue(
81       v8::Local<v8::Context>,
82       const ScriptSourceCode&,
83       const KURL& base_url,
84       SanitizeScriptErrors,
85       const ScriptFetchOptions& = ScriptFetchOptions());
86 
87   v8::Local<v8::Value> EvaluateMethodInMainWorld(
88       v8::Local<v8::Function> function,
89       v8::Local<v8::Value> receiver,
90       int argc,
91       v8::Local<v8::Value> argv[],
92       ScriptController::ExecuteScriptPolicy = ScriptController::
93           ExecuteScriptPolicy::kDoNotExecuteScriptWhenScriptsDisabled);
94 
95   // Evaluate JavaScript in the main world.
96   v8::Local<v8::Value> EvaluateScriptInMainWorld(const ScriptSourceCode&,
97                                                  const KURL& base_url,
98                                                  SanitizeScriptErrors,
99                                                  const ScriptFetchOptions&,
100                                                  ExecuteScriptPolicy);
101 
102   // Executes JavaScript in an isolated world. The script gets its own global
103   // scope, its own prototypes for intrinsic JavaScript objects (String, Array,
104   // and so-on), and its own wrappers for all DOM nodes and DOM constructors.
105   //
106   // If an isolated world with the specified ID already exists, it is reused.
107   // Otherwise, a new world is created.
108   v8::Local<v8::Value> ExecuteScriptInIsolatedWorld(
109       int32_t world_id,
110       const ScriptSourceCode&,
111       const KURL& base_url,
112       SanitizeScriptErrors sanitize_script_errors);
113 
114   // Executes a javascript url in the main world. |world_for_csp| denotes the
115   // javascript world in which this navigation initiated and which should be
116   // used for CSP checks.
117   void ExecuteJavaScriptURL(const KURL&,
118                             network::mojom::CSPDisposition,
119                             const DOMWrapperWorld* world_for_csp);
120 
121   // Creates a new isolated world for DevTools with the given human readable
122   // |world_name| and returns it id or nullptr on failure.
123   scoped_refptr<DOMWrapperWorld> CreateNewInspectorIsolatedWorld(
124       const String& world_name);
125 
126   // Disables eval for the main world.
127   void DisableEval(const String& error_message);
128 
129   // Disables eval for the given isolated |world_id|. This initializes the
130   // window proxy for the isolated world, if it's not yet initialized.
131   void DisableEvalForIsolatedWorld(int32_t world_id,
132                                    const String& error_message);
133 
134   TextPosition EventHandlerPosition() const;
135 
136   void UpdateDocument();
137   void UpdateSecurityOrigin(const SecurityOrigin*);
138 
139   // Registers a v8 extension to be available on webpages. Will only
140   // affect v8 contexts initialized after this call.
141   static void RegisterExtensionIfNeeded(std::unique_ptr<v8::Extension>);
142   static v8::ExtensionConfiguration ExtensionsFor(const ExecutionContext*);
143 
144  private:
145   bool CanExecuteScript(ExecuteScriptPolicy policy);
GetIsolate()146   v8::Isolate* GetIsolate() const {
147     return window_proxy_manager_->GetIsolate();
148   }
149   void EnableEval();
150 
151   // Sets whether eval is enabled for the context corresponding to the given
152   // |world|. |error_message| is used only when |allow_eval| is false.
153   void SetEvalForWorld(DOMWrapperWorld& world,
154                        bool allow_eval,
155                        const String& error_message);
156 
157   const Member<LocalDOMWindow> window_;
158   const Member<LocalWindowProxyManager> window_proxy_manager_;
159 
160   DISALLOW_COPY_AND_ASSIGN(ScriptController);
161 };
162 
163 }  // namespace blink
164 
165 #endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_CONTROLLER_H_
166