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

Side by Side Diff: extensions/browser/user_script_loader.cc

Issue 2227193002: Make UserScript non-copyable. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: uplaod with base 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/browser/user_script_loader.h" 5 #include "extensions/browser/user_script_loader.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 11 matching lines...) Expand all
22 #include "extensions/common/extension_messages.h" 22 #include "extensions/common/extension_messages.h"
23 23
24 using content::BrowserThread; 24 using content::BrowserThread;
25 using content::BrowserContext; 25 using content::BrowserContext;
26 26
27 namespace extensions { 27 namespace extensions {
28 28
29 namespace { 29 namespace {
30 30
31 #if DCHECK_IS_ON() 31 #if DCHECK_IS_ON()
32 bool AreScriptsUnique(const UserScriptList& scripts) { 32 bool AreScriptsUnique(const BrowserUserScriptList& scripts) {
33 std::set<int> script_ids; 33 std::set<int> script_ids;
34 for (const UserScript& script : scripts) { 34 for (const std::unique_ptr<BrowserUserScript>& script : scripts) {
35 if (script_ids.count(script.id())) 35 if (script_ids.count(script->id()))
36 return false; 36 return false;
37 script_ids.insert(script.id()); 37 script_ids.insert(script->id());
38 } 38 }
39 return true; 39 return true;
40 } 40 }
41 #endif // DCHECK_IS_ON() 41 #endif // DCHECK_IS_ON()
42 42
43 // Helper function to parse greasesmonkey headers 43 // Helper function to parse greasesmonkey headers
44 bool GetDeclarationValue(const base::StringPiece& line, 44 bool GetDeclarationValue(const base::StringPiece& line,
45 const base::StringPiece& prefix, 45 const base::StringPiece& prefix,
46 std::string* value) { 46 std::string* value) {
47 base::StringPiece::size_type index = line.find(prefix); 47 base::StringPiece::size_type index = line.find(prefix);
48 if (index == base::StringPiece::npos) 48 if (index == base::StringPiece::npos)
49 return false; 49 return false;
50 50
51 std::string temp(line.data() + index + prefix.length(), 51 std::string temp(line.data() + index + prefix.length(),
52 line.length() - index - prefix.length()); 52 line.length() - index - prefix.length());
53 53
54 if (temp.empty() || !base::IsUnicodeWhitespace(temp[0])) 54 if (temp.empty() || !base::IsUnicodeWhitespace(temp[0]))
55 return false; 55 return false;
56 56
57 base::TrimWhitespaceASCII(temp, base::TRIM_ALL, value); 57 base::TrimWhitespaceASCII(temp, base::TRIM_ALL, value);
58 return true; 58 return true;
59 } 59 }
60 60
61 } // namespace 61 } // namespace
62 62
63 // static 63 // static
64 bool UserScriptLoader::ParseMetadataHeader(const base::StringPiece& script_text, 64 bool UserScriptLoader::ParseMetadataHeader(const base::StringPiece& script_text,
65 UserScript* script) { 65 BrowserUserScript* script) {
66 // http://wiki.greasespot.net/Metadata_block 66 // http://wiki.greasespot.net/Metadata_block
67 base::StringPiece line; 67 base::StringPiece line;
68 size_t line_start = 0; 68 size_t line_start = 0;
69 size_t line_end = line_start; 69 size_t line_end = line_start;
70 bool in_metadata = false; 70 bool in_metadata = false;
71 71
72 static const base::StringPiece kUserScriptBegin("// ==UserScript=="); 72 static const base::StringPiece kUserScriptBegin("// ==UserScript==");
73 static const base::StringPiece kUserScriptEng("// ==/UserScript=="); 73 static const base::StringPiece kUserScriptEng("// ==/UserScript==");
74 static const base::StringPiece kNamespaceDeclaration("// @namespace"); 74 static const base::StringPiece kNamespaceDeclaration("// @namespace");
75 static const base::StringPiece kNameDeclaration("// @name"); 75 static const base::StringPiece kNameDeclaration("// @name");
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // If no patterns were specified, default to @include *. This is what 150 // If no patterns were specified, default to @include *. This is what
151 // Greasemonkey does. 151 // Greasemonkey does.
152 if (script->globs().empty() && script->url_patterns().is_empty()) 152 if (script->globs().empty() && script->url_patterns().is_empty())
153 script->add_glob("*"); 153 script->add_glob("*");
154 154
155 return true; 155 return true;
156 } 156 }
157 157
158 UserScriptLoader::UserScriptLoader(BrowserContext* browser_context, 158 UserScriptLoader::UserScriptLoader(BrowserContext* browser_context,
159 const HostID& host_id) 159 const HostID& host_id)
160 : user_scripts_(new UserScriptList()), 160 : user_scripts_(new BrowserUserScriptList()),
161 clear_scripts_(false), 161 clear_scripts_(false),
162 ready_(false), 162 ready_(false),
163 pending_load_(false), 163 pending_load_(false),
164 browser_context_(browser_context), 164 browser_context_(browser_context),
165 host_id_(host_id), 165 host_id_(host_id),
166 weak_factory_(this) { 166 weak_factory_(this) {
167 registrar_.Add(this, 167 registrar_.Add(this,
168 content::NOTIFICATION_RENDERER_PROCESS_CREATED, 168 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
169 content::NotificationService::AllBrowserContextsAndSources()); 169 content::NotificationService::AllBrowserContextsAndSources());
170 } 170 }
171 171
172 UserScriptLoader::~UserScriptLoader() { 172 UserScriptLoader::~UserScriptLoader() {
173 FOR_EACH_OBSERVER(Observer, observers_, OnUserScriptLoaderDestroyed(this)); 173 FOR_EACH_OBSERVER(Observer, observers_, OnUserScriptLoaderDestroyed(this));
174 } 174 }
175 175
176 void UserScriptLoader::AddScripts(const UserScriptList& scripts) { 176 void UserScriptLoader::AddScripts(BrowserUserScriptList& scripts) {
177 #if DCHECK_IS_ON() 177 #if DCHECK_IS_ON()
178 // |scripts| with non-unique IDs will work, but that would indicate we are 178 // |scripts| with non-unique IDs will work, but that would indicate we are
179 // doing something wrong somewhere, so DCHECK that. 179 // doing something wrong somewhere, so DCHECK that.
180 DCHECK(AreScriptsUnique(scripts)) 180 DCHECK(AreScriptsUnique(scripts))
181 << "AddScripts() expects scripts with unique IDs."; 181 << "AddScripts() expects scripts with unique IDs.";
182 #endif // DCHECK_IS_ON() 182 #endif // DCHECK_IS_ON()
183 for (const UserScript& user_script : scripts) { 183 for (std::unique_ptr<BrowserUserScript>& user_script : scripts) {
184 int id = user_script.id(); 184 int id = user_script->id();
185 removed_script_hosts_.erase(UserScriptIDPair(id)); 185 removed_script_hosts_.erase(UserScriptIDPair(id));
186 if (added_scripts_map_.count(id) == 0) 186 if (added_scripts_map_.count(id) == 0)
187 added_scripts_map_[id] = user_script; 187 added_scripts_map_[id] = std::move(user_script);
188 } 188 }
189 AttemptLoad(); 189 AttemptLoad();
190 } 190 }
191 191
192 void UserScriptLoader::AddScripts(const UserScriptList& scripts, 192 void UserScriptLoader::AddScripts(BrowserUserScriptList& scripts,
193 int render_process_id, 193 int render_process_id,
194 int render_view_id) { 194 int render_view_id) {
195 AddScripts(scripts); 195 AddScripts(scripts);
196 } 196 }
197 197
198 void UserScriptLoader::RemoveScripts( 198 void UserScriptLoader::RemoveScripts(
199 const std::set<UserScriptIDPair>& scripts) { 199 const std::set<UserScriptIDPair>& scripts) {
200 for (const UserScriptIDPair& id_pair : scripts) { 200 for (const UserScriptIDPair& id_pair : scripts) {
201 removed_script_hosts_.insert(UserScriptIDPair(id_pair.id, id_pair.host_id)); 201 removed_script_hosts_.insert(UserScriptIDPair(id_pair.id, id_pair.host_id));
202 // TODO(lazyboy): We shouldn't be trying to remove scripts that were never 202 // TODO(lazyboy): We shouldn't be trying to remove scripts that were never
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 251
252 void UserScriptLoader::StartLoad() { 252 void UserScriptLoader::StartLoad() {
253 DCHECK_CURRENTLY_ON(BrowserThread::UI); 253 DCHECK_CURRENTLY_ON(BrowserThread::UI);
254 DCHECK(!is_loading()); 254 DCHECK(!is_loading());
255 255
256 // If scripts were marked for clearing before adding and removing, then clear 256 // If scripts were marked for clearing before adding and removing, then clear
257 // them. 257 // them.
258 if (clear_scripts_) { 258 if (clear_scripts_) {
259 user_scripts_->clear(); 259 user_scripts_->clear();
260 } else { 260 } else {
261 for (UserScriptList::iterator it = user_scripts_->begin(); 261 for (BrowserUserScriptList::iterator it = user_scripts_->begin();
262 it != user_scripts_->end();) { 262 it != user_scripts_->end();) {
263 UserScriptIDPair id_pair(it->id()); 263 UserScriptIDPair id_pair(it->get()->id());
264 if (removed_script_hosts_.count(id_pair) > 0u) 264 if (removed_script_hosts_.count(id_pair) > 0u)
265 it = user_scripts_->erase(it); 265 it = user_scripts_->erase(it);
266 else 266 else
267 ++it; 267 ++it;
268 } 268 }
269 } 269 }
270 270
271 std::set<int> added_script_ids; 271 std::set<int> added_script_ids;
272 for (const auto& id_and_script : added_scripts_map_) 272 for (const auto& id_and_script : added_scripts_map_)
273 added_script_ids.insert(id_and_script.second.id()); 273 added_script_ids.insert(id_and_script.second->id());
274 274
275 // Expand |changed_hosts_| for OnScriptsLoaded, which will use it in 275 // Expand |changed_hosts_| for OnScriptsLoaded, which will use it in
276 // its IPC message. This must be done before we clear |added_scripts_map_| and 276 // its IPC message. This must be done before we clear |added_scripts_map_| and
277 // |removed_script_hosts_| below. 277 // |removed_script_hosts_| below.
278 for (const auto& id_and_script : added_scripts_map_) 278 for (const auto& id_and_script : added_scripts_map_)
279 changed_hosts_.insert(id_and_script.second.host_id()); 279 changed_hosts_.insert(id_and_script.second->host_id());
280 for (const UserScriptIDPair& id_pair : removed_script_hosts_) 280 for (const UserScriptIDPair& id_pair : removed_script_hosts_)
281 changed_hosts_.insert(id_pair.host_id); 281 changed_hosts_.insert(id_pair.host_id);
282 282
283 // Done with |added_scripts_map_|, now put them into |user_scripts_|. 283 // Done with |added_scripts_map_|, now put them into |user_scripts_|.
284 user_scripts_->reserve(user_scripts_->size() + added_scripts_map_.size()); 284 user_scripts_->reserve(user_scripts_->size() + added_scripts_map_.size());
285 for (int id : added_script_ids) 285 for (int id : added_script_ids)
286 user_scripts_->push_back(std::move(added_scripts_map_[id])); 286 user_scripts_->push_back(std::move(added_scripts_map_[id]));
287 287
288 LoadScripts(std::move(user_scripts_), changed_hosts_, added_script_ids, 288 LoadScripts(std::move(user_scripts_), changed_hosts_, added_script_ids,
289 base::Bind(&UserScriptLoader::OnScriptsLoaded, 289 base::Bind(&UserScriptLoader::OnScriptsLoaded,
290 weak_factory_.GetWeakPtr())); 290 weak_factory_.GetWeakPtr()));
291 291
292 clear_scripts_ = false; 292 clear_scripts_ = false;
293 added_scripts_map_.clear(); 293 added_scripts_map_.clear();
294 removed_script_hosts_.clear(); 294 removed_script_hosts_.clear();
295 user_scripts_.reset(); 295 user_scripts_.reset();
296 } 296 }
297 297
298 // static 298 // static
299 std::unique_ptr<base::SharedMemory> UserScriptLoader::Serialize( 299 std::unique_ptr<base::SharedMemory> UserScriptLoader::Serialize(
300 const UserScriptList& scripts) { 300 const BrowserUserScriptList& scripts) {
301 base::Pickle pickle; 301 base::Pickle pickle;
302 pickle.WriteUInt32(scripts.size()); 302 pickle.WriteUInt32(scripts.size());
303 for (const UserScript& script : scripts) { 303 for (const std::unique_ptr<BrowserUserScript>& script : scripts) {
304 // TODO(aa): This can be replaced by sending content script metadata to 304 // TODO(aa): This can be replaced by sending content script metadata to
305 // renderers along with other extension data in ExtensionMsg_Loaded. 305 // renderers along with other extension data in ExtensionMsg_Loaded.
306 // See crbug.com/70516. 306 // See crbug.com/70516.
307 script.Pickle(&pickle); 307 script->Pickle(&pickle);
308 // Write scripts as 'data' so that we can read it out in the slave without 308 // Write scripts as 'data' so that we can read it out in the slave without
309 // allocating a new string. 309 // allocating a new string.
310 for (const UserScript::File& script_file : script.js_scripts()) { 310 for (const std::unique_ptr<BrowserScriptFile>& script_file :
311 base::StringPiece contents = script_file.GetContent(); 311 script->js_scripts()) {
312 base::StringPiece contents = script_file->GetContent();
312 pickle.WriteData(contents.data(), contents.length()); 313 pickle.WriteData(contents.data(), contents.length());
313 } 314 }
314 for (const UserScript::File& script_file : script.css_scripts()) { 315 for (const std::unique_ptr<BrowserScriptFile>& script_file :
315 base::StringPiece contents = script_file.GetContent(); 316 script->css_scripts()) {
317 base::StringPiece contents = script_file->GetContent();
316 pickle.WriteData(contents.data(), contents.length()); 318 pickle.WriteData(contents.data(), contents.length());
317 } 319 }
318 } 320 }
319 321
320 // Create the shared memory object. 322 // Create the shared memory object.
321 base::SharedMemory shared_memory; 323 base::SharedMemory shared_memory;
322 324
323 base::SharedMemoryCreateOptions options; 325 base::SharedMemoryCreateOptions options;
324 options.size = pickle.size(); 326 options.size = pickle.size();
325 options.share_read_only = true; 327 options.share_read_only = true;
(...skipping 24 matching lines...) Expand all
350 } 352 }
351 353
352 void UserScriptLoader::SetReady(bool ready) { 354 void UserScriptLoader::SetReady(bool ready) {
353 bool was_ready = ready_; 355 bool was_ready = ready_;
354 ready_ = ready; 356 ready_ = ready;
355 if (ready_ && !was_ready) 357 if (ready_ && !was_ready)
356 AttemptLoad(); 358 AttemptLoad();
357 } 359 }
358 360
359 void UserScriptLoader::OnScriptsLoaded( 361 void UserScriptLoader::OnScriptsLoaded(
360 std::unique_ptr<UserScriptList> user_scripts, 362 std::unique_ptr<BrowserUserScriptList> user_scripts,
361 std::unique_ptr<base::SharedMemory> shared_memory) { 363 std::unique_ptr<base::SharedMemory> shared_memory) {
362 user_scripts_.reset(user_scripts.release()); 364 user_scripts_.reset(user_scripts.release());
363 if (pending_load_) { 365 if (pending_load_) {
364 // While we were loading, there were further changes. Don't bother 366 // While we were loading, there were further changes. Don't bother
365 // notifying about these scripts and instead just immediately reload. 367 // notifying about these scripts and instead just immediately reload.
366 pending_load_ = false; 368 pending_load_ = false;
367 StartLoad(); 369 StartLoad();
368 return; 370 return;
369 } 371 }
370 372
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) 422 if (!shared_memory->ShareToProcess(handle, &handle_for_process))
421 return; // This can legitimately fail if the renderer asserts at startup. 423 return; // This can legitimately fail if the renderer asserts at startup.
422 424
423 if (base::SharedMemory::IsHandleValid(handle_for_process)) { 425 if (base::SharedMemory::IsHandleValid(handle_for_process)) {
424 process->Send(new ExtensionMsg_UpdateUserScripts( 426 process->Send(new ExtensionMsg_UpdateUserScripts(
425 handle_for_process, host_id(), changed_hosts, whitelisted_only)); 427 handle_for_process, host_id(), changed_hosts, whitelisted_only));
426 } 428 }
427 } 429 }
428 430
429 } // namespace extensions 431 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698