| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/renderer/programmatic_script_injector.h" | 5 #include "extensions/renderer/programmatic_script_injector.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "content/public/common/url_constants.h" | 11 #include "content/public/common/url_constants.h" |
| 12 #include "content/public/renderer/render_frame.h" | 12 #include "content/public/renderer/render_frame.h" |
| 13 #include "extensions/common/error_utils.h" | 13 #include "extensions/common/error_utils.h" |
| 14 #include "extensions/common/extension_messages.h" | 14 #include "extensions/common/extension_messages.h" |
| 15 #include "extensions/common/manifest_constants.h" | 15 #include "extensions/common/manifest_constants.h" |
| 16 #include "extensions/common/permissions/api_permission.h" |
| 16 #include "extensions/common/permissions/permissions_data.h" | 17 #include "extensions/common/permissions/permissions_data.h" |
| 17 #include "extensions/renderer/injection_host.h" | 18 #include "extensions/renderer/injection_host.h" |
| 19 #include "extensions/renderer/renderer_extension_registry.h" |
| 18 #include "extensions/renderer/script_context.h" | 20 #include "extensions/renderer/script_context.h" |
| 19 #include "third_party/WebKit/public/platform/WebString.h" | 21 #include "third_party/WebKit/public/platform/WebString.h" |
| 20 #include "third_party/WebKit/public/web/WebDocument.h" | 22 #include "third_party/WebKit/public/web/WebDocument.h" |
| 21 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 23 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 22 #include "third_party/WebKit/public/web/WebScriptSource.h" | 24 #include "third_party/WebKit/public/web/WebScriptSource.h" |
| 23 #include "url/origin.h" | |
| 24 | 25 |
| 25 namespace extensions { | 26 namespace extensions { |
| 26 | 27 |
| 27 ProgrammaticScriptInjector::ProgrammaticScriptInjector( | 28 ProgrammaticScriptInjector::ProgrammaticScriptInjector( |
| 28 const ExtensionMsg_ExecuteCode_Params& params, | 29 const ExtensionMsg_ExecuteCode_Params& params, |
| 29 content::RenderFrame* render_frame) | 30 content::RenderFrame* render_frame) |
| 30 : params_(new ExtensionMsg_ExecuteCode_Params(params)), | 31 : params_(new ExtensionMsg_ExecuteCode_Params(params)), |
| 31 url_( | 32 url_( |
| 32 ScriptContext::GetDataSourceURLForFrame(render_frame->GetWebFrame())), | 33 ScriptContext::GetDataSourceURLForFrame(render_frame->GetWebFrame())), |
| 33 finished_(false) { | 34 finished_(false) { |
| 34 effective_url_ = ScriptContext::GetEffectiveDocumentURL( | 35 if (url_.SchemeIs(url::kAboutScheme)) { |
| 35 render_frame->GetWebFrame(), url_, params.match_about_blank); | 36 origin_for_about_error_ = |
| 37 render_frame->GetWebFrame()->securityOrigin().toString().utf8(); |
| 38 } |
| 36 } | 39 } |
| 37 | 40 |
| 38 ProgrammaticScriptInjector::~ProgrammaticScriptInjector() { | 41 ProgrammaticScriptInjector::~ProgrammaticScriptInjector() { |
| 39 } | 42 } |
| 40 | 43 |
| 41 UserScript::InjectionType ProgrammaticScriptInjector::script_type() | 44 UserScript::InjectionType ProgrammaticScriptInjector::script_type() |
| 42 const { | 45 const { |
| 43 return UserScript::PROGRAMMATIC_SCRIPT; | 46 return UserScript::PROGRAMMATIC_SCRIPT; |
| 44 } | 47 } |
| 45 | 48 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 results_.Append(std::move(execution_result)); | 126 results_.Append(std::move(execution_result)); |
| 124 Finish(std::string(), render_frame); | 127 Finish(std::string(), render_frame); |
| 125 } | 128 } |
| 126 | 129 |
| 127 void ProgrammaticScriptInjector::OnWillNotInject( | 130 void ProgrammaticScriptInjector::OnWillNotInject( |
| 128 InjectFailureReason reason, | 131 InjectFailureReason reason, |
| 129 content::RenderFrame* render_frame) { | 132 content::RenderFrame* render_frame) { |
| 130 std::string error; | 133 std::string error; |
| 131 switch (reason) { | 134 switch (reason) { |
| 132 case NOT_ALLOWED: | 135 case NOT_ALLOWED: |
| 133 if (url_.SchemeIs(url::kAboutScheme)) { | 136 if (!CanShowUrlInError()) { |
| 137 error = manifest_errors::kCannotAccessPage; |
| 138 } else if (!origin_for_about_error_.empty()) { |
| 134 error = ErrorUtils::FormatErrorMessage( | 139 error = ErrorUtils::FormatErrorMessage( |
| 135 manifest_errors::kCannotAccessAboutUrl, url_.spec(), | 140 manifest_errors::kCannotAccessAboutUrl, url_.spec(), |
| 136 url::Origin(effective_url_).Serialize()); | 141 origin_for_about_error_); |
| 137 } else { | 142 } else { |
| 138 // TODO(?) It would be nice to show kCannotAccessPageWithUrl here if | 143 error = ErrorUtils::FormatErrorMessage( |
| 139 // this is triggered by an extension with tabs permission. See | 144 manifest_errors::kCannotAccessPageWithUrl, url_.spec()); |
| 140 // https://codereview.chromium.org/1414223005/diff/1/extensions/ | |
| 141 // common/manifest_constants.cc#newcode269 | |
| 142 error = manifest_errors::kCannotAccessPage; | |
| 143 } | 145 } |
| 144 break; | 146 break; |
| 145 case EXTENSION_REMOVED: // no special error here. | 147 case EXTENSION_REMOVED: // no special error here. |
| 146 case WONT_INJECT: | 148 case WONT_INJECT: |
| 147 break; | 149 break; |
| 148 } | 150 } |
| 149 Finish(error, render_frame); | 151 Finish(error, render_frame); |
| 150 } | 152 } |
| 151 | 153 |
| 154 bool ProgrammaticScriptInjector::CanShowUrlInError() const { |
| 155 if (params_->host_id.type() != HostID::EXTENSIONS) |
| 156 return false; |
| 157 const Extension* extension = |
| 158 RendererExtensionRegistry::Get()->GetByID(params_->host_id.id()); |
| 159 if (!extension) |
| 160 return false; |
| 161 return extension->permissions_data()->active_permissions().HasAPIPermission( |
| 162 APIPermission::kTab); |
| 163 } |
| 164 |
| 152 UserScript::RunLocation ProgrammaticScriptInjector::GetRunLocation() const { | 165 UserScript::RunLocation ProgrammaticScriptInjector::GetRunLocation() const { |
| 153 return static_cast<UserScript::RunLocation>(params_->run_at); | 166 return static_cast<UserScript::RunLocation>(params_->run_at); |
| 154 } | 167 } |
| 155 | 168 |
| 156 void ProgrammaticScriptInjector::Finish(const std::string& error, | 169 void ProgrammaticScriptInjector::Finish(const std::string& error, |
| 157 content::RenderFrame* render_frame) { | 170 content::RenderFrame* render_frame) { |
| 158 DCHECK(!finished_); | 171 DCHECK(!finished_); |
| 159 finished_ = true; | 172 finished_ = true; |
| 160 | 173 |
| 161 // It's possible that the render frame was destroyed in the course of | 174 // It's possible that the render frame was destroyed in the course of |
| 162 // injecting scripts. Don't respond if it was (the browser side watches for | 175 // injecting scripts. Don't respond if it was (the browser side watches for |
| 163 // frame deletions so nothing is left hanging). | 176 // frame deletions so nothing is left hanging). |
| 164 if (render_frame) { | 177 if (render_frame) { |
| 165 render_frame->Send( | 178 render_frame->Send( |
| 166 new ExtensionHostMsg_ExecuteCodeFinished( | 179 new ExtensionHostMsg_ExecuteCodeFinished( |
| 167 render_frame->GetRoutingID(), params_->request_id, | 180 render_frame->GetRoutingID(), params_->request_id, |
| 168 error, url_, results_)); | 181 error, url_, results_)); |
| 169 } | 182 } |
| 170 } | 183 } |
| 171 | 184 |
| 172 } // namespace extensions | 185 } // namespace extensions |
| OLD | NEW |