• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/common/extensions/user_script.h"
6 
7 #include "base/pickle.h"
8 #include "base/string_util.h"
9 
10 namespace {
11 
UrlMatchesPatterns(const UserScript::PatternList * patterns,const GURL & url)12 bool UrlMatchesPatterns(const UserScript::PatternList* patterns,
13                         const GURL& url) {
14   for (UserScript::PatternList::const_iterator pattern = patterns->begin();
15        pattern != patterns->end(); ++pattern) {
16     if (pattern->MatchesUrl(url))
17       return true;
18   }
19 
20   return false;
21 }
22 
UrlMatchesGlobs(const std::vector<std::string> * globs,const GURL & url)23 bool UrlMatchesGlobs(const std::vector<std::string>* globs,
24                      const GURL& url) {
25   for (std::vector<std::string>::const_iterator glob = globs->begin();
26        glob != globs->end(); ++glob) {
27     if (MatchPattern(url.spec(), *glob))
28       return true;
29   }
30 
31   return false;
32 }
33 
34 }  // namespace
35 
36 // static
37 const char UserScript::kFileExtension[] = ".user.js";
38 
39 // static
40 const int UserScript::kValidUserScriptSchemes =
41     URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS |
42     URLPattern::SCHEME_FILE | URLPattern::SCHEME_FTP;
43 
IsURLUserScript(const GURL & url,const std::string & mime_type)44 bool UserScript::IsURLUserScript(const GURL& url,
45                                  const std::string& mime_type) {
46   return EndsWith(url.ExtractFileName(), kFileExtension, false) &&
47       mime_type != "text/html";
48 }
49 
File(const FilePath & extension_root,const FilePath & relative_path,const GURL & url)50 UserScript::File::File(const FilePath& extension_root,
51                        const FilePath& relative_path,
52                        const GURL& url)
53     : extension_root_(extension_root),
54       relative_path_(relative_path),
55       url_(url) {
56 }
57 
File()58 UserScript::File::File() {}
59 
~File()60 UserScript::File::~File() {}
61 
UserScript()62 UserScript::UserScript()
63     : run_location_(DOCUMENT_IDLE), emulate_greasemonkey_(false),
64       match_all_frames_(false), incognito_enabled_(false) {
65 }
66 
~UserScript()67 UserScript::~UserScript() {
68 }
69 
add_url_pattern(const URLPattern & pattern)70 void UserScript::add_url_pattern(const URLPattern& pattern) {
71   url_patterns_.push_back(pattern);
72 }
73 
MatchesUrl(const GURL & url) const74 bool UserScript::MatchesUrl(const GURL& url) const {
75   if (!url_patterns_.empty()) {
76     if (!UrlMatchesPatterns(&url_patterns_, url))
77       return false;
78   }
79 
80   if (!globs_.empty()) {
81     if (!UrlMatchesGlobs(&globs_, url))
82       return false;
83   }
84 
85   if (!exclude_globs_.empty()) {
86     if (UrlMatchesGlobs(&exclude_globs_, url))
87       return false;
88   }
89 
90   return true;
91 }
92 
Pickle(::Pickle * pickle) const93 void UserScript::File::Pickle(::Pickle* pickle) const {
94   pickle->WriteString(url_.spec());
95   // Do not write path. It's not needed in the renderer.
96   // Do not write content. It will be serialized by other means.
97 }
98 
Unpickle(const::Pickle & pickle,void ** iter)99 void UserScript::File::Unpickle(const ::Pickle& pickle, void** iter) {
100   // Read url.
101   std::string url;
102   CHECK(pickle.ReadString(iter, &url));
103   set_url(GURL(url));
104 }
105 
Pickle(::Pickle * pickle) const106 void UserScript::Pickle(::Pickle* pickle) const {
107   // Write simple types.
108   pickle->WriteInt(run_location());
109   pickle->WriteString(extension_id());
110   pickle->WriteBool(emulate_greasemonkey());
111   pickle->WriteBool(match_all_frames());
112   pickle->WriteBool(is_incognito_enabled());
113 
114   // Write globs.
115   std::vector<std::string>::const_iterator glob;
116   pickle->WriteSize(globs_.size());
117   for (glob = globs_.begin(); glob != globs_.end(); ++glob) {
118     pickle->WriteString(*glob);
119   }
120   pickle->WriteSize(exclude_globs_.size());
121   for (glob = exclude_globs_.begin(); glob != exclude_globs_.end(); ++glob) {
122     pickle->WriteString(*glob);
123   }
124 
125   // Write url patterns.
126   pickle->WriteSize(url_patterns_.size());
127   for (PatternList::const_iterator pattern = url_patterns_.begin();
128        pattern != url_patterns_.end(); ++pattern) {
129     pickle->WriteInt(pattern->valid_schemes());
130     pickle->WriteString(pattern->GetAsString());
131   }
132 
133   // Write js scripts.
134   pickle->WriteSize(js_scripts_.size());
135   for (FileList::const_iterator file = js_scripts_.begin();
136     file != js_scripts_.end(); ++file) {
137     file->Pickle(pickle);
138   }
139 
140   // Write css scripts.
141   pickle->WriteSize(css_scripts_.size());
142   for (FileList::const_iterator file = css_scripts_.begin();
143     file != css_scripts_.end(); ++file) {
144     file->Pickle(pickle);
145   }
146 }
147 
Unpickle(const::Pickle & pickle,void ** iter)148 void UserScript::Unpickle(const ::Pickle& pickle, void** iter) {
149   // Read the run location.
150   int run_location = 0;
151   CHECK(pickle.ReadInt(iter, &run_location));
152   CHECK(run_location >= 0 && run_location < RUN_LOCATION_LAST);
153   run_location_ = static_cast<RunLocation>(run_location);
154 
155   CHECK(pickle.ReadString(iter, &extension_id_));
156   CHECK(pickle.ReadBool(iter, &emulate_greasemonkey_));
157   CHECK(pickle.ReadBool(iter, &match_all_frames_));
158   CHECK(pickle.ReadBool(iter, &incognito_enabled_));
159 
160   // Read globs.
161   size_t num_globs = 0;
162   CHECK(pickle.ReadSize(iter, &num_globs));
163   globs_.clear();
164   for (size_t i = 0; i < num_globs; ++i) {
165     std::string glob;
166     CHECK(pickle.ReadString(iter, &glob));
167     globs_.push_back(glob);
168   }
169 
170   CHECK(pickle.ReadSize(iter, &num_globs));
171   exclude_globs_.clear();
172   for (size_t i = 0; i < num_globs; ++i) {
173     std::string glob;
174     CHECK(pickle.ReadString(iter, &glob));
175     exclude_globs_.push_back(glob);
176   }
177 
178   // Read url patterns.
179   size_t num_patterns = 0;
180   CHECK(pickle.ReadSize(iter, &num_patterns));
181 
182   url_patterns_.clear();
183   for (size_t i = 0; i < num_patterns; ++i) {
184     int valid_schemes;
185     CHECK(pickle.ReadInt(iter, &valid_schemes));
186     std::string pattern_str;
187     URLPattern pattern(valid_schemes);
188     CHECK(pickle.ReadString(iter, &pattern_str));
189 
190     // We remove the file scheme if it's not actually allowed (see Extension::
191     // LoadUserScriptHelper), but we need it temporarily while loading the
192     // pattern so that it's valid.
193     bool had_file_scheme = (valid_schemes & URLPattern::SCHEME_FILE) != 0;
194     if (!had_file_scheme)
195       pattern.set_valid_schemes(valid_schemes | URLPattern::SCHEME_FILE);
196     CHECK(URLPattern::PARSE_SUCCESS ==
197           pattern.Parse(pattern_str, URLPattern::PARSE_LENIENT));
198     if (!had_file_scheme)
199       pattern.set_valid_schemes(valid_schemes);
200 
201     url_patterns_.push_back(pattern);
202   }
203 
204   // Read js scripts.
205   size_t num_js_files = 0;
206   CHECK(pickle.ReadSize(iter, &num_js_files));
207   js_scripts_.clear();
208   for (size_t i = 0; i < num_js_files; ++i) {
209     File file;
210     file.Unpickle(pickle, iter);
211     js_scripts_.push_back(file);
212   }
213 
214   // Read css scripts.
215   size_t num_css_files = 0;
216   CHECK(pickle.ReadSize(iter, &num_css_files));
217   css_scripts_.clear();
218   for (size_t i = 0; i < num_css_files; ++i) {
219     File file;
220     file.Unpickle(pickle, iter);
221     css_scripts_.push_back(file);
222   }
223 }
224