blob: a1b90c4ff2d0aa5739999731068508b1258f67fe [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"
Devlin Croninfe480ed2017-09-15 20:51:1117#include "base/unguessable_token.h"
[email protected]f55c90ee62014-04-12 00:50:0318#include "extensions/common/features/feature.h"
rockote261b162014-12-12 01:59:4719#include "extensions/common/permissions/api_permission_set.h"
[email protected]f55c90ee62014-04-12 00:50:0320#include "extensions/renderer/module_system.h"
21#include "extensions/renderer/request_sender.h"
kalman33076cb2015-08-11 19:12:0722#include "extensions/renderer/safe_builtins.h"
rdevlin.cronin0d94256f2016-12-09 15:34:2323#include "extensions/renderer/script_injection_callback.h"
[email protected]d9f51dad2014-07-09 05:39:3824#include "gin/runner.h"
Sadrul Habib Chowdhury0d7ef9f2014-12-03 20:07:3025#include "url/gurl.h"
[email protected]f55c90ee62014-04-12 00:50:0326#include "v8/include/v8.h"
27
28namespace blink {
kalmanf91cb892015-04-15 19:20:4829class WebLocalFrame;
[email protected]f55c90ee62014-04-12 00:50:0330}
31
32namespace content {
[email protected]2101c4c2014-08-22 00:16:1633class RenderFrame;
[email protected]f55c90ee62014-04-12 00:50:0334}
35
36namespace extensions {
tbarzicfeb4b052016-11-29 18:23:0937enum class CheckAliasStatus;
[email protected]f55c90ee62014-04-12 00:50:0338class Extension;
39
kalman04755302015-09-14 18:52:1140// Extensions wrapper for a v8::Context.
41//
42// v8::Contexts can be constructed on any thread, and must only be accessed or
43// destroyed that thread.
44//
45// Note that ScriptContexts bound to worker threads will not have the full
46// functionality as those bound to the main RenderThread.
sammcde54a47e2015-01-13 23:16:3447class ScriptContext : public RequestSender::Source {
[email protected]f55c90ee62014-04-12 00:50:0348 public:
annekao533482222015-08-21 23:23:5349 using RunScriptExceptionHandler = base::Callback<void(const v8::TryCatch&)>;
50
tfarinaf85316f2015-04-29 17:03:4051 ScriptContext(const v8::Local<v8::Context>& context,
kalmanf91cb892015-04-15 19:20:4852 blink::WebLocalFrame* frame,
[email protected]f55c90ee62014-04-12 00:50:0353 const Extension* extension,
mek7e1d7452014-09-08 23:55:5754 Feature::Context context_type,
55 const Extension* effective_extension,
56 Feature::Context effective_context_type);
dcheng9168b2f2014-10-21 12:38:2457 ~ScriptContext() override;
[email protected]f55c90ee62014-04-12 00:50:0358
kalmanc81508d2015-04-23 17:14:0259 // Returns whether |url| from any Extension in |extension_set| is sandboxed,
60 // as declared in each Extension's manifest.
61 // TODO(kalman): Delete this when crbug.com/466373 is fixed.
62 // See comment in HasAccessOrThrowError.
annekao6572d5c2015-08-19 16:13:3663 static bool IsSandboxedPage(const GURL& url);
kalmanf91cb892015-04-15 19:20:4864
Daniel Cheng971cd4522017-05-31 21:58:2265 // Clears the WebLocalFrame for this contexts and invalidates the associated
[email protected]f55c90ee62014-04-12 00:50:0366 // ModuleSystem.
67 void Invalidate();
68
kalmanb0c1c502015-04-15 00:25:0669 // Registers |observer| to be run when this context is invalidated. Closures
70 // are run immediately when Invalidate() is called, not in a message loop.
71 void AddInvalidationObserver(const base::Closure& observer);
72
[email protected]f55c90ee62014-04-12 00:50:0373 // Returns true if this context is still valid, false if it isn't.
74 // A context becomes invalid via Invalidate().
kalmanb0c1c502015-04-15 00:25:0675 bool is_valid() const { return is_valid_; }
[email protected]f55c90ee62014-04-12 00:50:0376
tfarinaf85316f2015-04-29 17:03:4077 v8::Local<v8::Context> v8_context() const {
kalman078a2192015-03-09 18:19:3978 return v8::Local<v8::Context>::New(isolate_, v8_context_);
[email protected]f55c90ee62014-04-12 00:50:0379 }
80
81 const Extension* extension() const { return extension_.get(); }
82
mek7e1d7452014-09-08 23:55:5783 const Extension* effective_extension() const {
84 return effective_extension_.get();
85 }
86
kalmanf91cb892015-04-15 19:20:4887 blink::WebLocalFrame* web_frame() const { return web_frame_; }
[email protected]f55c90ee62014-04-12 00:50:0388
89 Feature::Context context_type() const { return context_type_; }
90
mek7e1d7452014-09-08 23:55:5791 Feature::Context effective_context_type() const {
92 return effective_context_type_;
93 }
94
Devlin Croninfe480ed2017-09-15 20:51:1195 const base::UnguessableToken& context_id() const { return context_id_; }
96
dchengf6f80662016-04-20 20:26:0497 void set_module_system(std::unique_ptr<ModuleSystem> module_system) {
dchenge59eca1602015-12-18 17:48:0098 module_system_ = std::move(module_system);
[email protected]f55c90ee62014-04-12 00:50:0399 }
100
101 ModuleSystem* module_system() { return module_system_.get(); }
102
kalman33076cb2015-08-11 19:12:07103 SafeBuiltins* safe_builtins() { return &safe_builtins_; }
[email protected]f55c90ee62014-04-12 00:50:03104
kalman33076cb2015-08-11 19:12:07105 const SafeBuiltins* safe_builtins() const { return &safe_builtins_; }
[email protected]f55c90ee62014-04-12 00:50:03106
107 // Returns the ID of the extension associated with this context, or empty
108 // string if there is no such extension.
[email protected]800f9872014-06-12 04:12:51109 const std::string& GetExtensionID() const;
[email protected]f55c90ee62014-04-12 00:50:03110
[email protected]2101c4c2014-08-22 00:16:16111 // Returns the RenderFrame associated with this context. Can return NULL if
112 // the context is in the process of being destroyed.
113 content::RenderFrame* GetRenderFrame() const;
114
rdevlin.cronina9bc8cc2016-10-06 15:51:17115 // Safely calls the v8::Function, respecting the page load deferrer and
116 // possibly executing asynchronously.
rdevlin.cronin12a457eb2016-10-25 20:39:58117 // Doesn't catch exceptions; callers must do that if they want.
rdevlin.cronin0d94256f2016-12-09 15:34:23118 // USE THESE METHODS RATHER THAN v8::Function::Call WHEREVER POSSIBLE.
rdevlin.cronina9bc8cc2016-10-06 15:51:17119 void SafeCallFunction(const v8::Local<v8::Function>& function,
120 int argc,
121 v8::Local<v8::Value> argv[]);
rdevlin.cronin0d94256f2016-12-09 15:34:23122 void SafeCallFunction(
123 const v8::Local<v8::Function>& function,
124 int argc,
125 v8::Local<v8::Value> argv[],
126 const ScriptInjectionCallback::CompleteCallback& callback);
rdevlin.cronina9bc8cc2016-10-06 15:51:17127
[email protected]f55c90ee62014-04-12 00:50:03128 // Returns the availability of the API |api_name|.
129 Feature::Availability GetAvailability(const std::string& api_name);
tbarzicfeb4b052016-11-29 18:23:09130 // Returns the availability of the API |api_name|.
131 // |check_alias| Whether API that has an alias that is available should be
132 // considered available (even if the API itself is not available).
133 Feature::Availability GetAvailability(const std::string& api_name,
134 CheckAliasStatus check_alias);
[email protected]f55c90ee62014-04-12 00:50:03135
136 // Returns a string description of the type of context this is.
kalman8bcbc7592015-06-03 23:12:27137 std::string GetContextTypeDescription() const;
[email protected]f55c90ee62014-04-12 00:50:03138
mek7e1d7452014-09-08 23:55:57139 // Returns a string description of the effective type of context this is.
kalman8bcbc7592015-06-03 23:12:27140 std::string GetEffectiveContextTypeDescription() const;
mek7e1d7452014-09-08 23:55:57141
[email protected]f55c90ee62014-04-12 00:50:03142 v8::Isolate* isolate() const { return isolate_; }
143
144 // Get the URL of this context's web frame.
kalmanf91cb892015-04-15 19:20:48145 //
146 // TODO(kalman): Remove this and replace with a GetOrigin() call which reads
Dana Jansens71331252016-03-09 20:57:22147 // of WebDocument::getSecurityOrigin():
kalmanf91cb892015-04-15 19:20:48148 // - The URL can change (e.g. pushState) but the origin cannot. Luckily it
149 // appears as though callers don't make security decisions based on the
kalman04755302015-09-14 18:52:11150 // result of url() so it's not a problem... yet.
kalmanf91cb892015-04-15 19:20:48151 // - Origin is the correct check to be making.
152 // - It might let us remove the about:blank resolving?
kalman04755302015-09-14 18:52:11153 const GURL& url() const { return url_; }
154
lazyboy63b994a2017-06-30 21:20:23155 const GURL& service_worker_scope() const;
156
kalman04755302015-09-14 18:52:11157 // Sets the URL of this ScriptContext. Usually this will automatically be set
158 // on construction, unless this isn't constructed with enough information to
159 // determine the URL (e.g. frame was null).
160 // TODO(kalman): Make this a constructor parameter (as an origin).
161 void set_url(const GURL& url) { url_ = url; }
lazyboy63b994a2017-06-30 21:20:23162 void set_service_worker_scope(const GURL& scope) {
163 service_worker_scope_ = scope;
164 }
[email protected]f55c90ee62014-04-12 00:50:03165
tbarzicfeb4b052016-11-29 18:23:09166 // Returns whether the API |api| or any part of the API could be available in
167 // this context without taking into account the context's extension.
168 // |check_alias| Whether the API should be considered available if it has an
169 // alias that is available.
170 bool IsAnyFeatureAvailableToContext(const extensions::Feature& api,
171 CheckAliasStatus check_alias);
[email protected]f55c90ee62014-04-12 00:50:03172
173 // Utility to get the URL we will match against for a frame. If the frame has
174 // committed, this is the commited URL. Otherwise it is the provisional URL.
[email protected]c1abb3232014-07-30 18:28:39175 // The returned URL may be invalid.
Takeshi Yoshino41b671a2017-08-01 12:17:51176 static GURL GetDocumentLoaderURLForFrame(const blink::WebLocalFrame* frame);
[email protected]f55c90ee62014-04-12 00:50:03177
Takeshi Yoshino41b671a2017-08-01 12:17:51178 // Similar to GetDocumentLoaderURLForFrame, but only returns the data source
179 // URL if the frame's document url is empty and the frame has a security
180 // origin that allows access to the data source url.
asargent79b64c32016-08-04 17:17:14181 // TODO(asargent/devlin) - there may be places that should switch to using
Takeshi Yoshino41b671a2017-08-01 12:17:51182 // this instead of GetDocumentLoaderURLForFrame.
Daniel Cheng971cd4522017-05-31 21:58:22183 static GURL GetAccessCheckedFrameURL(const blink::WebLocalFrame* frame);
asargent79b64c32016-08-04 17:17:14184
[email protected]ae26b282014-05-15 16:40:16185 // Returns the first non-about:-URL in the document hierarchy above and
186 // including |frame|. The document hierarchy is only traversed if
187 // |document_url| is an about:-URL and if |match_about_blank| is true.
lukaszabedb4b22017-06-23 00:00:13188 static GURL GetEffectiveDocumentURL(blink::WebLocalFrame* frame,
[email protected]ae26b282014-05-15 16:40:16189 const GURL& document_url,
190 bool match_about_blank);
191
[email protected]f55c90ee62014-04-12 00:50:03192 // RequestSender::Source implementation.
dcheng9168b2f2014-10-21 12:38:24193 ScriptContext* GetContext() override;
194 void OnResponseReceived(const std::string& name,
195 int request_id,
196 bool success,
197 const base::ListValue& response,
198 const std::string& error) override;
[email protected]f55c90ee62014-04-12 00:50:03199
rockote261b162014-12-12 01:59:47200 // Grants a set of content capabilities to this context.
kalman04755302015-09-14 18:52:11201 void set_content_capabilities(const APIPermissionSet& capabilities) {
202 content_capabilities_ = capabilities;
203 }
rockote261b162014-12-12 01:59:47204
205 // Indicates if this context has an effective API permission either by being
206 // a context for an extension which has that permission, or by being a web
207 // context which has been granted the corresponding capability by an
208 // extension.
209 bool HasAPIPermission(APIPermission::ID permission) const;
210
kalmanc81508d2015-04-23 17:14:02211 // Throws an Error in this context's JavaScript context, if this context does
212 // not have access to |name|. Returns true if this context has access (i.e.
213 // no exception thrown), false if it does not (i.e. an exception was thrown).
214 bool HasAccessOrThrowError(const std::string& name);
215
kalman8bcbc7592015-06-03 23:12:27216 // Returns a string representation of this ScriptContext, for debugging.
217 std::string GetDebugString() const;
218
dmazzonid6848287c2015-07-27 23:41:31219 // Gets the current stack trace as a multi-line string to be logged.
220 std::string GetStackTraceAsString() const;
221
annekao533482222015-08-21 23:23:53222 // Runs |code|, labelling the script that gets created as |name| (the name is
223 // used in the devtools and stack traces). |exception_handler| will be called
224 // re-entrantly if an exception is thrown during the script's execution.
225 v8::Local<v8::Value> RunScript(
226 v8::Local<v8::String> name,
227 v8::Local<v8::String> code,
228 const RunScriptExceptionHandler& exception_handler);
229
mlamouri60a2857d2015-04-14 15:22:36230 private:
rdevlin.cronincf5482bd2017-06-14 13:18:18231 // DEPRECATED.
232 v8::Local<v8::Value> CallFunction(const v8::Local<v8::Function>& function,
233 int argc,
234 v8::Local<v8::Value> argv[]) const;
235
mlamouri60a2857d2015-04-14 15:22:36236 class Runner;
237
kalmanb0c1c502015-04-15 00:25:06238 // Whether this context is valid.
239 bool is_valid_;
240
241 // The v8 context the bindings are accessible to.
242 v8::Global<v8::Context> v8_context_;
243
kalmanf91cb892015-04-15 19:20:48244 // The WebLocalFrame associated with this context. This can be NULL because
245 // this object can outlive is destroyed asynchronously.
246 blink::WebLocalFrame* web_frame_;
[email protected]f55c90ee62014-04-12 00:50:03247
248 // The extension associated with this context, or NULL if there is none. This
249 // might be a hosted app in the case that this context is hosting a web URL.
250 scoped_refptr<const Extension> extension_;
251
252 // The type of context.
253 Feature::Context context_type_;
254
mek7e1d7452014-09-08 23:55:57255 // The effective extension associated with this context, or NULL if there is
256 // none. This is different from the above extension if this context is in an
257 // about:blank iframe for example.
258 scoped_refptr<const Extension> effective_extension_;
259
260 // The type of context.
261 Feature::Context effective_context_type_;
262
Devlin Croninfe480ed2017-09-15 20:51:11263 // A globally-unique ID for the script context.
264 base::UnguessableToken context_id_;
265
[email protected]f55c90ee62014-04-12 00:50:03266 // Owns and structures the JS that is injected to set up extension bindings.
dchengf6f80662016-04-20 20:26:04267 std::unique_ptr<ModuleSystem> module_system_;
[email protected]f55c90ee62014-04-12 00:50:03268
269 // Contains safe copies of builtin objects like Function.prototype.
kalman33076cb2015-08-11 19:12:07270 SafeBuiltins safe_builtins_;
[email protected]f55c90ee62014-04-12 00:50:03271
rockote261b162014-12-12 01:59:47272 // The set of capabilities granted to this context by extensions.
273 APIPermissionSet content_capabilities_;
274
kalmanb0c1c502015-04-15 00:25:06275 // A list of base::Closure instances as an observer interface for
276 // invalidation.
277 std::vector<base::Closure> invalidate_observers_;
278
[email protected]f55c90ee62014-04-12 00:50:03279 v8::Isolate* isolate_;
280
Sadrul Habib Chowdhury0d7ef9f2014-12-03 20:07:30281 GURL url_;
282
lazyboy63b994a2017-06-30 21:20:23283 GURL service_worker_scope_;
284
dchengf6f80662016-04-20 20:26:04285 std::unique_ptr<Runner> runner_;
sammcde54a47e2015-01-13 23:16:34286
kalman04755302015-09-14 18:52:11287 base::ThreadChecker thread_checker_;
288
[email protected]f55c90ee62014-04-12 00:50:03289 DISALLOW_COPY_AND_ASSIGN(ScriptContext);
290};
291
292} // namespace extensions
293
294#endif // EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_