blob: c314d825d74d32cc493f5f7643b2980451c0957b [file] [log] [blame]
[email protected]f55c90ee62014-04-12 00:50:031// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_
6#define EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_
7
asargent79b64c32016-08-04 17:17:148#include <memory>
[email protected]f55c90ee62014-04-12 00:50:039#include <string>
dchenge59eca1602015-12-18 17:48:0010#include <utility>
kalmanb0c1c502015-04-15 00:25:0611#include <vector>
[email protected]f55c90ee62014-04-12 00:50:0312
kalmanb0c1c502015-04-15 00:25:0613#include "base/callback.h"
[email protected]f55c90ee62014-04-12 00:50:0314#include "base/compiler_specific.h"
avi2d124c02015-12-23 06:36:4215#include "base/macros.h"
kalman04755302015-09-14 18:52:1116#include "base/threading/thread_checker.h"
[email protected]f55c90ee62014-04-12 00:50:0317#include "extensions/common/features/feature.h"
rockote261b162014-12-12 01:59:4718#include "extensions/common/permissions/api_permission_set.h"
[email protected]f55c90ee62014-04-12 00:50:0319#include "extensions/renderer/module_system.h"
20#include "extensions/renderer/request_sender.h"
kalman33076cb2015-08-11 19:12:0721#include "extensions/renderer/safe_builtins.h"
rdevlin.cronin0d94256f2016-12-09 15:34:2322#include "extensions/renderer/script_injection_callback.h"
[email protected]d9f51dad2014-07-09 05:39:3823#include "gin/runner.h"
Sadrul Habib Chowdhury0d7ef9f2014-12-03 20:07:3024#include "url/gurl.h"
[email protected]f55c90ee62014-04-12 00:50:0325#include "v8/include/v8.h"
26
27namespace blink {
kalmanf91cb892015-04-15 19:20:4828class WebLocalFrame;
[email protected]f55c90ee62014-04-12 00:50:0329}
30
31namespace content {
[email protected]2101c4c2014-08-22 00:16:1632class RenderFrame;
[email protected]f55c90ee62014-04-12 00:50:0333}
34
35namespace extensions {
tbarzicfeb4b052016-11-29 18:23:0936enum class CheckAliasStatus;
[email protected]f55c90ee62014-04-12 00:50:0337class Extension;
38
kalman04755302015-09-14 18:52:1139// Extensions wrapper for a v8::Context.
40//
41// v8::Contexts can be constructed on any thread, and must only be accessed or
42// destroyed that thread.
43//
44// Note that ScriptContexts bound to worker threads will not have the full
45// functionality as those bound to the main RenderThread.
sammcde54a47e2015-01-13 23:16:3446class ScriptContext : public RequestSender::Source {
[email protected]f55c90ee62014-04-12 00:50:0347 public:
annekao533482222015-08-21 23:23:5348 using RunScriptExceptionHandler = base::Callback<void(const v8::TryCatch&)>;
49
tfarinaf85316f2015-04-29 17:03:4050 ScriptContext(const v8::Local<v8::Context>& context,
kalmanf91cb892015-04-15 19:20:4851 blink::WebLocalFrame* frame,
[email protected]f55c90ee62014-04-12 00:50:0352 const Extension* extension,
mek7e1d7452014-09-08 23:55:5753 Feature::Context context_type,
54 const Extension* effective_extension,
55 Feature::Context effective_context_type);
dcheng9168b2f2014-10-21 12:38:2456 ~ScriptContext() override;
[email protected]f55c90ee62014-04-12 00:50:0357
kalmanc81508d2015-04-23 17:14:0258 // Returns whether |url| from any Extension in |extension_set| is sandboxed,
59 // as declared in each Extension's manifest.
60 // TODO(kalman): Delete this when crbug.com/466373 is fixed.
61 // See comment in HasAccessOrThrowError.
annekao6572d5c2015-08-19 16:13:3662 static bool IsSandboxedPage(const GURL& url);
kalmanf91cb892015-04-15 19:20:4863
Daniel Cheng971cd4522017-05-31 21:58:2264 // Clears the WebLocalFrame for this contexts and invalidates the associated
[email protected]f55c90ee62014-04-12 00:50:0365 // ModuleSystem.
66 void Invalidate();
67
kalmanb0c1c502015-04-15 00:25:0668 // Registers |observer| to be run when this context is invalidated. Closures
69 // are run immediately when Invalidate() is called, not in a message loop.
70 void AddInvalidationObserver(const base::Closure& observer);
71
[email protected]f55c90ee62014-04-12 00:50:0372 // Returns true if this context is still valid, false if it isn't.
73 // A context becomes invalid via Invalidate().
kalmanb0c1c502015-04-15 00:25:0674 bool is_valid() const { return is_valid_; }
[email protected]f55c90ee62014-04-12 00:50:0375
tfarinaf85316f2015-04-29 17:03:4076 v8::Local<v8::Context> v8_context() const {
kalman078a2192015-03-09 18:19:3977 return v8::Local<v8::Context>::New(isolate_, v8_context_);
[email protected]f55c90ee62014-04-12 00:50:0378 }
79
80 const Extension* extension() const { return extension_.get(); }
81
mek7e1d7452014-09-08 23:55:5782 const Extension* effective_extension() const {
83 return effective_extension_.get();
84 }
85
kalmanf91cb892015-04-15 19:20:4886 blink::WebLocalFrame* web_frame() const { return web_frame_; }
[email protected]f55c90ee62014-04-12 00:50:0387
88 Feature::Context context_type() const { return context_type_; }
89
mek7e1d7452014-09-08 23:55:5790 Feature::Context effective_context_type() const {
91 return effective_context_type_;
92 }
93
dchengf6f80662016-04-20 20:26:0494 void set_module_system(std::unique_ptr<ModuleSystem> module_system) {
dchenge59eca1602015-12-18 17:48:0095 module_system_ = std::move(module_system);
[email protected]f55c90ee62014-04-12 00:50:0396 }
97
98 ModuleSystem* module_system() { return module_system_.get(); }
99
kalman33076cb2015-08-11 19:12:07100 SafeBuiltins* safe_builtins() { return &safe_builtins_; }
[email protected]f55c90ee62014-04-12 00:50:03101
kalman33076cb2015-08-11 19:12:07102 const SafeBuiltins* safe_builtins() const { return &safe_builtins_; }
[email protected]f55c90ee62014-04-12 00:50:03103
104 // Returns the ID of the extension associated with this context, or empty
105 // string if there is no such extension.
[email protected]800f9872014-06-12 04:12:51106 const std::string& GetExtensionID() const;
[email protected]f55c90ee62014-04-12 00:50:03107
[email protected]2101c4c2014-08-22 00:16:16108 // Returns the RenderFrame associated with this context. Can return NULL if
109 // the context is in the process of being destroyed.
110 content::RenderFrame* GetRenderFrame() const;
111
rdevlin.cronin12a457eb2016-10-25 20:39:58112 // DEPRECATED.
kalman70c00e242015-05-15 23:42:27113 v8::Local<v8::Value> CallFunction(const v8::Local<v8::Function>& function,
[email protected]f55c90ee62014-04-12 00:50:03114 int argc,
tfarinaf85316f2015-04-29 17:03:40115 v8::Local<v8::Value> argv[]) const;
[email protected]f55c90ee62014-04-12 00:50:03116
rdevlin.cronina9bc8cc2016-10-06 15:51:17117 // Safely calls the v8::Function, respecting the page load deferrer and
118 // possibly executing asynchronously.
rdevlin.cronin12a457eb2016-10-25 20:39:58119 // Doesn't catch exceptions; callers must do that if they want.
rdevlin.cronin0d94256f2016-12-09 15:34:23120 // USE THESE METHODS RATHER THAN v8::Function::Call WHEREVER POSSIBLE.
rdevlin.cronina9bc8cc2016-10-06 15:51:17121 // TODO(devlin): Remove the above variants in favor of this.
122 void SafeCallFunction(const v8::Local<v8::Function>& function,
123 int argc,
124 v8::Local<v8::Value> argv[]);
rdevlin.cronin0d94256f2016-12-09 15:34:23125 void SafeCallFunction(
126 const v8::Local<v8::Function>& function,
127 int argc,
128 v8::Local<v8::Value> argv[],
129 const ScriptInjectionCallback::CompleteCallback& callback);
rdevlin.cronina9bc8cc2016-10-06 15:51:17130
[email protected]f55c90ee62014-04-12 00:50:03131 // Returns the availability of the API |api_name|.
132 Feature::Availability GetAvailability(const std::string& api_name);
tbarzicfeb4b052016-11-29 18:23:09133 // Returns the availability of the API |api_name|.
134 // |check_alias| Whether API that has an alias that is available should be
135 // considered available (even if the API itself is not available).
136 Feature::Availability GetAvailability(const std::string& api_name,
137 CheckAliasStatus check_alias);
[email protected]f55c90ee62014-04-12 00:50:03138
139 // Returns a string description of the type of context this is.
kalman8bcbc7592015-06-03 23:12:27140 std::string GetContextTypeDescription() const;
[email protected]f55c90ee62014-04-12 00:50:03141
mek7e1d7452014-09-08 23:55:57142 // Returns a string description of the effective type of context this is.
kalman8bcbc7592015-06-03 23:12:27143 std::string GetEffectiveContextTypeDescription() const;
mek7e1d7452014-09-08 23:55:57144
[email protected]f55c90ee62014-04-12 00:50:03145 v8::Isolate* isolate() const { return isolate_; }
146
147 // Get the URL of this context's web frame.
kalmanf91cb892015-04-15 19:20:48148 //
149 // TODO(kalman): Remove this and replace with a GetOrigin() call which reads
Dana Jansens71331252016-03-09 20:57:22150 // of WebDocument::getSecurityOrigin():
kalmanf91cb892015-04-15 19:20:48151 // - The URL can change (e.g. pushState) but the origin cannot. Luckily it
152 // appears as though callers don't make security decisions based on the
kalman04755302015-09-14 18:52:11153 // result of url() so it's not a problem... yet.
kalmanf91cb892015-04-15 19:20:48154 // - Origin is the correct check to be making.
155 // - It might let us remove the about:blank resolving?
kalman04755302015-09-14 18:52:11156 const GURL& url() const { return url_; }
157
158 // Sets the URL of this ScriptContext. Usually this will automatically be set
159 // on construction, unless this isn't constructed with enough information to
160 // determine the URL (e.g. frame was null).
161 // TODO(kalman): Make this a constructor parameter (as an origin).
162 void set_url(const GURL& url) { url_ = url; }
[email protected]f55c90ee62014-04-12 00:50:03163
tbarzicfeb4b052016-11-29 18:23:09164 // Returns whether the API |api| or any part of the API could be available in
165 // this context without taking into account the context's extension.
166 // |check_alias| Whether the API should be considered available if it has an
167 // alias that is available.
168 bool IsAnyFeatureAvailableToContext(const extensions::Feature& api,
169 CheckAliasStatus check_alias);
[email protected]f55c90ee62014-04-12 00:50:03170
171 // Utility to get the URL we will match against for a frame. If the frame has
172 // committed, this is the commited URL. Otherwise it is the provisional URL.
[email protected]c1abb3232014-07-30 18:28:39173 // The returned URL may be invalid.
Daniel Cheng971cd4522017-05-31 21:58:22174 static GURL GetDataSourceURLForFrame(const blink::WebLocalFrame* frame);
[email protected]f55c90ee62014-04-12 00:50:03175
asargent79b64c32016-08-04 17:17:14176 // Similar to GetDataSourceURLForFrame, but only returns the data source URL
177 // if the frame's document url is empty and the frame has a security origin
178 // that allows access to the data source url.
179 // TODO(asargent/devlin) - there may be places that should switch to using
180 // this instead of GetDataSourceURLForFrame.
Daniel Cheng971cd4522017-05-31 21:58:22181 static GURL GetAccessCheckedFrameURL(const blink::WebLocalFrame* frame);
asargent79b64c32016-08-04 17:17:14182
[email protected]ae26b282014-05-15 16:40:16183 // Returns the first non-about:-URL in the document hierarchy above and
184 // including |frame|. The document hierarchy is only traversed if
185 // |document_url| is an about:-URL and if |match_about_blank| is true.
Daniel Cheng971cd4522017-05-31 21:58:22186 static GURL GetEffectiveDocumentURL(const blink::WebLocalFrame* frame,
[email protected]ae26b282014-05-15 16:40:16187 const GURL& document_url,
188 bool match_about_blank);
189
[email protected]f55c90ee62014-04-12 00:50:03190 // RequestSender::Source implementation.
dcheng9168b2f2014-10-21 12:38:24191 ScriptContext* GetContext() override;
192 void OnResponseReceived(const std::string& name,
193 int request_id,
194 bool success,
195 const base::ListValue& response,
196 const std::string& error) override;
[email protected]f55c90ee62014-04-12 00:50:03197
rockote261b162014-12-12 01:59:47198 // Grants a set of content capabilities to this context.
kalman04755302015-09-14 18:52:11199 void set_content_capabilities(const APIPermissionSet& capabilities) {
200 content_capabilities_ = capabilities;
201 }
rockote261b162014-12-12 01:59:47202
203 // Indicates if this context has an effective API permission either by being
204 // a context for an extension which has that permission, or by being a web
205 // context which has been granted the corresponding capability by an
206 // extension.
207 bool HasAPIPermission(APIPermission::ID permission) const;
208
kalmanc81508d2015-04-23 17:14:02209 // Throws an Error in this context's JavaScript context, if this context does
210 // not have access to |name|. Returns true if this context has access (i.e.
211 // no exception thrown), false if it does not (i.e. an exception was thrown).
212 bool HasAccessOrThrowError(const std::string& name);
213
kalman8bcbc7592015-06-03 23:12:27214 // Returns a string representation of this ScriptContext, for debugging.
215 std::string GetDebugString() const;
216
dmazzonid6848287c2015-07-27 23:41:31217 // Gets the current stack trace as a multi-line string to be logged.
218 std::string GetStackTraceAsString() const;
219
annekao533482222015-08-21 23:23:53220 // Runs |code|, labelling the script that gets created as |name| (the name is
221 // used in the devtools and stack traces). |exception_handler| will be called
222 // re-entrantly if an exception is thrown during the script's execution.
223 v8::Local<v8::Value> RunScript(
224 v8::Local<v8::String> name,
225 v8::Local<v8::String> code,
226 const RunScriptExceptionHandler& exception_handler);
227
mlamouri60a2857d2015-04-14 15:22:36228 private:
229 class Runner;
230
kalmanb0c1c502015-04-15 00:25:06231 // Whether this context is valid.
232 bool is_valid_;
233
234 // The v8 context the bindings are accessible to.
235 v8::Global<v8::Context> v8_context_;
236
kalmanf91cb892015-04-15 19:20:48237 // The WebLocalFrame associated with this context. This can be NULL because
238 // this object can outlive is destroyed asynchronously.
239 blink::WebLocalFrame* web_frame_;
[email protected]f55c90ee62014-04-12 00:50:03240
241 // The extension associated with this context, or NULL if there is none. This
242 // might be a hosted app in the case that this context is hosting a web URL.
243 scoped_refptr<const Extension> extension_;
244
245 // The type of context.
246 Feature::Context context_type_;
247
mek7e1d7452014-09-08 23:55:57248 // The effective extension associated with this context, or NULL if there is
249 // none. This is different from the above extension if this context is in an
250 // about:blank iframe for example.
251 scoped_refptr<const Extension> effective_extension_;
252
253 // The type of context.
254 Feature::Context effective_context_type_;
255
[email protected]f55c90ee62014-04-12 00:50:03256 // Owns and structures the JS that is injected to set up extension bindings.
dchengf6f80662016-04-20 20:26:04257 std::unique_ptr<ModuleSystem> module_system_;
[email protected]f55c90ee62014-04-12 00:50:03258
259 // Contains safe copies of builtin objects like Function.prototype.
kalman33076cb2015-08-11 19:12:07260 SafeBuiltins safe_builtins_;
[email protected]f55c90ee62014-04-12 00:50:03261
rockote261b162014-12-12 01:59:47262 // The set of capabilities granted to this context by extensions.
263 APIPermissionSet content_capabilities_;
264
kalmanb0c1c502015-04-15 00:25:06265 // A list of base::Closure instances as an observer interface for
266 // invalidation.
267 std::vector<base::Closure> invalidate_observers_;
268
[email protected]f55c90ee62014-04-12 00:50:03269 v8::Isolate* isolate_;
270
Sadrul Habib Chowdhury0d7ef9f2014-12-03 20:07:30271 GURL url_;
272
dchengf6f80662016-04-20 20:26:04273 std::unique_ptr<Runner> runner_;
sammcde54a47e2015-01-13 23:16:34274
kalman04755302015-09-14 18:52:11275 base::ThreadChecker thread_checker_;
276
[email protected]f55c90ee62014-04-12 00:50:03277 DISALLOW_COPY_AND_ASSIGN(ScriptContext);
278};
279
280} // namespace extensions
281
282#endif // EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_