blob: c320c9c3a1f8e2bcf237e56249a38c0daec5d242 [file] [log] [blame]
[email protected]c11e6592014-06-27 17:07:341// 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#include "extensions/renderer/programmatic_script_injector.h"
6
dchenge59eca1602015-12-18 17:48:007#include <utility>
[email protected]c11e6592014-06-27 17:07:348#include <vector>
9
10#include "base/values.h"
roba9e6e6422015-03-30 21:14:0211#include "content/public/common/url_constants.h"
rdevlin.croninf994d1e2015-06-03 22:28:1912#include "content/public/renderer/render_frame.h"
[email protected]c11e6592014-06-27 17:07:3413#include "extensions/common/error_utils.h"
[email protected]c11e6592014-06-27 17:07:3414#include "extensions/common/extension_messages.h"
15#include "extensions/common/manifest_constants.h"
rob52277c82016-02-07 17:28:5716#include "extensions/common/permissions/api_permission.h"
[email protected]c11e6592014-06-27 17:07:3417#include "extensions/common/permissions/permissions_data.h"
hanxia5c856cf2015-02-13 20:51:5818#include "extensions/renderer/injection_host.h"
rob52277c82016-02-07 17:28:5719#include "extensions/renderer/renderer_extension_registry.h"
[email protected]c11e6592014-06-27 17:07:3420#include "extensions/renderer/script_context.h"
Blink Reformata30d4232018-04-07 15:31:0621#include "third_party/blink/public/platform/web_string.h"
22#include "third_party/blink/public/web/web_document.h"
23#include "third_party/blink/public/web/web_local_frame.h"
24#include "third_party/blink/public/web/web_script_source.h"
[email protected]c11e6592014-06-27 17:07:3425
26namespace extensions {
27
28ProgrammaticScriptInjector::ProgrammaticScriptInjector(
jam69e71152016-11-02 01:15:4329 const ExtensionMsg_ExecuteCode_Params& params)
[email protected]c11e6592014-06-27 17:07:3430 : params_(new ExtensionMsg_ExecuteCode_Params(params)),
[email protected]c11e6592014-06-27 17:07:3431 finished_(false) {
32}
33
34ProgrammaticScriptInjector::~ProgrammaticScriptInjector() {
35}
36
[email protected]23a85362014-07-07 23:26:1937UserScript::InjectionType ProgrammaticScriptInjector::script_type()
38 const {
39 return UserScript::PROGRAMMATIC_SCRIPT;
40}
41
[email protected]c11e6592014-06-27 17:07:3442bool ProgrammaticScriptInjector::ShouldExecuteInMainWorld() const {
43 return params_->in_main_world;
44}
45
46bool ProgrammaticScriptInjector::IsUserGesture() const {
47 return params_->user_gesture;
48}
49
Manish Jethani9494d722018-01-20 00:28:4750base::Optional<CSSOrigin> ProgrammaticScriptInjector::GetCssOrigin() const {
51 return params_->css_origin;
52}
53
Manish Jethaniff6ff852018-02-23 07:24:5554const base::Optional<std::string>
55ProgrammaticScriptInjector::GetInjectionKey() const {
56 return params_->injection_key;
57}
58
[email protected]c11e6592014-06-27 17:07:3459bool ProgrammaticScriptInjector::ExpectsResults() const {
60 return params_->wants_result;
61}
62
63bool ProgrammaticScriptInjector::ShouldInjectJs(
catmullingsd4faad4f2016-09-08 19:55:3064 UserScript::RunLocation run_location,
65 const std::set<std::string>& executing_scripts) const {
Devlin Cronina9ec04b2017-11-28 19:27:2966 return params_->run_at == run_location && params_->is_javascript;
[email protected]c11e6592014-06-27 17:07:3467}
68
69bool ProgrammaticScriptInjector::ShouldInjectCss(
catmullingsd4faad4f2016-09-08 19:55:3070 UserScript::RunLocation run_location,
71 const std::set<std::string>& injected_stylesheets) const {
Devlin Cronina9ec04b2017-11-28 19:27:2972 return params_->run_at == run_location && !params_->is_javascript;
[email protected]c11e6592014-06-27 17:07:3473}
74
Devlin Cronin3e532b82018-05-03 21:27:1975PermissionsData::PageAccess ProgrammaticScriptInjector::CanExecuteOnFrame(
hanxia5c856cf2015-02-13 20:51:5876 const InjectionHost* injection_host,
rdevlin.cronin3e11c9862015-06-04 19:54:2577 blink::WebLocalFrame* frame,
jam69e71152016-11-02 01:15:4378 int tab_id) {
79 // Note: we calculate url_ now and not in the constructor because with
80 // PlzNavigate we won't have the URL at that point when loads start. The
81 // browser issues the request and only when it has a response does the
82 // renderer see the provisional data source which the method below uses.
Takeshi Yoshino41b671a2017-08-01 12:17:5183 url_ = ScriptContext::GetDocumentLoaderURLForFrame(frame);
jam69e71152016-11-02 01:15:4384 if (url_.SchemeIs(url::kAboutScheme)) {
Blink Reformat1c4d759e2017-04-09 16:34:5485 origin_for_about_error_ = frame->GetSecurityOrigin().ToString().Utf8();
jam69e71152016-11-02 01:15:4386 }
[email protected]c11e6592014-06-27 17:07:3487 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL(
Blink Reformat1c4d759e2017-04-09 16:34:5488 frame, frame->GetDocument().Url(), params_->match_about_blank);
[email protected]c11e6592014-06-27 17:07:3489 if (params_->is_web_view) {
Blink Reformat1c4d759e2017-04-09 16:34:5490 if (frame->Parent()) {
lazyboy2254f0e2014-12-10 07:10:5491 // This is a subframe inside <webview>, so allow it.
Devlin Cronin3e532b82018-05-03 21:27:1992 return PermissionsData::PageAccess::kAllowed;
lazyboy2254f0e2014-12-10 07:10:5493 }
94
[email protected]23a85362014-07-07 23:26:1995 return effective_document_url == params_->webview_src
Devlin Cronin3e532b82018-05-03 21:27:1996 ? PermissionsData::PageAccess::kAllowed
97 : PermissionsData::PageAccess::kDenied;
[email protected]c11e6592014-06-27 17:07:3498 }
hanxi79f7a572015-03-09 20:46:5999 DCHECK_EQ(injection_host->id().type(), HostID::EXTENSIONS);
[email protected]c11e6592014-06-27 17:07:34100
hanxia5c856cf2015-02-13 20:51:58101 return injection_host->CanExecuteOnFrame(
rdevlin.croninf994d1e2015-06-03 22:28:19102 effective_document_url,
103 content::RenderFrame::FromWebFrame(frame),
104 tab_id,
105 true /* is_declarative */);
[email protected]c11e6592014-06-27 17:07:34106}
107
108std::vector<blink::WebScriptSource> ProgrammaticScriptInjector::GetJsSources(
catmullingsd4faad4f2016-09-08 19:55:30109 UserScript::RunLocation run_location,
110 std::set<std::string>* executing_scripts,
111 size_t* num_injected_js_scripts) const {
Devlin Cronina9ec04b2017-11-28 19:27:29112 DCHECK_EQ(params_->run_at, run_location);
[email protected]c11e6592014-06-27 17:07:34113 DCHECK(params_->is_javascript);
114
115 return std::vector<blink::WebScriptSource>(
Blink Reformat1c4d759e2017-04-09 16:34:54116 1, blink::WebScriptSource(blink::WebString::FromUTF8(params_->code),
117 params_->file_url));
[email protected]c11e6592014-06-27 17:07:34118}
119
lazyboy49cc0b3a2016-08-18 21:55:12120std::vector<blink::WebString> ProgrammaticScriptInjector::GetCssSources(
catmullingsd4faad4f2016-09-08 19:55:30121 UserScript::RunLocation run_location,
122 std::set<std::string>* injected_stylesheets,
123 size_t* num_injected_stylesheets) const {
Devlin Cronina9ec04b2017-11-28 19:27:29124 DCHECK_EQ(params_->run_at, run_location);
[email protected]c11e6592014-06-27 17:07:34125 DCHECK(!params_->is_javascript);
126
lazyboy49cc0b3a2016-08-18 21:55:12127 return std::vector<blink::WebString>(
Blink Reformat1c4d759e2017-04-09 16:34:54128 1, blink::WebString::FromUTF8(params_->code));
[email protected]c11e6592014-06-27 17:07:34129}
130
131void ProgrammaticScriptInjector::OnInjectionComplete(
dchengf6f80662016-04-20 20:26:04132 std::unique_ptr<base::Value> execution_result,
rdevlin.cronind533be962015-10-02 17:01:18133 UserScript::RunLocation run_location,
134 content::RenderFrame* render_frame) {
rdevlin.cronin4bb32d72015-06-02 21:55:01135 DCHECK(results_.empty());
136 if (execution_result)
dchenge59eca1602015-12-18 17:48:00137 results_.Append(std::move(execution_result));
rdevlin.cronind533be962015-10-02 17:01:18138 Finish(std::string(), render_frame);
[email protected]c11e6592014-06-27 17:07:34139}
140
rdevlin.cronind533be962015-10-02 17:01:18141void ProgrammaticScriptInjector::OnWillNotInject(
142 InjectFailureReason reason,
143 content::RenderFrame* render_frame) {
[email protected]c11e6592014-06-27 17:07:34144 std::string error;
145 switch (reason) {
146 case NOT_ALLOWED:
rob52277c82016-02-07 17:28:57147 if (!CanShowUrlInError()) {
148 error = manifest_errors::kCannotAccessPage;
149 } else if (!origin_for_about_error_.empty()) {
roba9e6e6422015-03-30 21:14:02150 error = ErrorUtils::FormatErrorMessage(
151 manifest_errors::kCannotAccessAboutUrl, url_.spec(),
rob52277c82016-02-07 17:28:57152 origin_for_about_error_);
roba9e6e6422015-03-30 21:14:02153 } else {
rob52277c82016-02-07 17:28:57154 error = ErrorUtils::FormatErrorMessage(
155 manifest_errors::kCannotAccessPageWithUrl, url_.spec());
roba9e6e6422015-03-30 21:14:02156 }
[email protected]c11e6592014-06-27 17:07:34157 break;
158 case EXTENSION_REMOVED: // no special error here.
159 case WONT_INJECT:
160 break;
161 }
rdevlin.cronind533be962015-10-02 17:01:18162 Finish(error, render_frame);
[email protected]c11e6592014-06-27 17:07:34163}
164
rob52277c82016-02-07 17:28:57165bool ProgrammaticScriptInjector::CanShowUrlInError() const {
166 if (params_->host_id.type() != HostID::EXTENSIONS)
167 return false;
168 const Extension* extension =
169 RendererExtensionRegistry::Get()->GetByID(params_->host_id.id());
170 if (!extension)
171 return false;
172 return extension->permissions_data()->active_permissions().HasAPIPermission(
173 APIPermission::kTab);
174}
175
rdevlin.cronind533be962015-10-02 17:01:18176void ProgrammaticScriptInjector::Finish(const std::string& error,
177 content::RenderFrame* render_frame) {
[email protected]c11e6592014-06-27 17:07:34178 DCHECK(!finished_);
179 finished_ = true;
180
rdevlin.cronin3ae4a32012015-06-30 17:43:19181 // It's possible that the render frame was destroyed in the course of
182 // injecting scripts. Don't respond if it was (the browser side watches for
183 // frame deletions so nothing is left hanging).
rdevlin.cronind533be962015-10-02 17:01:18184 if (render_frame) {
185 render_frame->Send(
rdevlin.cronin3ae4a32012015-06-30 17:43:19186 new ExtensionHostMsg_ExecuteCodeFinished(
rdevlin.cronind533be962015-10-02 17:01:18187 render_frame->GetRoutingID(), params_->request_id,
rdevlin.cronin3ae4a32012015-06-30 17:43:19188 error, url_, results_));
189 }
[email protected]c11e6592014-06-27 17:07:34190}
191
192} // namespace extensions