| 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 <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 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 // show packaged apps and platform apps because there are some pieces of | 1188 // show packaged apps and platform apps because there are some pieces of |
| 1189 // functionality that are only available in chrome://extensions/ but which | 1189 // functionality that are only available in chrome://extensions/ but which |
| 1190 // are needed for packaged and platform apps. For example, inspecting | 1190 // are needed for packaged and platform apps. For example, inspecting |
| 1191 // background pages. See http://crbug.com/116134. | 1191 // background pages. See http://crbug.com/116134. |
| 1192 if (is_hosted_app()) | 1192 if (is_hosted_app()) |
| 1193 return false; | 1193 return false; |
| 1194 | 1194 |
| 1195 return true; | 1195 return true; |
| 1196 } | 1196 } |
| 1197 | 1197 |
| 1198 bool Extension::HasContentScriptAtURL(const GURL& url) const { | |
| 1199 for (UserScriptList::const_iterator it = content_scripts_.begin(); | |
| 1200 it != content_scripts_.end(); ++it) { | |
| 1201 if (it->MatchesURL(url)) | |
| 1202 return true; | |
| 1203 } | |
| 1204 return false; | |
| 1205 } | |
| 1206 | |
| 1207 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( | 1198 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( |
| 1208 int tab_id) const { | 1199 int tab_id) const { |
| 1209 base::AutoLock auto_lock(runtime_data_lock_); | 1200 base::AutoLock auto_lock(runtime_data_lock_); |
| 1210 return runtime_data_.GetTabSpecificPermissions(tab_id); | 1201 return runtime_data_.GetTabSpecificPermissions(tab_id); |
| 1211 } | 1202 } |
| 1212 | 1203 |
| 1213 void Extension::UpdateTabSpecificPermissions( | 1204 void Extension::UpdateTabSpecificPermissions( |
| 1214 int tab_id, | 1205 int tab_id, |
| 1215 scoped_refptr<const PermissionSet> permissions) const { | 1206 scoped_refptr<const PermissionSet> permissions) const { |
| 1216 base::AutoLock auto_lock(runtime_data_lock_); | 1207 base::AutoLock auto_lock(runtime_data_lock_); |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 return true; | 2363 return true; |
| 2373 } | 2364 } |
| 2374 | 2365 |
| 2375 bool Extension::LoadExtensionFeatures(APIPermissionSet* api_permissions, | 2366 bool Extension::LoadExtensionFeatures(APIPermissionSet* api_permissions, |
| 2376 string16* error) { | 2367 string16* error) { |
| 2377 if (manifest_->HasKey(keys::kConvertedFromUserScript)) | 2368 if (manifest_->HasKey(keys::kConvertedFromUserScript)) |
| 2378 manifest_->GetBoolean(keys::kConvertedFromUserScript, | 2369 manifest_->GetBoolean(keys::kConvertedFromUserScript, |
| 2379 &converted_from_user_script_); | 2370 &converted_from_user_script_); |
| 2380 | 2371 |
| 2381 if (!LoadManifestHandlerFeatures(error) || | 2372 if (!LoadManifestHandlerFeatures(error) || |
| 2382 !LoadContentScripts(error) || | |
| 2383 !LoadPageAction(error) || | 2373 !LoadPageAction(error) || |
| 2384 !LoadBrowserAction(error) || | 2374 !LoadBrowserAction(error) || |
| 2385 !LoadSystemIndicator(api_permissions, error) || | 2375 !LoadSystemIndicator(api_permissions, error) || |
| 2386 !LoadIncognitoMode(error) || | 2376 !LoadIncognitoMode(error) || |
| 2387 !LoadContentSecurityPolicy(error)) | 2377 !LoadContentSecurityPolicy(error)) |
| 2388 return false; | 2378 return false; |
| 2389 | 2379 |
| 2390 return true; | 2380 return true; |
| 2391 } | 2381 } |
| 2392 | 2382 |
| 2393 bool Extension::LoadManifestHandlerFeatures(string16* error) { | 2383 bool Extension::LoadManifestHandlerFeatures(string16* error) { |
| 2394 std::vector<std::string> keys = ManifestHandler::GetKeys(); | 2384 std::vector<std::string> keys = ManifestHandler::GetKeys(); |
| 2395 for (size_t i = 0; i < keys.size(); ++i) { | 2385 for (size_t i = 0; i < keys.size(); ++i) { |
| 2396 Value* value = NULL; | 2386 Value* value = NULL; |
| 2397 if (!manifest_->Get(keys[i], &value)) { | 2387 if (!manifest_->Get(keys[i], &value)) { |
| 2398 if (!ManifestHandler::Get(keys[i])->HasNoKey(this, error)) | 2388 if (!ManifestHandler::Get(keys[i])->HasNoKey(this, error)) |
| 2399 return false; | 2389 return false; |
| 2400 } else if (!ManifestHandler::Get(keys[i])->Parse(value, this, error)) { | 2390 } else if (!ManifestHandler::Get(keys[i])->Parse(value, this, error)) { |
| 2401 return false; | 2391 return false; |
| 2402 } | 2392 } |
| 2403 } | 2393 } |
| 2404 return true; | 2394 return true; |
| 2405 } | 2395 } |
| 2406 | 2396 |
| 2407 bool Extension::LoadContentScripts(string16* error) { | |
| 2408 if (!manifest_->HasKey(keys::kContentScripts)) | |
| 2409 return true; | |
| 2410 ListValue* list_value; | |
| 2411 if (!manifest_->GetList(keys::kContentScripts, &list_value)) { | |
| 2412 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList); | |
| 2413 return false; | |
| 2414 } | |
| 2415 | |
| 2416 for (size_t i = 0; i < list_value->GetSize(); ++i) { | |
| 2417 DictionaryValue* content_script = NULL; | |
| 2418 if (!list_value->GetDictionary(i, &content_script)) { | |
| 2419 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2420 errors::kInvalidContentScript, base::IntToString(i)); | |
| 2421 return false; | |
| 2422 } | |
| 2423 | |
| 2424 UserScript script; | |
| 2425 if (!LoadUserScriptHelper(content_script, i, error, &script)) | |
| 2426 return false; // Failed to parse script context definition. | |
| 2427 script.set_extension_id(id()); | |
| 2428 if (converted_from_user_script_) { | |
| 2429 script.set_emulate_greasemonkey(true); | |
| 2430 script.set_match_all_frames(true); // Greasemonkey matches all frames. | |
| 2431 } | |
| 2432 content_scripts_.push_back(script); | |
| 2433 } | |
| 2434 return true; | |
| 2435 } | |
| 2436 | |
| 2437 bool Extension::LoadPageAction(string16* error) { | 2397 bool Extension::LoadPageAction(string16* error) { |
| 2438 DictionaryValue* page_action_value = NULL; | 2398 DictionaryValue* page_action_value = NULL; |
| 2439 | 2399 |
| 2440 if (manifest_->HasKey(keys::kPageActions)) { | 2400 if (manifest_->HasKey(keys::kPageActions)) { |
| 2441 ListValue* list_value = NULL; | 2401 ListValue* list_value = NULL; |
| 2442 if (!manifest_->GetList(keys::kPageActions, &list_value)) { | 2402 if (!manifest_->GetList(keys::kPageActions, &list_value)) { |
| 2443 *error = ASCIIToUTF16(errors::kInvalidPageActionsList); | 2403 *error = ASCIIToUTF16(errors::kInvalidPageActionsList); |
| 2444 return false; | 2404 return false; |
| 2445 } | 2405 } |
| 2446 | 2406 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2694 const SkBitmap& image = i->second; | 2654 const SkBitmap& image = i->second; |
| 2695 if (image.width() <= max_size.width() && | 2655 if (image.width() <= max_size.width() && |
| 2696 image.height() <= max_size.height()) { | 2656 image.height() <= max_size.height()) { |
| 2697 return &(i->second); | 2657 return &(i->second); |
| 2698 } | 2658 } |
| 2699 } | 2659 } |
| 2700 | 2660 |
| 2701 return NULL; | 2661 return NULL; |
| 2702 } | 2662 } |
| 2703 | 2663 |
| 2704 // Helper method that loads a UserScript object from a dictionary in the | |
| 2705 // content_script list of the manifest. | |
| 2706 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, | |
| 2707 int definition_index, | |
| 2708 string16* error, | |
| 2709 UserScript* result) { | |
| 2710 // run_at | |
| 2711 if (content_script->HasKey(keys::kRunAt)) { | |
| 2712 std::string run_location; | |
| 2713 if (!content_script->GetString(keys::kRunAt, &run_location)) { | |
| 2714 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2715 errors::kInvalidRunAt, | |
| 2716 base::IntToString(definition_index)); | |
| 2717 return false; | |
| 2718 } | |
| 2719 | |
| 2720 if (run_location == values::kRunAtDocumentStart) { | |
| 2721 result->set_run_location(UserScript::DOCUMENT_START); | |
| 2722 } else if (run_location == values::kRunAtDocumentEnd) { | |
| 2723 result->set_run_location(UserScript::DOCUMENT_END); | |
| 2724 } else if (run_location == values::kRunAtDocumentIdle) { | |
| 2725 result->set_run_location(UserScript::DOCUMENT_IDLE); | |
| 2726 } else { | |
| 2727 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2728 errors::kInvalidRunAt, | |
| 2729 base::IntToString(definition_index)); | |
| 2730 return false; | |
| 2731 } | |
| 2732 } | |
| 2733 | |
| 2734 // all frames | |
| 2735 if (content_script->HasKey(keys::kAllFrames)) { | |
| 2736 bool all_frames = false; | |
| 2737 if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) { | |
| 2738 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2739 errors::kInvalidAllFrames, base::IntToString(definition_index)); | |
| 2740 return false; | |
| 2741 } | |
| 2742 result->set_match_all_frames(all_frames); | |
| 2743 } | |
| 2744 | |
| 2745 // matches (required) | |
| 2746 const ListValue* matches = NULL; | |
| 2747 if (!content_script->GetList(keys::kMatches, &matches)) { | |
| 2748 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2749 errors::kInvalidMatches, | |
| 2750 base::IntToString(definition_index)); | |
| 2751 return false; | |
| 2752 } | |
| 2753 | |
| 2754 if (matches->GetSize() == 0) { | |
| 2755 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2756 errors::kInvalidMatchCount, | |
| 2757 base::IntToString(definition_index)); | |
| 2758 return false; | |
| 2759 } | |
| 2760 for (size_t j = 0; j < matches->GetSize(); ++j) { | |
| 2761 std::string match_str; | |
| 2762 if (!matches->GetString(j, &match_str)) { | |
| 2763 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2764 errors::kInvalidMatch, | |
| 2765 base::IntToString(definition_index), | |
| 2766 base::IntToString(j), | |
| 2767 errors::kExpectString); | |
| 2768 return false; | |
| 2769 } | |
| 2770 | |
| 2771 URLPattern pattern(UserScript::kValidUserScriptSchemes); | |
| 2772 if (CanExecuteScriptEverywhere()) | |
| 2773 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 2774 | |
| 2775 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | |
| 2776 if (parse_result != URLPattern::PARSE_SUCCESS) { | |
| 2777 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2778 errors::kInvalidMatch, | |
| 2779 base::IntToString(definition_index), | |
| 2780 base::IntToString(j), | |
| 2781 URLPattern::GetParseResultString(parse_result)); | |
| 2782 return false; | |
| 2783 } | |
| 2784 | |
| 2785 if (pattern.MatchesScheme(chrome::kFileScheme) && | |
| 2786 !CanExecuteScriptEverywhere()) { | |
| 2787 wants_file_access_ = true; | |
| 2788 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | |
| 2789 pattern.SetValidSchemes( | |
| 2790 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | |
| 2791 } | |
| 2792 } | |
| 2793 | |
| 2794 result->add_url_pattern(pattern); | |
| 2795 } | |
| 2796 | |
| 2797 // exclude_matches | |
| 2798 if (content_script->HasKey(keys::kExcludeMatches)) { // optional | |
| 2799 const ListValue* exclude_matches = NULL; | |
| 2800 if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) { | |
| 2801 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2802 errors::kInvalidExcludeMatches, | |
| 2803 base::IntToString(definition_index)); | |
| 2804 return false; | |
| 2805 } | |
| 2806 | |
| 2807 for (size_t j = 0; j < exclude_matches->GetSize(); ++j) { | |
| 2808 std::string match_str; | |
| 2809 if (!exclude_matches->GetString(j, &match_str)) { | |
| 2810 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2811 errors::kInvalidExcludeMatch, | |
| 2812 base::IntToString(definition_index), | |
| 2813 base::IntToString(j), | |
| 2814 errors::kExpectString); | |
| 2815 return false; | |
| 2816 } | |
| 2817 | |
| 2818 URLPattern pattern(UserScript::kValidUserScriptSchemes); | |
| 2819 if (CanExecuteScriptEverywhere()) | |
| 2820 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 2821 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | |
| 2822 if (parse_result != URLPattern::PARSE_SUCCESS) { | |
| 2823 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2824 errors::kInvalidExcludeMatch, | |
| 2825 base::IntToString(definition_index), base::IntToString(j), | |
| 2826 URLPattern::GetParseResultString(parse_result)); | |
| 2827 return false; | |
| 2828 } | |
| 2829 | |
| 2830 result->add_exclude_url_pattern(pattern); | |
| 2831 } | |
| 2832 } | |
| 2833 | |
| 2834 // include/exclude globs (mostly for Greasemonkey compatibility) | |
| 2835 if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs, | |
| 2836 error, &UserScript::add_glob, result)) { | |
| 2837 return false; | |
| 2838 } | |
| 2839 | |
| 2840 if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs, | |
| 2841 error, &UserScript::add_exclude_glob, result)) { | |
| 2842 return false; | |
| 2843 } | |
| 2844 | |
| 2845 // js and css keys | |
| 2846 const ListValue* js = NULL; | |
| 2847 if (content_script->HasKey(keys::kJs) && | |
| 2848 !content_script->GetList(keys::kJs, &js)) { | |
| 2849 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2850 errors::kInvalidJsList, | |
| 2851 base::IntToString(definition_index)); | |
| 2852 return false; | |
| 2853 } | |
| 2854 | |
| 2855 const ListValue* css = NULL; | |
| 2856 if (content_script->HasKey(keys::kCss) && | |
| 2857 !content_script->GetList(keys::kCss, &css)) { | |
| 2858 *error = ErrorUtils:: | |
| 2859 FormatErrorMessageUTF16(errors::kInvalidCssList, | |
| 2860 base::IntToString(definition_index)); | |
| 2861 return false; | |
| 2862 } | |
| 2863 | |
| 2864 // The manifest needs to have at least one js or css user script definition. | |
| 2865 if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) { | |
| 2866 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2867 errors::kMissingFile, | |
| 2868 base::IntToString(definition_index)); | |
| 2869 return false; | |
| 2870 } | |
| 2871 | |
| 2872 if (js) { | |
| 2873 for (size_t script_index = 0; script_index < js->GetSize(); | |
| 2874 ++script_index) { | |
| 2875 const Value* value; | |
| 2876 std::string relative; | |
| 2877 if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) { | |
| 2878 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2879 errors::kInvalidJs, | |
| 2880 base::IntToString(definition_index), | |
| 2881 base::IntToString(script_index)); | |
| 2882 return false; | |
| 2883 } | |
| 2884 GURL url = GetResourceURL(relative); | |
| 2885 ExtensionResource resource = GetResource(relative); | |
| 2886 result->js_scripts().push_back(UserScript::File( | |
| 2887 resource.extension_root(), resource.relative_path(), url)); | |
| 2888 } | |
| 2889 } | |
| 2890 | |
| 2891 if (css) { | |
| 2892 for (size_t script_index = 0; script_index < css->GetSize(); | |
| 2893 ++script_index) { | |
| 2894 const Value* value; | |
| 2895 std::string relative; | |
| 2896 if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) { | |
| 2897 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2898 errors::kInvalidCss, | |
| 2899 base::IntToString(definition_index), | |
| 2900 base::IntToString(script_index)); | |
| 2901 return false; | |
| 2902 } | |
| 2903 GURL url = GetResourceURL(relative); | |
| 2904 ExtensionResource resource = GetResource(relative); | |
| 2905 result->css_scripts().push_back(UserScript::File( | |
| 2906 resource.extension_root(), resource.relative_path(), url)); | |
| 2907 } | |
| 2908 } | |
| 2909 | |
| 2910 return true; | |
| 2911 } | |
| 2912 | |
| 2913 bool Extension::LoadGlobsHelper( | |
| 2914 const DictionaryValue* content_script, | |
| 2915 int content_script_index, | |
| 2916 const char* globs_property_name, | |
| 2917 string16* error, | |
| 2918 void(UserScript::*add_method)(const std::string& glob), | |
| 2919 UserScript* instance) { | |
| 2920 if (!content_script->HasKey(globs_property_name)) | |
| 2921 return true; // they are optional | |
| 2922 | |
| 2923 const ListValue* list = NULL; | |
| 2924 if (!content_script->GetList(globs_property_name, &list)) { | |
| 2925 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2926 errors::kInvalidGlobList, | |
| 2927 base::IntToString(content_script_index), | |
| 2928 globs_property_name); | |
| 2929 return false; | |
| 2930 } | |
| 2931 | |
| 2932 for (size_t i = 0; i < list->GetSize(); ++i) { | |
| 2933 std::string glob; | |
| 2934 if (!list->GetString(i, &glob)) { | |
| 2935 *error = ErrorUtils::FormatErrorMessageUTF16( | |
| 2936 errors::kInvalidGlob, | |
| 2937 base::IntToString(content_script_index), | |
| 2938 globs_property_name, | |
| 2939 base::IntToString(i)); | |
| 2940 return false; | |
| 2941 } | |
| 2942 | |
| 2943 (instance->*add_method)(glob); | |
| 2944 } | |
| 2945 | |
| 2946 return true; | |
| 2947 } | |
| 2948 | |
| 2949 bool Extension::LoadOAuth2Info(string16* error) { | 2664 bool Extension::LoadOAuth2Info(string16* error) { |
| 2950 if (!manifest_->HasKey(keys::kOAuth2)) | 2665 if (!manifest_->HasKey(keys::kOAuth2)) |
| 2951 return true; | 2666 return true; |
| 2952 | 2667 |
| 2953 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || | 2668 if (!manifest_->GetString(keys::kOAuth2ClientId, &oauth2_info_.client_id) || |
| 2954 oauth2_info_.client_id.empty()) { | 2669 oauth2_info_.client_id.empty()) { |
| 2955 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); | 2670 *error = ASCIIToUTF16(errors::kInvalidOAuth2ClientId); |
| 2956 return false; | 2671 return false; |
| 2957 } | 2672 } |
| 2958 | 2673 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3158 | 2873 |
| 3159 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 2874 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3160 const Extension* extension, | 2875 const Extension* extension, |
| 3161 const PermissionSet* permissions, | 2876 const PermissionSet* permissions, |
| 3162 Reason reason) | 2877 Reason reason) |
| 3163 : reason(reason), | 2878 : reason(reason), |
| 3164 extension(extension), | 2879 extension(extension), |
| 3165 permissions(permissions) {} | 2880 permissions(permissions) {} |
| 3166 | 2881 |
| 3167 } // namespace extensions | 2882 } // namespace extensions |
| OLD | NEW |