| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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/command_line.h" | |
| 8 #include "base/pickle.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "chrome/common/chrome_switches.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 bool UrlMatchesGlobs(const std::vector<std::string>* globs, | |
| 15 const GURL& url) { | |
| 16 for (std::vector<std::string>::const_iterator glob = globs->begin(); | |
| 17 glob != globs->end(); ++glob) { | |
| 18 if (MatchPattern(url.spec(), *glob)) | |
| 19 return true; | |
| 20 } | |
| 21 | |
| 22 return false; | |
| 23 } | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 27 namespace extensions { | |
| 28 | |
| 29 // The bitmask for valid user script injectable schemes used by URLPattern. | |
| 30 enum { | |
| 31 kValidUserScriptSchemes = URLPattern::SCHEME_CHROMEUI | | |
| 32 URLPattern::SCHEME_HTTP | | |
| 33 URLPattern::SCHEME_HTTPS | | |
| 34 URLPattern::SCHEME_FILE | | |
| 35 URLPattern::SCHEME_FTP | |
| 36 }; | |
| 37 | |
| 38 // static | |
| 39 const char UserScript::kFileExtension[] = ".user.js"; | |
| 40 | |
| 41 bool UserScript::IsURLUserScript(const GURL& url, | |
| 42 const std::string& mime_type) { | |
| 43 return EndsWith(url.ExtractFileName(), kFileExtension, false) && | |
| 44 mime_type != "text/html"; | |
| 45 } | |
| 46 | |
| 47 // static | |
| 48 int UserScript::ValidUserScriptSchemes(bool canExecuteScriptEverywhere) { | |
| 49 if (canExecuteScriptEverywhere) | |
| 50 return URLPattern::SCHEME_ALL; | |
| 51 int valid_schemes = kValidUserScriptSchemes; | |
| 52 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 53 switches::kExtensionsOnChromeURLs)) { | |
| 54 valid_schemes &= ~URLPattern::SCHEME_CHROMEUI; | |
| 55 } | |
| 56 return valid_schemes; | |
| 57 } | |
| 58 | |
| 59 UserScript::File::File(const base::FilePath& extension_root, | |
| 60 const base::FilePath& relative_path, | |
| 61 const GURL& url) | |
| 62 : extension_root_(extension_root), | |
| 63 relative_path_(relative_path), | |
| 64 url_(url) { | |
| 65 } | |
| 66 | |
| 67 UserScript::File::File() {} | |
| 68 | |
| 69 UserScript::File::~File() {} | |
| 70 | |
| 71 UserScript::UserScript() | |
| 72 : run_location_(DOCUMENT_IDLE), emulate_greasemonkey_(false), | |
| 73 match_all_frames_(false), incognito_enabled_(false) { | |
| 74 } | |
| 75 | |
| 76 UserScript::~UserScript() { | |
| 77 } | |
| 78 | |
| 79 void UserScript::add_url_pattern(const URLPattern& pattern) { | |
| 80 url_set_.AddPattern(pattern); | |
| 81 } | |
| 82 | |
| 83 void UserScript::add_exclude_url_pattern(const URLPattern& pattern) { | |
| 84 exclude_url_set_.AddPattern(pattern); | |
| 85 } | |
| 86 | |
| 87 bool UserScript::MatchesURL(const GURL& url) const { | |
| 88 if (!url_set_.is_empty()) { | |
| 89 if (!url_set_.MatchesURL(url)) | |
| 90 return false; | |
| 91 } | |
| 92 | |
| 93 if (!exclude_url_set_.is_empty()) { | |
| 94 if (exclude_url_set_.MatchesURL(url)) | |
| 95 return false; | |
| 96 } | |
| 97 | |
| 98 if (!globs_.empty()) { | |
| 99 if (!UrlMatchesGlobs(&globs_, url)) | |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 if (!exclude_globs_.empty()) { | |
| 104 if (UrlMatchesGlobs(&exclude_globs_, url)) | |
| 105 return false; | |
| 106 } | |
| 107 | |
| 108 return true; | |
| 109 } | |
| 110 | |
| 111 void UserScript::File::Pickle(::Pickle* pickle) const { | |
| 112 pickle->WriteString(url_.spec()); | |
| 113 // Do not write path. It's not needed in the renderer. | |
| 114 // Do not write content. It will be serialized by other means. | |
| 115 } | |
| 116 | |
| 117 void UserScript::File::Unpickle(const ::Pickle& pickle, PickleIterator* iter) { | |
| 118 // Read the url from the pickle. | |
| 119 std::string url; | |
| 120 CHECK(pickle.ReadString(iter, &url)); | |
| 121 set_url(GURL(url)); | |
| 122 } | |
| 123 | |
| 124 void UserScript::Pickle(::Pickle* pickle) const { | |
| 125 // Write the simple types to the pickle. | |
| 126 pickle->WriteInt(run_location()); | |
| 127 pickle->WriteString(extension_id()); | |
| 128 pickle->WriteBool(emulate_greasemonkey()); | |
| 129 pickle->WriteBool(match_all_frames()); | |
| 130 pickle->WriteBool(is_incognito_enabled()); | |
| 131 | |
| 132 PickleGlobs(pickle, globs_); | |
| 133 PickleGlobs(pickle, exclude_globs_); | |
| 134 PickleURLPatternSet(pickle, url_set_); | |
| 135 PickleURLPatternSet(pickle, exclude_url_set_); | |
| 136 PickleScripts(pickle, js_scripts_); | |
| 137 PickleScripts(pickle, css_scripts_); | |
| 138 } | |
| 139 | |
| 140 void UserScript::PickleGlobs(::Pickle* pickle, | |
| 141 const std::vector<std::string>& globs) const { | |
| 142 pickle->WriteUInt64(globs.size()); | |
| 143 for (std::vector<std::string>::const_iterator glob = globs.begin(); | |
| 144 glob != globs.end(); ++glob) { | |
| 145 pickle->WriteString(*glob); | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 void UserScript::PickleURLPatternSet(::Pickle* pickle, | |
| 150 const URLPatternSet& pattern_list) const { | |
| 151 pickle->WriteUInt64(pattern_list.patterns().size()); | |
| 152 for (URLPatternSet::const_iterator pattern = pattern_list.begin(); | |
| 153 pattern != pattern_list.end(); ++pattern) { | |
| 154 pickle->WriteInt(pattern->valid_schemes()); | |
| 155 pickle->WriteString(pattern->GetAsString()); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 void UserScript::PickleScripts(::Pickle* pickle, | |
| 160 const FileList& scripts) const { | |
| 161 pickle->WriteUInt64(scripts.size()); | |
| 162 for (FileList::const_iterator file = scripts.begin(); | |
| 163 file != scripts.end(); ++file) { | |
| 164 file->Pickle(pickle); | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 void UserScript::Unpickle(const ::Pickle& pickle, PickleIterator* iter) { | |
| 169 // Read the run location. | |
| 170 int run_location = 0; | |
| 171 CHECK(pickle.ReadInt(iter, &run_location)); | |
| 172 CHECK(run_location >= 0 && run_location < RUN_LOCATION_LAST); | |
| 173 run_location_ = static_cast<RunLocation>(run_location); | |
| 174 | |
| 175 CHECK(pickle.ReadString(iter, &extension_id_)); | |
| 176 CHECK(pickle.ReadBool(iter, &emulate_greasemonkey_)); | |
| 177 CHECK(pickle.ReadBool(iter, &match_all_frames_)); | |
| 178 CHECK(pickle.ReadBool(iter, &incognito_enabled_)); | |
| 179 | |
| 180 UnpickleGlobs(pickle, iter, &globs_); | |
| 181 UnpickleGlobs(pickle, iter, &exclude_globs_); | |
| 182 UnpickleURLPatternSet(pickle, iter, &url_set_); | |
| 183 UnpickleURLPatternSet(pickle, iter, &exclude_url_set_); | |
| 184 UnpickleScripts(pickle, iter, &js_scripts_); | |
| 185 UnpickleScripts(pickle, iter, &css_scripts_); | |
| 186 } | |
| 187 | |
| 188 void UserScript::UnpickleGlobs(const ::Pickle& pickle, PickleIterator* iter, | |
| 189 std::vector<std::string>* globs) { | |
| 190 uint64 num_globs = 0; | |
| 191 CHECK(pickle.ReadUInt64(iter, &num_globs)); | |
| 192 globs->clear(); | |
| 193 for (uint64 i = 0; i < num_globs; ++i) { | |
| 194 std::string glob; | |
| 195 CHECK(pickle.ReadString(iter, &glob)); | |
| 196 globs->push_back(glob); | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 void UserScript::UnpickleURLPatternSet(const ::Pickle& pickle, | |
| 201 PickleIterator* iter, | |
| 202 URLPatternSet* pattern_list) { | |
| 203 uint64 num_patterns = 0; | |
| 204 CHECK(pickle.ReadUInt64(iter, &num_patterns)); | |
| 205 | |
| 206 pattern_list->ClearPatterns(); | |
| 207 for (uint64 i = 0; i < num_patterns; ++i) { | |
| 208 int valid_schemes; | |
| 209 CHECK(pickle.ReadInt(iter, &valid_schemes)); | |
| 210 | |
| 211 std::string pattern_str; | |
| 212 CHECK(pickle.ReadString(iter, &pattern_str)); | |
| 213 | |
| 214 URLPattern pattern(kValidUserScriptSchemes); | |
| 215 URLPattern::ParseResult result = pattern.Parse(pattern_str); | |
| 216 CHECK(URLPattern::PARSE_SUCCESS == result) << | |
| 217 URLPattern::GetParseResultString(result) << " " << pattern_str.c_str(); | |
| 218 | |
| 219 pattern.SetValidSchemes(valid_schemes); | |
| 220 pattern_list->AddPattern(pattern); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 void UserScript::UnpickleScripts(const ::Pickle& pickle, PickleIterator* iter, | |
| 225 FileList* scripts) { | |
| 226 uint64 num_files = 0; | |
| 227 CHECK(pickle.ReadUInt64(iter, &num_files)); | |
| 228 scripts->clear(); | |
| 229 for (uint64 i = 0; i < num_files; ++i) { | |
| 230 File file; | |
| 231 file.Unpickle(pickle, iter); | |
| 232 scripts->push_back(file); | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 } // namespace extensions | |
| OLD | NEW |