| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chrome/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 // show packaged apps and platform apps because there are some pieces of | 996 // show packaged apps and platform apps because there are some pieces of |
| 997 // functionality that are only available in chrome://extensions/ but which | 997 // functionality that are only available in chrome://extensions/ but which |
| 998 // are needed for packaged and platform apps. For example, inspecting | 998 // are needed for packaged and platform apps. For example, inspecting |
| 999 // background pages. See http://crbug.com/116134. | 999 // background pages. See http://crbug.com/116134. |
| 1000 if (is_hosted_app()) | 1000 if (is_hosted_app()) |
| 1001 return false; | 1001 return false; |
| 1002 | 1002 |
| 1003 return true; | 1003 return true; |
| 1004 } | 1004 } |
| 1005 | 1005 |
| 1006 bool Extension::HasContentScriptAtURL(const GURL& url) const { | |
| 1007 for (UserScriptList::const_iterator it = content_scripts_.begin(); | |
| 1008 it != content_scripts_.end(); ++it) { | |
| 1009 if (it->MatchesURL(url)) | |
| 1010 return true; | |
| 1011 } | |
| 1012 return false; | |
| 1013 } | |
| 1014 | |
| 1015 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( | 1006 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( |
| 1016 int tab_id) const { | 1007 int tab_id) const { |
| 1017 base::AutoLock auto_lock(runtime_data_lock_); | 1008 base::AutoLock auto_lock(runtime_data_lock_); |
| 1018 return runtime_data_.GetTabSpecificPermissions(tab_id); | 1009 return runtime_data_.GetTabSpecificPermissions(tab_id); |
| 1019 } | 1010 } |
| 1020 | 1011 |
| 1021 void Extension::UpdateTabSpecificPermissions( | 1012 void Extension::UpdateTabSpecificPermissions( |
| 1022 int tab_id, | 1013 int tab_id, |
| 1023 scoped_refptr<const PermissionSet> permissions) const { | 1014 scoped_refptr<const PermissionSet> permissions) const { |
| 1024 base::AutoLock auto_lock(runtime_data_lock_); | 1015 base::AutoLock auto_lock(runtime_data_lock_); |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 return false; | 1935 return false; |
| 1945 } | 1936 } |
| 1946 return true; | 1937 return true; |
| 1947 } | 1938 } |
| 1948 | 1939 |
| 1949 bool Extension::LoadExtensionFeatures(string16* error) { | 1940 bool Extension::LoadExtensionFeatures(string16* error) { |
| 1950 if (manifest_->HasKey(keys::kConvertedFromUserScript)) | 1941 if (manifest_->HasKey(keys::kConvertedFromUserScript)) |
| 1951 manifest_->GetBoolean(keys::kConvertedFromUserScript, | 1942 manifest_->GetBoolean(keys::kConvertedFromUserScript, |
| 1952 &converted_from_user_script_); | 1943 &converted_from_user_script_); |
| 1953 | 1944 |
| 1954 if (!LoadContentScripts(error) || | 1945 if (!LoadSystemIndicator(error) || |
| 1955 !LoadSystemIndicator(error) || | |
| 1956 !LoadIncognitoMode(error)) | 1946 !LoadIncognitoMode(error)) |
| 1957 return false; | 1947 return false; |
| 1958 | 1948 |
| 1959 return true; | 1949 return true; |
| 1960 } | 1950 } |
| 1961 | 1951 |
| 1962 bool Extension::LoadContentScripts(string16* error) { | |
| 1963 if (!manifest_->HasKey(keys::kContentScripts)) | |
| 1964 return true; | |
| 1965 const ListValue* list_value; | |
| 1966 if (!manifest_->GetList(keys::kContentScripts, &list_value)) { | |
| 1967 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList); | |
| 1968 return false; | |
| 1969 } | |
| 1970 | |
| 1971 for (size_t i = 0; i < list_value->GetSize(); ++i) { | |
| 1972 const DictionaryValue* content_script = NULL; | |
| 1973 if (!list_value->GetDictionary(i, &content_script)) { | |
| 1974 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 1975 errors::kInvalidContentScript, base::IntToString(i)); | |
| 1976 return false; | |
| 1977 } | |
| 1978 | |
| 1979 UserScript script; | |
| 1980 if (!LoadUserScriptHelper(content_script, i, error, &script)) | |
| 1981 return false; // Failed to parse script context definition. | |
| 1982 script.set_extension_id(id()); | |
| 1983 if (converted_from_user_script_) { | |
| 1984 script.set_emulate_greasemonkey(true); | |
| 1985 script.set_match_all_frames(true); // Greasemonkey matches all frames. | |
| 1986 } | |
| 1987 content_scripts_.push_back(script); | |
| 1988 } | |
| 1989 return true; | |
| 1990 } | |
| 1991 | |
| 1992 bool Extension::LoadSystemIndicator(string16* error) { | 1952 bool Extension::LoadSystemIndicator(string16* error) { |
| 1993 if (!manifest_->HasKey(keys::kSystemIndicator)) { | 1953 if (!manifest_->HasKey(keys::kSystemIndicator)) { |
| 1994 // There was no manifest entry for the system indicator. | 1954 // There was no manifest entry for the system indicator. |
| 1995 return true; | 1955 return true; |
| 1996 } | 1956 } |
| 1997 | 1957 |
| 1998 const DictionaryValue* system_indicator_value = NULL; | 1958 const DictionaryValue* system_indicator_value = NULL; |
| 1999 if (!manifest_->GetDictionary(keys::kSystemIndicator, | 1959 if (!manifest_->GetDictionary(keys::kSystemIndicator, |
| 2000 &system_indicator_value)) { | 1960 &system_indicator_value)) { |
| 2001 *error = ASCIIToUTF16(errors::kInvalidSystemIndicator); | 1961 *error = ASCIIToUTF16(errors::kInvalidSystemIndicator); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2030 incognito_split_mode_ = false; | 1990 incognito_split_mode_ = false; |
| 2031 } else if (value == values::kIncognitoSplit) { | 1991 } else if (value == values::kIncognitoSplit) { |
| 2032 incognito_split_mode_ = true; | 1992 incognito_split_mode_ = true; |
| 2033 } else { | 1993 } else { |
| 2034 *error = ASCIIToUTF16(errors::kInvalidIncognitoBehavior); | 1994 *error = ASCIIToUTF16(errors::kInvalidIncognitoBehavior); |
| 2035 return false; | 1995 return false; |
| 2036 } | 1996 } |
| 2037 return true; | 1997 return true; |
| 2038 } | 1998 } |
| 2039 | 1999 |
| 2040 // Helper method that loads a UserScript object from a dictionary in the | |
| 2041 // content_script list of the manifest. | |
| 2042 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, | |
| 2043 int definition_index, | |
| 2044 string16* error, | |
| 2045 UserScript* result) { | |
| 2046 // run_at | |
| 2047 if (content_script->HasKey(keys::kRunAt)) { | |
| 2048 std::string run_location; | |
| 2049 if (!content_script->GetString(keys::kRunAt, &run_location)) { | |
| 2050 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2051 errors::kInvalidRunAt, | |
| 2052 base::IntToString(definition_index)); | |
| 2053 return false; | |
| 2054 } | |
| 2055 | |
| 2056 if (run_location == values::kRunAtDocumentStart) { | |
| 2057 result->set_run_location(UserScript::DOCUMENT_START); | |
| 2058 } else if (run_location == values::kRunAtDocumentEnd) { | |
| 2059 result->set_run_location(UserScript::DOCUMENT_END); | |
| 2060 } else if (run_location == values::kRunAtDocumentIdle) { | |
| 2061 result->set_run_location(UserScript::DOCUMENT_IDLE); | |
| 2062 } else { | |
| 2063 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2064 errors::kInvalidRunAt, | |
| 2065 base::IntToString(definition_index)); | |
| 2066 return false; | |
| 2067 } | |
| 2068 } | |
| 2069 | |
| 2070 // all frames | |
| 2071 if (content_script->HasKey(keys::kAllFrames)) { | |
| 2072 bool all_frames = false; | |
| 2073 if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) { | |
| 2074 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2075 errors::kInvalidAllFrames, base::IntToString(definition_index)); | |
| 2076 return false; | |
| 2077 } | |
| 2078 result->set_match_all_frames(all_frames); | |
| 2079 } | |
| 2080 | |
| 2081 // matches (required) | |
| 2082 const ListValue* matches = NULL; | |
| 2083 if (!content_script->GetList(keys::kMatches, &matches)) { | |
| 2084 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2085 errors::kInvalidMatches, | |
| 2086 base::IntToString(definition_index)); | |
| 2087 return false; | |
| 2088 } | |
| 2089 | |
| 2090 if (matches->GetSize() == 0) { | |
| 2091 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2092 errors::kInvalidMatchCount, | |
| 2093 base::IntToString(definition_index)); | |
| 2094 return false; | |
| 2095 } | |
| 2096 for (size_t j = 0; j < matches->GetSize(); ++j) { | |
| 2097 std::string match_str; | |
| 2098 if (!matches->GetString(j, &match_str)) { | |
| 2099 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2100 errors::kInvalidMatch, | |
| 2101 base::IntToString(definition_index), | |
| 2102 base::IntToString(j), | |
| 2103 errors::kExpectString); | |
| 2104 return false; | |
| 2105 } | |
| 2106 | |
| 2107 URLPattern pattern(UserScript::kValidUserScriptSchemes); | |
| 2108 if (CanExecuteScriptEverywhere()) | |
| 2109 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 2110 | |
| 2111 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | |
| 2112 if (parse_result != URLPattern::PARSE_SUCCESS) { | |
| 2113 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2114 errors::kInvalidMatch, | |
| 2115 base::IntToString(definition_index), | |
| 2116 base::IntToString(j), | |
| 2117 URLPattern::GetParseResultString(parse_result)); | |
| 2118 return false; | |
| 2119 } | |
| 2120 | |
| 2121 if (pattern.MatchesScheme(chrome::kFileScheme) && | |
| 2122 !CanExecuteScriptEverywhere()) { | |
| 2123 wants_file_access_ = true; | |
| 2124 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | |
| 2125 pattern.SetValidSchemes( | |
| 2126 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | |
| 2127 } | |
| 2128 } | |
| 2129 | |
| 2130 result->add_url_pattern(pattern); | |
| 2131 } | |
| 2132 | |
| 2133 // exclude_matches | |
| 2134 if (content_script->HasKey(keys::kExcludeMatches)) { // optional | |
| 2135 const ListValue* exclude_matches = NULL; | |
| 2136 if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) { | |
| 2137 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2138 errors::kInvalidExcludeMatches, | |
| 2139 base::IntToString(definition_index)); | |
| 2140 return false; | |
| 2141 } | |
| 2142 | |
| 2143 for (size_t j = 0; j < exclude_matches->GetSize(); ++j) { | |
| 2144 std::string match_str; | |
| 2145 if (!exclude_matches->GetString(j, &match_str)) { | |
| 2146 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2147 errors::kInvalidExcludeMatch, | |
| 2148 base::IntToString(definition_index), | |
| 2149 base::IntToString(j), | |
| 2150 errors::kExpectString); | |
| 2151 return false; | |
| 2152 } | |
| 2153 | |
| 2154 URLPattern pattern(UserScript::kValidUserScriptSchemes); | |
| 2155 if (CanExecuteScriptEverywhere()) | |
| 2156 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 2157 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | |
| 2158 if (parse_result != URLPattern::PARSE_SUCCESS) { | |
| 2159 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2160 errors::kInvalidExcludeMatch, | |
| 2161 base::IntToString(definition_index), base::IntToString(j), | |
| 2162 URLPattern::GetParseResultString(parse_result)); | |
| 2163 return false; | |
| 2164 } | |
| 2165 | |
| 2166 result->add_exclude_url_pattern(pattern); | |
| 2167 } | |
| 2168 } | |
| 2169 | |
| 2170 // include/exclude globs (mostly for Greasemonkey compatibility) | |
| 2171 if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs, | |
| 2172 error, &UserScript::add_glob, result)) { | |
| 2173 return false; | |
| 2174 } | |
| 2175 | |
| 2176 if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs, | |
| 2177 error, &UserScript::add_exclude_glob, result)) { | |
| 2178 return false; | |
| 2179 } | |
| 2180 | |
| 2181 // js and css keys | |
| 2182 const ListValue* js = NULL; | |
| 2183 if (content_script->HasKey(keys::kJs) && | |
| 2184 !content_script->GetList(keys::kJs, &js)) { | |
| 2185 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2186 errors::kInvalidJsList, | |
| 2187 base::IntToString(definition_index)); | |
| 2188 return false; | |
| 2189 } | |
| 2190 | |
| 2191 const ListValue* css = NULL; | |
| 2192 if (content_script->HasKey(keys::kCss) && | |
| 2193 !content_script->GetList(keys::kCss, &css)) { | |
| 2194 *error = ErrorUtils:: | |
| 2195 FormatErrorMessageUTF16(errors::kInvalidCssList, | |
| 2196 base::IntToString(definition_index)); | |
| 2197 return false; | |
| 2198 } | |
| 2199 | |
| 2200 // The manifest needs to have at least one js or css user script definition. | |
| 2201 if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) { | |
| 2202 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2203 errors::kMissingFile, | |
| 2204 base::IntToString(definition_index)); | |
| 2205 return false; | |
| 2206 } | |
| 2207 | |
| 2208 if (js) { | |
| 2209 for (size_t script_index = 0; script_index < js->GetSize(); | |
| 2210 ++script_index) { | |
| 2211 const Value* value; | |
| 2212 std::string relative; | |
| 2213 if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) { | |
| 2214 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2215 errors::kInvalidJs, | |
| 2216 base::IntToString(definition_index), | |
| 2217 base::IntToString(script_index)); | |
| 2218 return false; | |
| 2219 } | |
| 2220 GURL url = GetResourceURL(relative); | |
| 2221 ExtensionResource resource = GetResource(relative); | |
| 2222 result->js_scripts().push_back(UserScript::File( | |
| 2223 resource.extension_root(), resource.relative_path(), url)); | |
| 2224 } | |
| 2225 } | |
| 2226 | |
| 2227 if (css) { | |
| 2228 for (size_t script_index = 0; script_index < css->GetSize(); | |
| 2229 ++script_index) { | |
| 2230 const Value* value; | |
| 2231 std::string relative; | |
| 2232 if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) { | |
| 2233 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2234 errors::kInvalidCss, | |
| 2235 base::IntToString(definition_index), | |
| 2236 base::IntToString(script_index)); | |
| 2237 return false; | |
| 2238 } | |
| 2239 GURL url = GetResourceURL(relative); | |
| 2240 ExtensionResource resource = GetResource(relative); | |
| 2241 result->css_scripts().push_back(UserScript::File( | |
| 2242 resource.extension_root(), resource.relative_path(), url)); | |
| 2243 } | |
| 2244 } | |
| 2245 | |
| 2246 return true; | |
| 2247 } | |
| 2248 | |
| 2249 bool Extension::LoadGlobsHelper( | |
| 2250 const DictionaryValue* content_script, | |
| 2251 int content_script_index, | |
| 2252 const char* globs_property_name, | |
| 2253 string16* error, | |
| 2254 void(UserScript::*add_method)(const std::string& glob), | |
| 2255 UserScript* instance) { | |
| 2256 if (!content_script->HasKey(globs_property_name)) | |
| 2257 return true; // they are optional | |
| 2258 | |
| 2259 const ListValue* list = NULL; | |
| 2260 if (!content_script->GetList(globs_property_name, &list)) { | |
| 2261 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2262 errors::kInvalidGlobList, | |
| 2263 base::IntToString(content_script_index), | |
| 2264 globs_property_name); | |
| 2265 return false; | |
| 2266 } | |
| 2267 | |
| 2268 for (size_t i = 0; i < list->GetSize(); ++i) { | |
| 2269 std::string glob; | |
| 2270 if (!list->GetString(i, &glob)) { | |
| 2271 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2272 errors::kInvalidGlob, | |
| 2273 base::IntToString(content_script_index), | |
| 2274 globs_property_name, | |
| 2275 base::IntToString(i)); | |
| 2276 return false; | |
| 2277 } | |
| 2278 | |
| 2279 (instance->*add_method)(glob); | |
| 2280 } | |
| 2281 | |
| 2282 return true; | |
| 2283 } | |
| 2284 | |
| 2285 bool Extension::HasMultipleUISurfaces() const { | 2000 bool Extension::HasMultipleUISurfaces() const { |
| 2286 int num_surfaces = 0; | 2001 int num_surfaces = 0; |
| 2287 | 2002 |
| 2288 if (ActionInfo::GetPageActionInfo(this)) | 2003 if (ActionInfo::GetPageActionInfo(this)) |
| 2289 ++num_surfaces; | 2004 ++num_surfaces; |
| 2290 | 2005 |
| 2291 if (ActionInfo::GetBrowserActionInfo(this)) | 2006 if (ActionInfo::GetBrowserActionInfo(this)) |
| 2292 ++num_surfaces; | 2007 ++num_surfaces; |
| 2293 | 2008 |
| 2294 if (is_app()) | 2009 if (is_app()) |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2451 | 2166 |
| 2452 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 2167 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 2453 const Extension* extension, | 2168 const Extension* extension, |
| 2454 const PermissionSet* permissions, | 2169 const PermissionSet* permissions, |
| 2455 Reason reason) | 2170 Reason reason) |
| 2456 : reason(reason), | 2171 : reason(reason), |
| 2457 extension(extension), | 2172 extension(extension), |
| 2458 permissions(permissions) {} | 2173 permissions(permissions) {} |
| 2459 | 2174 |
| 2460 } // namespace extensions | 2175 } // namespace extensions |
| OLD | NEW |