Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Side by Side Diff: extensions/renderer/user_script_injector.cc

Issue 2213603002: Prevent duplicate content script injection defined in manifest.json (reland) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Initial fix to bug 631247 Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/user_script_injector.h" 5 #include "extensions/renderer/user_script_injector.h"
6 6
7 #include <tuple> 7 #include <tuple>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 131
132 bool UserScriptInjector::IsUserGesture() const { 132 bool UserScriptInjector::IsUserGesture() const {
133 return false; 133 return false;
134 } 134 }
135 135
136 bool UserScriptInjector::ExpectsResults() const { 136 bool UserScriptInjector::ExpectsResults() const {
137 return false; 137 return false;
138 } 138 }
139 139
140 bool UserScriptInjector::ShouldInjectJs( 140 bool UserScriptInjector::ShouldInjectJs(
141 UserScript::RunLocation run_location) const { 141 UserScript::RunLocation run_location,
142 ScriptsRunInfo* scripts_run_info) const {
142 return script_ && script_->run_location() == run_location && 143 return script_ && script_->run_location() == run_location &&
143 !script_->js_scripts().empty(); 144 !script_->js_scripts().empty() &&
145 !scripts_run_info->injected_scripts.empty();
Devlin 2016/08/03 23:34:44 Same comment as in programmatic script injector.
catmullings 2016/08/09 23:13:41 Done.
144 } 146 }
145 147
146 bool UserScriptInjector::ShouldInjectCss( 148 bool UserScriptInjector::ShouldInjectCss(
147 UserScript::RunLocation run_location) const { 149 UserScript::RunLocation run_location,
150 ScriptsRunInfo* scripts_run_info) const {
148 return script_ && run_location == UserScript::DOCUMENT_START && 151 return script_ && run_location == UserScript::DOCUMENT_START &&
149 !script_->css_scripts().empty(); 152 !script_->css_scripts().empty() &&
153 !scripts_run_info->injected_scripts.empty();
150 } 154 }
151 155
152 PermissionsData::AccessType UserScriptInjector::CanExecuteOnFrame( 156 PermissionsData::AccessType UserScriptInjector::CanExecuteOnFrame(
153 const InjectionHost* injection_host, 157 const InjectionHost* injection_host,
154 blink::WebLocalFrame* web_frame, 158 blink::WebLocalFrame* web_frame,
155 int tab_id) const { 159 int tab_id) const {
156 // There is no harm in allowing the injection when the script is gone, 160 // There is no harm in allowing the injection when the script is gone,
157 // because there is nothing to inject. 161 // because there is nothing to inject.
158 if (!script_) 162 if (!script_)
159 return PermissionsData::ACCESS_ALLOWED; 163 return PermissionsData::ACCESS_ALLOWED;
(...skipping 30 matching lines...) Expand all
190 web_frame, web_frame->document().url(), script_->match_about_blank()); 194 web_frame, web_frame->document().url(), script_->match_about_blank());
191 195
192 return injection_host->CanExecuteOnFrame( 196 return injection_host->CanExecuteOnFrame(
193 effective_document_url, 197 effective_document_url,
194 content::RenderFrame::FromWebFrame(web_frame), 198 content::RenderFrame::FromWebFrame(web_frame),
195 tab_id, 199 tab_id,
196 is_declarative_); 200 is_declarative_);
197 } 201 }
198 202
199 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( 203 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources(
200 UserScript::RunLocation run_location) const { 204 UserScript::RunLocation run_location,
205 ScriptsRunInfo* scripts_run_info) const {
206 DCHECK(script_ != NULL);
Devlin 2016/08/03 23:34:44 DCHECK(script_) is sufficient.
catmullings 2016/08/09 23:13:41 Done.
201 std::vector<blink::WebScriptSource> sources; 207 std::vector<blink::WebScriptSource> sources;
202 if (!script_)
203 return sources;
204 208
205 DCHECK_EQ(script_->run_location(), run_location); 209 DCHECK_EQ(script_->run_location(), run_location);
206 210
207 const UserScript::FileList& js_scripts = script_->js_scripts(); 211 const UserScript::FileList& js_scripts = script_->js_scripts();
208 212
209 for (UserScript::FileList::const_iterator iter = js_scripts.begin(); 213 for (UserScript::FileList::const_iterator iter = js_scripts.begin();
210 iter != js_scripts.end(); 214 iter != js_scripts.end();
211 ++iter) { 215 ++iter) {
216 const GURL& script_url = iter->url();
217 // Check if the script is already injected.
218 if (scripts_run_info->injected_scripts.count(script_url) != 0)
219 continue;
220
212 std::string content = iter->GetContent().as_string(); 221 std::string content = iter->GetContent().as_string();
213 222
214 // We add this dumb function wrapper for user scripts to emulate what 223 // We add this dumb function wrapper for user scripts to emulate what
215 // Greasemonkey does. 224 // Greasemonkey does.
216 if (script_->emulate_greasemonkey()) { 225 if (script_->emulate_greasemonkey()) {
217 content.insert(0, kUserScriptHead); 226 content.insert(0, kUserScriptHead);
218 content += kUserScriptTail; 227 content += kUserScriptTail;
219 } 228 }
220 sources.push_back(blink::WebScriptSource( 229 sources.push_back(blink::WebScriptSource(
221 blink::WebString::fromUTF8(content), iter->url())); 230 blink::WebString::fromUTF8(content), script_url));
231
232 scripts_run_info->injected_scripts.insert(script_url);
222 } 233 }
223 234
224 // Emulate Greasemonkey API for scripts that were converted to extension 235 // Emulate Greasemonkey API for scripts that were converted to extension
225 // user scripts. 236 // user scripts.
226 if (script_->emulate_greasemonkey()) 237 if (script_->emulate_greasemonkey())
227 sources.insert(sources.begin(), g_greasemonkey_api.Get().GetSource()); 238 sources.insert(sources.begin(), g_greasemonkey_api.Get().GetSource());
228 239
229 return sources; 240 return sources;
230 } 241 }
231 242
232 std::vector<std::string> UserScriptInjector::GetCssSources( 243 std::vector<std::string> UserScriptInjector::GetCssSources(
233 UserScript::RunLocation run_location) const { 244 UserScript::RunLocation run_location,
245 ScriptsRunInfo* scripts_run_info) const {
246 DCHECK(script_ != NULL);
234 DCHECK_EQ(UserScript::DOCUMENT_START, run_location); 247 DCHECK_EQ(UserScript::DOCUMENT_START, run_location);
235 248
236 std::vector<std::string> sources; 249 std::vector<std::string> sources;
237 if (!script_)
238 return sources;
239 250
240 const UserScript::FileList& css_scripts = script_->css_scripts(); 251 const UserScript::FileList& css_scripts = script_->css_scripts();
252
241 for (UserScript::FileList::const_iterator iter = css_scripts.begin(); 253 for (UserScript::FileList::const_iterator iter = css_scripts.begin();
242 iter != css_scripts.end(); 254 iter != css_scripts.end();
243 ++iter) { 255 ++iter) {
244 sources.push_back(iter->GetContent().as_string()); 256 const GURL& script_url = iter->url();
257 // Check if the stylesheet is already injected.
258 if (scripts_run_info->injected_scripts.find(script_url) ==
259 scripts_run_info->injected_scripts.end()) {
260 sources.push_back(iter->GetContent().as_string());
261
262 scripts_run_info->injected_scripts.insert(script_url);
263 }
245 } 264 }
246 return sources; 265 return sources;
247 } 266 }
248 267
249 void UserScriptInjector::GetRunInfo( 268 void UserScriptInjector::GetRunInfo(
250 ScriptsRunInfo* scripts_run_info, 269 ScriptsRunInfo* scripts_run_info,
251 UserScript::RunLocation run_location) const { 270 UserScript::RunLocation run_location) const {
252 if (!script_) 271 if (!script_)
catmullings 2016/08/03 23:31:22 Should this be removed as well and converted into
catmullings 2016/08/09 23:13:41 bump
Devlin 2016/08/10 19:23:27 Yep. :)
253 return; 272 return;
254 273
255 if (ShouldInjectJs(run_location)) { 274 if (ShouldInjectJs(run_location, scripts_run_info)) {
256 const UserScript::FileList& js_scripts = script_->js_scripts(); 275 const UserScript::FileList& js_scripts = script_->js_scripts();
257 scripts_run_info->num_js += js_scripts.size(); 276 scripts_run_info->num_js += js_scripts.size();
258 for (UserScript::FileList::const_iterator iter = js_scripts.begin(); 277 for (UserScript::FileList::const_iterator iter = js_scripts.begin();
259 iter != js_scripts.end(); 278 iter != js_scripts.end();
260 ++iter) { 279 ++iter) {
261 scripts_run_info->executing_scripts[host_id_.id()].insert( 280 scripts_run_info->executing_scripts[host_id_.id()].insert(
262 iter->url().path()); 281 iter->url().path());
263 } 282 }
264 } 283 }
265 284
266 if (ShouldInjectCss(run_location)) 285 if (ShouldInjectCss(run_location, scripts_run_info))
267 scripts_run_info->num_css += script_->css_scripts().size(); 286 scripts_run_info->num_css += script_->css_scripts().size();
268 } 287 }
269 288
270 void UserScriptInjector::OnInjectionComplete( 289 void UserScriptInjector::OnInjectionComplete(
271 std::unique_ptr<base::Value> execution_result, 290 std::unique_ptr<base::Value> execution_result,
272 UserScript::RunLocation run_location, 291 UserScript::RunLocation run_location,
273 content::RenderFrame* render_frame) {} 292 content::RenderFrame* render_frame) {}
274 293
275 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason, 294 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason,
276 content::RenderFrame* render_frame) { 295 content::RenderFrame* render_frame) {
277 } 296 }
278 297
279 } // namespace extensions 298 } // namespace extensions
OLDNEW
« extensions/renderer/script_injector.h ('K') | « extensions/renderer/user_script_injector.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698