| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "app/resource_bundle.h" | 7 #include "app/resource_bundle.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_path.h" | 10 #include "base/file_path.h" |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 if (!theme_key_mapped) { | 460 if (!theme_key_mapped) { |
| 461 for (size_t i = 0; i < arraysize(kValidThemeKeys); ++i) { | 461 for (size_t i = 0; i < arraysize(kValidThemeKeys); ++i) { |
| 462 theme_keys[kValidThemeKeys[i]] = true; | 462 theme_keys[kValidThemeKeys[i]] = true; |
| 463 } | 463 } |
| 464 theme_key_mapped = true; | 464 theme_key_mapped = true; |
| 465 } | 465 } |
| 466 | 466 |
| 467 // Go through all the root level keys and verify that they're in the map | 467 // Go through all the root level keys and verify that they're in the map |
| 468 // of keys allowable by themes. If they're not, then make a not of it for | 468 // of keys allowable by themes. If they're not, then make a not of it for |
| 469 // later. | 469 // later. |
| 470 DictionaryValue::key_iterator iter = source.begin_keys(); | 470 for (DictionaryValue::key_iterator iter = source.begin_keys(); |
| 471 while (iter != source.end_keys()) { | 471 iter != source.end_keys(); ++iter) { |
| 472 std::wstring key = (*iter); | 472 if (theme_keys.find(*iter) == theme_keys.end()) |
| 473 if (theme_keys.find(key) == theme_keys.end()) | |
| 474 return true; | 473 return true; |
| 475 ++iter; | |
| 476 } | 474 } |
| 477 return false; | 475 return false; |
| 478 } | 476 } |
| 479 | 477 |
| 480 // static | 478 // static |
| 481 ExtensionResource Extension::GetResource(const FilePath& extension_path, | 479 ExtensionResource Extension::GetResource(const FilePath& extension_path, |
| 482 const std::string& relative_path) { | 480 const std::string& relative_path) { |
| 483 // IsAbsolutePath gets confused on Unix if relative path starts with /. | 481 // IsAbsolutePath gets confused on Unix if relative path starts with /. |
| 484 // Lets remove leading / if there is one. | 482 // Lets remove leading / if there is one. |
| 485 size_t start_pos = relative_path.find_first_not_of("/"); | 483 size_t start_pos = relative_path.find_first_not_of("/"); |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 DictionaryValue* theme_value; | 748 DictionaryValue* theme_value; |
| 751 if (!source.GetDictionary(keys::kTheme, &theme_value)) { | 749 if (!source.GetDictionary(keys::kTheme, &theme_value)) { |
| 752 *error = errors::kInvalidTheme; | 750 *error = errors::kInvalidTheme; |
| 753 return false; | 751 return false; |
| 754 } | 752 } |
| 755 is_theme_ = true; | 753 is_theme_ = true; |
| 756 | 754 |
| 757 DictionaryValue* images_value; | 755 DictionaryValue* images_value; |
| 758 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { | 756 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { |
| 759 // Validate that the images are all strings | 757 // Validate that the images are all strings |
| 760 DictionaryValue::key_iterator iter = images_value->begin_keys(); | 758 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); |
| 761 while (iter != images_value->end_keys()) { | 759 iter != images_value->end_keys(); ++iter) { |
| 762 std::string val; | 760 std::string val; |
| 763 if (!images_value->GetString(*iter, &val)) { | 761 if (!images_value->GetString(*iter, &val)) { |
| 764 *error = errors::kInvalidThemeImages; | 762 *error = errors::kInvalidThemeImages; |
| 765 return false; | 763 return false; |
| 766 } | 764 } |
| 767 ++iter; | |
| 768 } | 765 } |
| 769 theme_images_.reset( | 766 theme_images_.reset( |
| 770 static_cast<DictionaryValue*>(images_value->DeepCopy())); | 767 static_cast<DictionaryValue*>(images_value->DeepCopy())); |
| 771 } | 768 } |
| 772 | 769 |
| 773 DictionaryValue* colors_value; | 770 DictionaryValue* colors_value; |
| 774 if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { | 771 if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { |
| 775 // Validate that the colors are all three-item lists | 772 // Validate that the colors are RGB or RGBA lists |
| 776 DictionaryValue::key_iterator iter = colors_value->begin_keys(); | 773 for (DictionaryValue::key_iterator iter = colors_value->begin_keys(); |
| 777 while (iter != colors_value->end_keys()) { | 774 iter != colors_value->end_keys(); ++iter) { |
| 778 std::string val; | |
| 779 int color = 0; | |
| 780 ListValue* color_list; | 775 ListValue* color_list; |
| 781 if (colors_value->GetList(*iter, &color_list)) { | 776 double alpha; |
| 782 if (color_list->GetSize() == 3 || | 777 int alpha_int; |
| 783 color_list->GetSize() == 4) { | 778 int color; |
| 784 if (color_list->GetInteger(0, &color) && | 779 // The color must be a list |
| 785 color_list->GetInteger(1, &color) && | 780 if (!colors_value->GetListWithoutPathExpansion(*iter, &color_list) || |
| 786 color_list->GetInteger(2, &color)) { | 781 // And either 3 items (RGB) or 4 (RGBA) |
| 787 if (color_list->GetSize() == 4) { | 782 ((color_list->GetSize() != 3) && |
| 788 double alpha; | 783 ((color_list->GetSize() != 4) || |
| 789 int alpha_int; | 784 // For RGBA, the fourth item must be a real or int alpha value |
| 790 if (color_list->GetReal(3, &alpha) || | 785 (!color_list->GetReal(3, &alpha) && |
| 791 color_list->GetInteger(3, &alpha_int)) { | 786 !color_list->GetInteger(3, &alpha_int)))) || |
| 792 ++iter; | 787 // For both RGB and RGBA, the first three items must be ints (R,G,B) |
| 793 continue; | 788 !color_list->GetInteger(0, &color) || |
| 794 } | 789 !color_list->GetInteger(1, &color) || |
| 795 } else { | 790 !color_list->GetInteger(2, &color)) { |
| 796 ++iter; | 791 *error = errors::kInvalidThemeColors; |
| 797 continue; | 792 return false; |
| 798 } | |
| 799 } | |
| 800 } | |
| 801 } | 793 } |
| 802 *error = errors::kInvalidThemeColors; | |
| 803 return false; | |
| 804 } | 794 } |
| 805 theme_colors_.reset( | 795 theme_colors_.reset( |
| 806 static_cast<DictionaryValue*>(colors_value->DeepCopy())); | 796 static_cast<DictionaryValue*>(colors_value->DeepCopy())); |
| 807 } | 797 } |
| 808 | 798 |
| 809 DictionaryValue* tints_value; | 799 DictionaryValue* tints_value; |
| 810 if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) { | 800 if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) { |
| 811 // Validate that the tints are all reals. | 801 // Validate that the tints are all reals. |
| 812 DictionaryValue::key_iterator iter = tints_value->begin_keys(); | 802 for (DictionaryValue::key_iterator iter = tints_value->begin_keys(); |
| 813 while (iter != tints_value->end_keys()) { | 803 iter != tints_value->end_keys(); ++iter) { |
| 814 ListValue* tint_list; | 804 ListValue* tint_list; |
| 815 double v = 0; | 805 double v; |
| 816 int vi = 0; | 806 int vi; |
| 817 if (!tints_value->GetList(*iter, &tint_list) || | 807 if (!tints_value->GetListWithoutPathExpansion(*iter, &tint_list) || |
| 818 tint_list->GetSize() != 3 || | 808 tint_list->GetSize() != 3 || |
| 819 !(tint_list->GetReal(0, &v) || tint_list->GetInteger(0, &vi)) || | 809 !(tint_list->GetReal(0, &v) || tint_list->GetInteger(0, &vi)) || |
| 820 !(tint_list->GetReal(1, &v) || tint_list->GetInteger(1, &vi)) || | 810 !(tint_list->GetReal(1, &v) || tint_list->GetInteger(1, &vi)) || |
| 821 !(tint_list->GetReal(2, &v) || tint_list->GetInteger(2, &vi))) { | 811 !(tint_list->GetReal(2, &v) || tint_list->GetInteger(2, &vi))) { |
| 822 *error = errors::kInvalidThemeTints; | 812 *error = errors::kInvalidThemeTints; |
| 823 return false; | 813 return false; |
| 824 } | 814 } |
| 825 ++iter; | |
| 826 } | 815 } |
| 827 theme_tints_.reset( | 816 theme_tints_.reset( |
| 828 static_cast<DictionaryValue*>(tints_value->DeepCopy())); | 817 static_cast<DictionaryValue*>(tints_value->DeepCopy())); |
| 829 } | 818 } |
| 830 | 819 |
| 831 DictionaryValue* display_properties_value; | 820 DictionaryValue* display_properties_value; |
| 832 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, | 821 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, |
| 833 &display_properties_value)) { | 822 &display_properties_value)) { |
| 834 theme_display_properties_.reset( | 823 theme_display_properties_.reset( |
| 835 static_cast<DictionaryValue*>(display_properties_value->DeepCopy())); | 824 static_cast<DictionaryValue*>(display_properties_value->DeepCopy())); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 | 1099 |
| 1111 // Chrome URL overrides (optional) | 1100 // Chrome URL overrides (optional) |
| 1112 if (source.HasKey(keys::kChromeURLOverrides)) { | 1101 if (source.HasKey(keys::kChromeURLOverrides)) { |
| 1113 DictionaryValue* overrides; | 1102 DictionaryValue* overrides; |
| 1114 if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { | 1103 if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { |
| 1115 *error = errors::kInvalidChromeURLOverrides; | 1104 *error = errors::kInvalidChromeURLOverrides; |
| 1116 return false; | 1105 return false; |
| 1117 } | 1106 } |
| 1118 | 1107 |
| 1119 // Validate that the overrides are all strings | 1108 // Validate that the overrides are all strings |
| 1120 DictionaryValue::key_iterator iter = overrides->begin_keys(); | 1109 for (DictionaryValue::key_iterator iter = overrides->begin_keys(); |
| 1121 while (iter != overrides->end_keys()) { | 1110 iter != overrides->end_keys(); ++iter) { |
| 1122 std::string page = WideToUTF8(*iter); | 1111 std::string page = WideToUTF8(*iter); |
| 1123 // For now, only allow the new tab page. Others will work when we remove | 1112 // For now, only allow the new tab page. Others will work when we remove |
| 1124 // this check, but let's keep it simple for now. | 1113 // this check, but let's keep it simple for now. |
| 1125 // TODO(erikkay) enable other pages as well | 1114 // TODO(erikkay) enable other pages as well |
| 1126 if (page != chrome::kChromeUINewTabHost) { | |
| 1127 *error = errors::kInvalidChromeURLOverrides; | |
| 1128 return false; | |
| 1129 } | |
| 1130 std::string val; | 1115 std::string val; |
| 1131 if (!overrides->GetString(*iter, &val)) { | 1116 if ((page != chrome::kChromeUINewTabHost) || |
| 1117 !overrides->GetStringWithoutPathExpansion(*iter, &val)) { |
| 1132 *error = errors::kInvalidChromeURLOverrides; | 1118 *error = errors::kInvalidChromeURLOverrides; |
| 1133 return false; | 1119 return false; |
| 1134 } | 1120 } |
| 1135 // Replace the entry with a fully qualified chrome-extension:// URL. | 1121 // Replace the entry with a fully qualified chrome-extension:// URL. |
| 1136 chrome_url_overrides_[page] = GetResourceURL(val); | 1122 chrome_url_overrides_[page] = GetResourceURL(val); |
| 1137 ++iter; | |
| 1138 } | 1123 } |
| 1139 } | 1124 } |
| 1140 | 1125 |
| 1141 // Although |source| is passed in as a const, it's still possible to modify | 1126 // Although |source| is passed in as a const, it's still possible to modify |
| 1142 // it. This is dangerous since the utility process re-uses |source| after | 1127 // it. This is dangerous since the utility process re-uses |source| after |
| 1143 // it calls InitFromValue, passing it up to the browser process which calls | 1128 // it calls InitFromValue, passing it up to the browser process which calls |
| 1144 // InitFromValue again. As a result, we need to make sure that nobody | 1129 // InitFromValue again. As a result, we need to make sure that nobody |
| 1145 // accidentally modifies it. | 1130 // accidentally modifies it. |
| 1146 DCHECK(source.Equals(manifest_value_.get())); | 1131 DCHECK(source.Equals(manifest_value_.get())); |
| 1147 | 1132 |
| 1148 return true; | 1133 return true; |
| 1149 } | 1134 } |
| 1150 | 1135 |
| 1151 std::set<FilePath> Extension::GetBrowserImages() { | 1136 std::set<FilePath> Extension::GetBrowserImages() { |
| 1152 std::set<FilePath> image_paths; | 1137 std::set<FilePath> image_paths; |
| 1153 | 1138 |
| 1154 // extension icons | 1139 // extension icons |
| 1155 for (std::map<int, std::string>::iterator iter = icons_.begin(); | 1140 for (std::map<int, std::string>::iterator iter = icons_.begin(); |
| 1156 iter != icons_.end(); ++iter) { | 1141 iter != icons_.end(); ++iter) { |
| 1157 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); | 1142 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); |
| 1158 } | 1143 } |
| 1159 | 1144 |
| 1160 // theme images | 1145 // theme images |
| 1161 DictionaryValue* theme_images = GetThemeImages(); | 1146 DictionaryValue* theme_images = GetThemeImages(); |
| 1162 if (theme_images) { | 1147 if (theme_images) { |
| 1163 for (DictionaryValue::key_iterator it = theme_images->begin_keys(); | 1148 for (DictionaryValue::key_iterator it = theme_images->begin_keys(); |
| 1164 it != theme_images->end_keys(); ++it) { | 1149 it != theme_images->end_keys(); ++it) { |
| 1165 std::wstring val; | 1150 std::wstring val; |
| 1166 if (theme_images->GetString(*it, &val)) { | 1151 if (theme_images->GetStringWithoutPathExpansion(*it, &val)) |
| 1167 image_paths.insert(FilePath::FromWStringHack(val)); | 1152 image_paths.insert(FilePath::FromWStringHack(val)); |
| 1168 } | |
| 1169 } | 1153 } |
| 1170 } | 1154 } |
| 1171 | 1155 |
| 1172 // page action icons | 1156 // page action icons |
| 1173 if (page_action_.get()) { | 1157 if (page_action_.get()) { |
| 1174 std::vector<std::string>* icon_paths = page_action_->icon_paths(); | 1158 std::vector<std::string>* icon_paths = page_action_->icon_paths(); |
| 1175 for (std::vector<std::string>::iterator iter = icon_paths->begin(); | 1159 for (std::vector<std::string>::iterator iter = icon_paths->begin(); |
| 1176 iter != icon_paths->end(); ++iter) { | 1160 iter != icon_paths->end(); ++iter) { |
| 1177 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(*iter))); | 1161 image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(*iter))); |
| 1178 } | 1162 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1250 UserScript::PatternList::const_iterator pattern = | 1234 UserScript::PatternList::const_iterator pattern = |
| 1251 content_script->url_patterns().begin(); | 1235 content_script->url_patterns().begin(); |
| 1252 for (; pattern != content_script->url_patterns().end(); ++pattern) { | 1236 for (; pattern != content_script->url_patterns().end(); ++pattern) { |
| 1253 if (pattern->match_subdomains() && pattern->host().empty()) | 1237 if (pattern->match_subdomains() && pattern->host().empty()) |
| 1254 return true; | 1238 return true; |
| 1255 } | 1239 } |
| 1256 } | 1240 } |
| 1257 | 1241 |
| 1258 return false; | 1242 return false; |
| 1259 } | 1243 } |
| OLD | NEW |