| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 // show packaged apps and platform apps because there are some pieces of | 1229 // show packaged apps and platform apps because there are some pieces of |
| 1230 // functionality that are only available in chrome://extensions/ but which | 1230 // functionality that are only available in chrome://extensions/ but which |
| 1231 // are needed for packaged and platform apps. For example, inspecting | 1231 // are needed for packaged and platform apps. For example, inspecting |
| 1232 // background pages. See http://crbug.com/116134. | 1232 // background pages. See http://crbug.com/116134. |
| 1233 if (is_hosted_app()) | 1233 if (is_hosted_app()) |
| 1234 return false; | 1234 return false; |
| 1235 | 1235 |
| 1236 return true; | 1236 return true; |
| 1237 } | 1237 } |
| 1238 | 1238 |
| 1239 bool Extension::HasContentScriptAtURL(const GURL& url) const { | |
| 1240 for (UserScriptList::const_iterator it = content_scripts_.begin(); | |
| 1241 it != content_scripts_.end(); ++it) { | |
| 1242 if (it->MatchesURL(url)) | |
| 1243 return true; | |
| 1244 } | |
| 1245 return false; | |
| 1246 } | |
| 1247 | |
| 1248 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( | 1239 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( |
| 1249 int tab_id) const { | 1240 int tab_id) const { |
| 1250 base::AutoLock auto_lock(runtime_data_lock_); | 1241 base::AutoLock auto_lock(runtime_data_lock_); |
| 1251 return runtime_data_.GetTabSpecificPermissions(tab_id); | 1242 return runtime_data_.GetTabSpecificPermissions(tab_id); |
| 1252 } | 1243 } |
| 1253 | 1244 |
| 1254 void Extension::UpdateTabSpecificPermissions( | 1245 void Extension::UpdateTabSpecificPermissions( |
| 1255 int tab_id, | 1246 int tab_id, |
| 1256 scoped_refptr<const PermissionSet> permissions) const { | 1247 scoped_refptr<const PermissionSet> permissions) const { |
| 1257 base::AutoLock auto_lock(runtime_data_lock_); | 1248 base::AutoLock auto_lock(runtime_data_lock_); |
| (...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2760 | 2751 |
| 2761 bool Extension::LoadExtensionFeatures(APIPermissionSet* api_permissions, | 2752 bool Extension::LoadExtensionFeatures(APIPermissionSet* api_permissions, |
| 2762 string16* error) { | 2753 string16* error) { |
| 2763 if (manifest_->HasKey(keys::kConvertedFromUserScript)) | 2754 if (manifest_->HasKey(keys::kConvertedFromUserScript)) |
| 2764 manifest_->GetBoolean(keys::kConvertedFromUserScript, | 2755 manifest_->GetBoolean(keys::kConvertedFromUserScript, |
| 2765 &converted_from_user_script_); | 2756 &converted_from_user_script_); |
| 2766 | 2757 |
| 2767 if (!LoadManifestHandlerFeatures(error) || | 2758 if (!LoadManifestHandlerFeatures(error) || |
| 2768 !LoadDevToolsPage(error) || | 2759 !LoadDevToolsPage(error) || |
| 2769 !LoadInputComponents(*api_permissions, error) || | 2760 !LoadInputComponents(*api_permissions, error) || |
| 2770 !LoadContentScripts(error) || | |
| 2771 !LoadPageAction(error) || | 2761 !LoadPageAction(error) || |
| 2772 !LoadSystemIndicator(api_permissions, error) || | 2762 !LoadSystemIndicator(api_permissions, error) || |
| 2773 !LoadChromeURLOverrides(error) || | 2763 !LoadChromeURLOverrides(error) || |
| 2774 !LoadTextToSpeechVoices(error) || | 2764 !LoadTextToSpeechVoices(error) || |
| 2775 !LoadIncognitoMode(error) || | 2765 !LoadIncognitoMode(error) || |
| 2776 !LoadFileHandlers(error) || | 2766 !LoadFileHandlers(error) || |
| 2777 !LoadContentSecurityPolicy(error)) | 2767 !LoadContentSecurityPolicy(error)) |
| 2778 return false; | 2768 return false; |
| 2779 | 2769 |
| 2780 return true; | 2770 return true; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2932 input_components_.back().layouts.insert(layouts.begin(), layouts.end()); | 2922 input_components_.back().layouts.insert(layouts.begin(), layouts.end()); |
| 2933 input_components_.back().shortcut_keycode = shortcut_keycode_str; | 2923 input_components_.back().shortcut_keycode = shortcut_keycode_str; |
| 2934 input_components_.back().shortcut_alt = shortcut_alt; | 2924 input_components_.back().shortcut_alt = shortcut_alt; |
| 2935 input_components_.back().shortcut_ctrl = shortcut_ctrl; | 2925 input_components_.back().shortcut_ctrl = shortcut_ctrl; |
| 2936 input_components_.back().shortcut_shift = shortcut_shift; | 2926 input_components_.back().shortcut_shift = shortcut_shift; |
| 2937 } | 2927 } |
| 2938 | 2928 |
| 2939 return true; | 2929 return true; |
| 2940 } | 2930 } |
| 2941 | 2931 |
| 2942 bool Extension::LoadContentScripts(string16* error) { | |
| 2943 if (!manifest_->HasKey(keys::kContentScripts)) | |
| 2944 return true; | |
| 2945 ListValue* list_value; | |
| 2946 if (!manifest_->GetList(keys::kContentScripts, &list_value)) { | |
| 2947 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList); | |
| 2948 return false; | |
| 2949 } | |
| 2950 | |
| 2951 for (size_t i = 0; i < list_value->GetSize(); ++i) { | |
| 2952 DictionaryValue* content_script = NULL; | |
| 2953 if (!list_value->GetDictionary(i, &content_script)) { | |
| 2954 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2955 errors::kInvalidContentScript, base::IntToString(i)); | |
| 2956 return false; | |
| 2957 } | |
| 2958 | |
| 2959 UserScript script; | |
| 2960 if (!LoadUserScriptHelper(content_script, i, error, &script)) | |
| 2961 return false; // Failed to parse script context definition. | |
| 2962 script.set_extension_id(id()); | |
| 2963 if (converted_from_user_script_) { | |
| 2964 script.set_emulate_greasemonkey(true); | |
| 2965 script.set_match_all_frames(true); // Greasemonkey matches all frames. | |
| 2966 } | |
| 2967 content_scripts_.push_back(script); | |
| 2968 } | |
| 2969 return true; | |
| 2970 } | |
| 2971 | |
| 2972 bool Extension::LoadPageAction(string16* error) { | 2932 bool Extension::LoadPageAction(string16* error) { |
| 2973 DictionaryValue* page_action_value = NULL; | 2933 DictionaryValue* page_action_value = NULL; |
| 2974 | 2934 |
| 2975 if (manifest_->HasKey(keys::kPageActions)) { | 2935 if (manifest_->HasKey(keys::kPageActions)) { |
| 2976 ListValue* list_value = NULL; | 2936 ListValue* list_value = NULL; |
| 2977 if (!manifest_->GetList(keys::kPageActions, &list_value)) { | 2937 if (!manifest_->GetList(keys::kPageActions, &list_value)) { |
| 2978 *error = ASCIIToUTF16(errors::kInvalidPageActionsList); | 2938 *error = ASCIIToUTF16(errors::kInvalidPageActionsList); |
| 2979 return false; | 2939 return false; |
| 2980 } | 2940 } |
| 2981 | 2941 |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3357 const SkBitmap& image = i->second; | 3317 const SkBitmap& image = i->second; |
| 3358 if (image.width() <= max_size.width() && | 3318 if (image.width() <= max_size.width() && |
| 3359 image.height() <= max_size.height()) { | 3319 image.height() <= max_size.height()) { |
| 3360 return &(i->second); | 3320 return &(i->second); |
| 3361 } | 3321 } |
| 3362 } | 3322 } |
| 3363 | 3323 |
| 3364 return NULL; | 3324 return NULL; |
| 3365 } | 3325 } |
| 3366 | 3326 |
| 3367 // Helper method that loads a UserScript object from a dictionary in the | |
| 3368 // content_script list of the manifest. | |
| 3369 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, | |
| 3370 int definition_index, | |
| 3371 string16* error, | |
| 3372 UserScript* result) { | |
| 3373 // run_at | |
| 3374 if (content_script->HasKey(keys::kRunAt)) { | |
| 3375 std::string run_location; | |
| 3376 if (!content_script->GetString(keys::kRunAt, &run_location)) { | |
| 3377 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3378 errors::kInvalidRunAt, | |
| 3379 base::IntToString(definition_index)); | |
| 3380 return false; | |
| 3381 } | |
| 3382 | |
| 3383 if (run_location == values::kRunAtDocumentStart) { | |
| 3384 result->set_run_location(UserScript::DOCUMENT_START); | |
| 3385 } else if (run_location == values::kRunAtDocumentEnd) { | |
| 3386 result->set_run_location(UserScript::DOCUMENT_END); | |
| 3387 } else if (run_location == values::kRunAtDocumentIdle) { | |
| 3388 result->set_run_location(UserScript::DOCUMENT_IDLE); | |
| 3389 } else { | |
| 3390 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3391 errors::kInvalidRunAt, | |
| 3392 base::IntToString(definition_index)); | |
| 3393 return false; | |
| 3394 } | |
| 3395 } | |
| 3396 | |
| 3397 // all frames | |
| 3398 if (content_script->HasKey(keys::kAllFrames)) { | |
| 3399 bool all_frames = false; | |
| 3400 if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) { | |
| 3401 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3402 errors::kInvalidAllFrames, base::IntToString(definition_index)); | |
| 3403 return false; | |
| 3404 } | |
| 3405 result->set_match_all_frames(all_frames); | |
| 3406 } | |
| 3407 | |
| 3408 // matches (required) | |
| 3409 const ListValue* matches = NULL; | |
| 3410 if (!content_script->GetList(keys::kMatches, &matches)) { | |
| 3411 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3412 errors::kInvalidMatches, | |
| 3413 base::IntToString(definition_index)); | |
| 3414 return false; | |
| 3415 } | |
| 3416 | |
| 3417 if (matches->GetSize() == 0) { | |
| 3418 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3419 errors::kInvalidMatchCount, | |
| 3420 base::IntToString(definition_index)); | |
| 3421 return false; | |
| 3422 } | |
| 3423 for (size_t j = 0; j < matches->GetSize(); ++j) { | |
| 3424 std::string match_str; | |
| 3425 if (!matches->GetString(j, &match_str)) { | |
| 3426 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3427 errors::kInvalidMatch, | |
| 3428 base::IntToString(definition_index), | |
| 3429 base::IntToString(j), | |
| 3430 errors::kExpectString); | |
| 3431 return false; | |
| 3432 } | |
| 3433 | |
| 3434 URLPattern pattern(UserScript::kValidUserScriptSchemes); | |
| 3435 if (CanExecuteScriptEverywhere()) | |
| 3436 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 3437 | |
| 3438 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | |
| 3439 if (parse_result != URLPattern::PARSE_SUCCESS) { | |
| 3440 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3441 errors::kInvalidMatch, | |
| 3442 base::IntToString(definition_index), | |
| 3443 base::IntToString(j), | |
| 3444 URLPattern::GetParseResultString(parse_result)); | |
| 3445 return false; | |
| 3446 } | |
| 3447 | |
| 3448 if (pattern.MatchesScheme(chrome::kFileScheme) && | |
| 3449 !CanExecuteScriptEverywhere()) { | |
| 3450 wants_file_access_ = true; | |
| 3451 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | |
| 3452 pattern.SetValidSchemes( | |
| 3453 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | |
| 3454 } | |
| 3455 } | |
| 3456 | |
| 3457 result->add_url_pattern(pattern); | |
| 3458 } | |
| 3459 | |
| 3460 // exclude_matches | |
| 3461 if (content_script->HasKey(keys::kExcludeMatches)) { // optional | |
| 3462 const ListValue* exclude_matches = NULL; | |
| 3463 if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) { | |
| 3464 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3465 errors::kInvalidExcludeMatches, | |
| 3466 base::IntToString(definition_index)); | |
| 3467 return false; | |
| 3468 } | |
| 3469 | |
| 3470 for (size_t j = 0; j < exclude_matches->GetSize(); ++j) { | |
| 3471 std::string match_str; | |
| 3472 if (!exclude_matches->GetString(j, &match_str)) { | |
| 3473 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3474 errors::kInvalidExcludeMatch, | |
| 3475 base::IntToString(definition_index), | |
| 3476 base::IntToString(j), | |
| 3477 errors::kExpectString); | |
| 3478 return false; | |
| 3479 } | |
| 3480 | |
| 3481 URLPattern pattern(UserScript::kValidUserScriptSchemes); | |
| 3482 if (CanExecuteScriptEverywhere()) | |
| 3483 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 3484 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | |
| 3485 if (parse_result != URLPattern::PARSE_SUCCESS) { | |
| 3486 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3487 errors::kInvalidExcludeMatch, | |
| 3488 base::IntToString(definition_index), base::IntToString(j), | |
| 3489 URLPattern::GetParseResultString(parse_result)); | |
| 3490 return false; | |
| 3491 } | |
| 3492 | |
| 3493 result->add_exclude_url_pattern(pattern); | |
| 3494 } | |
| 3495 } | |
| 3496 | |
| 3497 // include/exclude globs (mostly for Greasemonkey compatibility) | |
| 3498 if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs, | |
| 3499 error, &UserScript::add_glob, result)) { | |
| 3500 return false; | |
| 3501 } | |
| 3502 | |
| 3503 if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs, | |
| 3504 error, &UserScript::add_exclude_glob, result)) { | |
| 3505 return false; | |
| 3506 } | |
| 3507 | |
| 3508 // js and css keys | |
| 3509 const ListValue* js = NULL; | |
| 3510 if (content_script->HasKey(keys::kJs) && | |
| 3511 !content_script->GetList(keys::kJs, &js)) { | |
| 3512 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3513 errors::kInvalidJsList, | |
| 3514 base::IntToString(definition_index)); | |
| 3515 return false; | |
| 3516 } | |
| 3517 | |
| 3518 const ListValue* css = NULL; | |
| 3519 if (content_script->HasKey(keys::kCss) && | |
| 3520 !content_script->GetList(keys::kCss, &css)) { | |
| 3521 *error = ErrorUtils:: | |
| 3522 FormatErrorMessageUTF16(errors::kInvalidCssList, | |
| 3523 base::IntToString(definition_index)); | |
| 3524 return false; | |
| 3525 } | |
| 3526 | |
| 3527 // The manifest needs to have at least one js or css user script definition. | |
| 3528 if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) { | |
| 3529 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3530 errors::kMissingFile, | |
| 3531 base::IntToString(definition_index)); | |
| 3532 return false; | |
| 3533 } | |
| 3534 | |
| 3535 if (js) { | |
| 3536 for (size_t script_index = 0; script_index < js->GetSize(); | |
| 3537 ++script_index) { | |
| 3538 const Value* value; | |
| 3539 std::string relative; | |
| 3540 if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) { | |
| 3541 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3542 errors::kInvalidJs, | |
| 3543 base::IntToString(definition_index), | |
| 3544 base::IntToString(script_index)); | |
| 3545 return false; | |
| 3546 } | |
| 3547 GURL url = GetResourceURL(relative); | |
| 3548 ExtensionResource resource = GetResource(relative); | |
| 3549 result->js_scripts().push_back(UserScript::File( | |
| 3550 resource.extension_root(), resource.relative_path(), url)); | |
| 3551 } | |
| 3552 } | |
| 3553 | |
| 3554 if (css) { | |
| 3555 for (size_t script_index = 0; script_index < css->GetSize(); | |
| 3556 ++script_index) { | |
| 3557 const Value* value; | |
| 3558 std::string relative; | |
| 3559 if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) { | |
| 3560 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3561 errors::kInvalidCss, | |
| 3562 base::IntToString(definition_index), | |
| 3563 base::IntToString(script_index)); | |
| 3564 return false; | |
| 3565 } | |
| 3566 GURL url = GetResourceURL(relative); | |
| 3567 ExtensionResource resource = GetResource(relative); | |
| 3568 result->css_scripts().push_back(UserScript::File( | |
| 3569 resource.extension_root(), resource.relative_path(), url)); | |
| 3570 } | |
| 3571 } | |
| 3572 | |
| 3573 return true; | |
| 3574 } | |
| 3575 | |
| 3576 bool Extension::LoadGlobsHelper( | |
| 3577 const DictionaryValue* content_script, | |
| 3578 int content_script_index, | |
| 3579 const char* globs_property_name, | |
| 3580 string16* error, | |
| 3581 void(UserScript::*add_method)(const std::string& glob), | |
| 3582 UserScript* instance) { | |
| 3583 if (!content_script->HasKey(globs_property_name)) | |
| 3584 return true; // they are optional | |
| 3585 | |
| 3586 const ListValue* list = NULL; | |
| 3587 if (!content_script->GetList(globs_property_name, &list)) { | |
| 3588 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3589 errors::kInvalidGlobList, | |
| 3590 base::IntToString(content_script_index), | |
| 3591 globs_property_name); | |
| 3592 return false; | |
| 3593 } | |
| 3594 | |
| 3595 for (size_t i = 0; i < list->GetSize(); ++i) { | |
| 3596 std::string glob; | |
| 3597 if (!list->GetString(i, &glob)) { | |
| 3598 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 3599 errors::kInvalidGlob, | |
| 3600 base::IntToString(content_script_index), | |
| 3601 globs_property_name, | |
| 3602 base::IntToString(i)); | |
| 3603 return false; | |
| 3604 } | |
| 3605 | |
| 3606 (instance->*add_method)(glob); | |
| 3607 } | |
| 3608 | |
| 3609 return true; | |
| 3610 } | |
| 3611 | |
| 3612 bool Extension::LoadOAuth2Info(string16* error) { | 3327 bool Extension::LoadOAuth2Info(string16* error) { |
| 3613 if (!manifest_->HasKey(keys::kOAuth2)) | 3328 if (!manifest_->HasKey(keys::kOAuth2)) |
| 3614 return true; | 3329 return true; |
| 3615 | 3330 |
| 3616 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || | 3331 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || |
| 3617 oauth2_info_.client_id.empty()) { | 3332 oauth2_info_.client_id.empty()) { |
| 3618 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); | 3333 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); |
| 3619 return false; | 3334 return false; |
| 3620 } | 3335 } |
| 3621 | 3336 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3821 | 3536 |
| 3822 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3537 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3823 const Extension* extension, | 3538 const Extension* extension, |
| 3824 const PermissionSet* permissions, | 3539 const PermissionSet* permissions, |
| 3825 Reason reason) | 3540 Reason reason) |
| 3826 : reason(reason), | 3541 : reason(reason), |
| 3827 extension(extension), | 3542 extension(extension), |
| 3828 permissions(permissions) {} | 3543 permissions(permissions) {} |
| 3829 | 3544 |
| 3830 } // namespace extensions | 3545 } // namespace extensions |
| OLD | NEW |