OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/plugins/npapi/plugin_list.h" | 5 #include "webkit/plugins/npapi/plugin_list.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/cpu.h" | 9 #include "base/cpu.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
12 #include "base/sha1.h" | 12 #include "base/sha1.h" |
13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
14 #include "base/string_split.h" | 14 #include "base/string_split.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 | 17 |
18 namespace webkit { | 18 namespace webkit { |
19 namespace npapi { | 19 namespace npapi { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // We build up a list of files and mtimes so we can sort them. | 23 // We build up a list of files and mtimes so we can sort them. |
24 typedef std::pair<FilePath, base::Time> FileAndTime; | 24 typedef std::pair<base::FilePath, base::Time> FileAndTime; |
25 typedef std::vector<FileAndTime> FileTimeList; | 25 typedef std::vector<FileAndTime> FileTimeList; |
26 | 26 |
27 enum PluginQuirk { | 27 enum PluginQuirk { |
28 // No quirks - plugin is outright banned. | 28 // No quirks - plugin is outright banned. |
29 PLUGIN_QUIRK_NONE = 0, | 29 PLUGIN_QUIRK_NONE = 0, |
30 // Plugin is using SSE2 instructions without checking for SSE2 instruction | 30 // Plugin is using SSE2 instructions without checking for SSE2 instruction |
31 // support. Ban the plugin if the system has no SSE2 support. | 31 // support. Ban the plugin if the system has no SSE2 support. |
32 PLUGIN_QUIRK_MISSING_SSE2_CHECK = 1 << 0, | 32 PLUGIN_QUIRK_MISSING_SSE2_CHECK = 1 << 0, |
33 }; | 33 }; |
34 | 34 |
(...skipping 21 matching lines...) Expand all Loading... |
56 return true; | 56 return true; |
57 } | 57 } |
58 | 58 |
59 return false; | 59 return false; |
60 } | 60 } |
61 | 61 |
62 // Return true if |path| matches a known (file size, sha1sum) pair. | 62 // Return true if |path| matches a known (file size, sha1sum) pair. |
63 // Also check against any PluginQuirks the bad plugin may have. | 63 // Also check against any PluginQuirks the bad plugin may have. |
64 // The use of the file size is an optimization so we don't have to read in | 64 // The use of the file size is an optimization so we don't have to read in |
65 // the entire file unless we have to. | 65 // the entire file unless we have to. |
66 bool IsBlacklistedBySha1sumAndQuirks(const FilePath& path) { | 66 bool IsBlacklistedBySha1sumAndQuirks(const base::FilePath& path) { |
67 const struct BadEntry { | 67 const struct BadEntry { |
68 int64 size; | 68 int64 size; |
69 std::string sha1; | 69 std::string sha1; |
70 PluginQuirk quirks; | 70 PluginQuirk quirks; |
71 } bad_entries[] = { | 71 } bad_entries[] = { |
72 // Flash 9 r31 - http://crbug.com/29237 | 72 // Flash 9 r31 - http://crbug.com/29237 |
73 { 7040080, "fa5803061125ca47846713b34a26a42f1f1e98bb", PLUGIN_QUIRK_NONE }, | 73 { 7040080, "fa5803061125ca47846713b34a26a42f1f1e98bb", PLUGIN_QUIRK_NONE }, |
74 // Flash 9 r48 - http://crbug.com/29237 | 74 // Flash 9 r48 - http://crbug.com/29237 |
75 { 7040036, "0c4b3768a6d4bfba003088e4b9090d381de1af2b", PLUGIN_QUIRK_NONE }, | 75 { 7040036, "0c4b3768a6d4bfba003088e4b9090d381de1af2b", PLUGIN_QUIRK_NONE }, |
76 // Flash 11.2.202.236, 32-bit - http://crbug.com/140086 | 76 // Flash 11.2.202.236, 32-bit - http://crbug.com/140086 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 return true; | 116 return true; |
117 } | 117 } |
118 } | 118 } |
119 return false; | 119 return false; |
120 } | 120 } |
121 | 121 |
122 // Return true if we shouldn't load a plugin at all. | 122 // Return true if we shouldn't load a plugin at all. |
123 // This is an ugly hack to blacklist Adobe Acrobat due to not supporting | 123 // This is an ugly hack to blacklist Adobe Acrobat due to not supporting |
124 // its Xt-based mainloop. | 124 // its Xt-based mainloop. |
125 // http://code.google.com/p/chromium/issues/detail?id=38229 | 125 // http://code.google.com/p/chromium/issues/detail?id=38229 |
126 bool IsBlacklistedPlugin(const FilePath& path) { | 126 bool IsBlacklistedPlugin(const base::FilePath& path) { |
127 const char* kBlackListedPlugins[] = { | 127 const char* kBlackListedPlugins[] = { |
128 "nppdf.so", // Adobe PDF | 128 "nppdf.so", // Adobe PDF |
129 }; | 129 }; |
130 std::string filename = path.BaseName().value(); | 130 std::string filename = path.BaseName().value(); |
131 for (size_t i = 0; i < arraysize(kBlackListedPlugins); i++) { | 131 for (size_t i = 0; i < arraysize(kBlackListedPlugins); i++) { |
132 if (filename.find(kBlackListedPlugins[i]) != std::string::npos) { | 132 if (filename.find(kBlackListedPlugins[i]) != std::string::npos) { |
133 return true; | 133 return true; |
134 } | 134 } |
135 } | 135 } |
136 return IsBlacklistedBySha1sumAndQuirks(path); | 136 return IsBlacklistedBySha1sumAndQuirks(path); |
137 } | 137 } |
138 | 138 |
139 } // namespace | 139 } // namespace |
140 | 140 |
141 void PluginList::PlatformInit() { | 141 void PluginList::PlatformInit() { |
142 } | 142 } |
143 | 143 |
144 void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { | 144 void PluginList::GetPluginDirectories(std::vector<base::FilePath>* plugin_dirs)
{ |
145 // See http://groups.google.com/group/chromium-dev/browse_thread/thread/7a70e5
fcbac786a9 | 145 // See http://groups.google.com/group/chromium-dev/browse_thread/thread/7a70e5
fcbac786a9 |
146 // for discussion. | 146 // for discussion. |
147 // We first consult Chrome-specific dirs, then fall back on the logic | 147 // We first consult Chrome-specific dirs, then fall back on the logic |
148 // Mozilla uses. | 148 // Mozilla uses. |
149 | 149 |
150 // Note: "extra" plugin dirs, including the Plugins subdirectory of | 150 // Note: "extra" plugin dirs, including the Plugins subdirectory of |
151 // your Chrome config, are examined before these. See the logic | 151 // your Chrome config, are examined before these. See the logic |
152 // related to extra_plugin_dirs in plugin_list.cc. | 152 // related to extra_plugin_dirs in plugin_list.cc. |
153 | 153 |
154 // The Chrome binary dir + "plugins/". | 154 // The Chrome binary dir + "plugins/". |
155 FilePath dir; | 155 base::FilePath dir; |
156 PathService::Get(base::DIR_EXE, &dir); | 156 PathService::Get(base::DIR_EXE, &dir); |
157 plugin_dirs->push_back(dir.Append("plugins")); | 157 plugin_dirs->push_back(dir.Append("plugins")); |
158 | 158 |
159 // Chrome OS only loads plugins from /opt/google/chrome/plugins. | 159 // Chrome OS only loads plugins from /opt/google/chrome/plugins. |
160 #if !defined(OS_CHROMEOS) | 160 #if !defined(OS_CHROMEOS) |
161 // Mozilla code to reference: | 161 // Mozilla code to reference: |
162 // http://mxr.mozilla.org/firefox/ident?i=NS_APP_PLUGINS_DIR_LIST | 162 // http://mxr.mozilla.org/firefox/ident?i=NS_APP_PLUGINS_DIR_LIST |
163 // and tens of accompanying files (mxr is very helpful). | 163 // and tens of accompanying files (mxr is very helpful). |
164 // This code carefully matches their behavior for compat reasons. | 164 // This code carefully matches their behavior for compat reasons. |
165 | 165 |
166 // 1) MOZ_PLUGIN_PATH env variable. | 166 // 1) MOZ_PLUGIN_PATH env variable. |
167 const char* moz_plugin_path = getenv("MOZ_PLUGIN_PATH"); | 167 const char* moz_plugin_path = getenv("MOZ_PLUGIN_PATH"); |
168 if (moz_plugin_path) { | 168 if (moz_plugin_path) { |
169 std::vector<std::string> paths; | 169 std::vector<std::string> paths; |
170 base::SplitString(moz_plugin_path, ':', &paths); | 170 base::SplitString(moz_plugin_path, ':', &paths); |
171 for (size_t i = 0; i < paths.size(); ++i) | 171 for (size_t i = 0; i < paths.size(); ++i) |
172 plugin_dirs->push_back(FilePath(paths[i])); | 172 plugin_dirs->push_back(base::FilePath(paths[i])); |
173 } | 173 } |
174 | 174 |
175 // 2) NS_USER_PLUGINS_DIR: ~/.mozilla/plugins. | 175 // 2) NS_USER_PLUGINS_DIR: ~/.mozilla/plugins. |
176 // This is a de-facto standard, so even though we're not Mozilla, let's | 176 // This is a de-facto standard, so even though we're not Mozilla, let's |
177 // look in there too. | 177 // look in there too. |
178 FilePath home = file_util::GetHomeDir(); | 178 base::FilePath home = file_util::GetHomeDir(); |
179 if (!home.empty()) | 179 if (!home.empty()) |
180 plugin_dirs->push_back(home.Append(".mozilla/plugins")); | 180 plugin_dirs->push_back(home.Append(".mozilla/plugins")); |
181 | 181 |
182 // 3) NS_SYSTEM_PLUGINS_DIR: | 182 // 3) NS_SYSTEM_PLUGINS_DIR: |
183 // This varies across different browsers and versions, so check 'em all. | 183 // This varies across different browsers and versions, so check 'em all. |
184 plugin_dirs->push_back(FilePath("/usr/lib/browser-plugins")); | 184 plugin_dirs->push_back(base::FilePath("/usr/lib/browser-plugins")); |
185 plugin_dirs->push_back(FilePath("/usr/lib/mozilla/plugins")); | 185 plugin_dirs->push_back(base::FilePath("/usr/lib/mozilla/plugins")); |
186 plugin_dirs->push_back(FilePath("/usr/lib/firefox/plugins")); | 186 plugin_dirs->push_back(base::FilePath("/usr/lib/firefox/plugins")); |
187 plugin_dirs->push_back(FilePath("/usr/lib/xulrunner-addons/plugins")); | 187 plugin_dirs->push_back(base::FilePath("/usr/lib/xulrunner-addons/plugins")); |
188 | 188 |
189 #if defined(ARCH_CPU_64_BITS) | 189 #if defined(ARCH_CPU_64_BITS) |
190 // On my Ubuntu system, /usr/lib64 is a symlink to /usr/lib. | 190 // On my Ubuntu system, /usr/lib64 is a symlink to /usr/lib. |
191 // But a user reported on their Fedora system they are separate. | 191 // But a user reported on their Fedora system they are separate. |
192 plugin_dirs->push_back(FilePath("/usr/lib64/browser-plugins")); | 192 plugin_dirs->push_back(base::FilePath("/usr/lib64/browser-plugins")); |
193 plugin_dirs->push_back(FilePath("/usr/lib64/mozilla/plugins")); | 193 plugin_dirs->push_back(base::FilePath("/usr/lib64/mozilla/plugins")); |
194 plugin_dirs->push_back(FilePath("/usr/lib64/firefox/plugins")); | 194 plugin_dirs->push_back(base::FilePath("/usr/lib64/firefox/plugins")); |
195 plugin_dirs->push_back(FilePath("/usr/lib64/xulrunner-addons/plugins")); | 195 plugin_dirs->push_back(base::FilePath("/usr/lib64/xulrunner-addons/plugins")); |
196 #endif // defined(ARCH_CPU_64_BITS) | 196 #endif // defined(ARCH_CPU_64_BITS) |
197 #endif // !defined(OS_CHROMEOS) | 197 #endif // !defined(OS_CHROMEOS) |
198 } | 198 } |
199 | 199 |
200 void PluginList::GetPluginsInDir( | 200 void PluginList::GetPluginsInDir( |
201 const FilePath& dir_path, std::vector<FilePath>* plugins) { | 201 const base::FilePath& dir_path, std::vector<base::FilePath>* plugins) { |
202 // See ScanPluginsDirectory near | 202 // See ScanPluginsDirectory near |
203 // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginHostI
mpl.cpp#5052 | 203 // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginHostI
mpl.cpp#5052 |
204 | 204 |
205 // Construct and stat a list of all filenames under consideration, for | 205 // Construct and stat a list of all filenames under consideration, for |
206 // later sorting by mtime. | 206 // later sorting by mtime. |
207 FileTimeList files; | 207 FileTimeList files; |
208 file_util::FileEnumerator enumerator(dir_path, | 208 file_util::FileEnumerator enumerator(dir_path, |
209 false, // not recursive | 209 false, // not recursive |
210 file_util::FileEnumerator::FILES); | 210 file_util::FileEnumerator::FILES); |
211 for (FilePath path = enumerator.Next(); !path.value().empty(); | 211 for (base::FilePath path = enumerator.Next(); !path.value().empty(); |
212 path = enumerator.Next()) { | 212 path = enumerator.Next()) { |
213 // Skip over Mozilla .xpt files. | 213 // Skip over Mozilla .xpt files. |
214 if (path.MatchesExtension(FILE_PATH_LITERAL(".xpt"))) | 214 if (path.MatchesExtension(FILE_PATH_LITERAL(".xpt"))) |
215 continue; | 215 continue; |
216 | 216 |
217 // Java doesn't like being loaded through a symlink, since it uses | 217 // Java doesn't like being loaded through a symlink, since it uses |
218 // its path to find dependent data files. | 218 // its path to find dependent data files. |
219 // file_util::AbsolutePath calls through to realpath(), which resolves | 219 // file_util::AbsolutePath calls through to realpath(), which resolves |
220 // symlinks. | 220 // symlinks. |
221 FilePath orig_path = path; | 221 base::FilePath orig_path = path; |
222 file_util::AbsolutePath(&path); | 222 file_util::AbsolutePath(&path); |
223 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 223 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
224 << "Resolved " << orig_path.value() << " -> " << path.value(); | 224 << "Resolved " << orig_path.value() << " -> " << path.value(); |
225 | 225 |
226 if (std::find(plugins->begin(), plugins->end(), path) != plugins->end()) { | 226 if (std::find(plugins->begin(), plugins->end(), path) != plugins->end()) { |
227 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 227 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
228 << "Skipping duplicate instance of " << path.value(); | 228 << "Skipping duplicate instance of " << path.value(); |
229 continue; | 229 continue; |
230 } | 230 } |
231 | 231 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 | 294 |
295 // TODO(evanm): prefer the newest version of flash, etc. here? | 295 // TODO(evanm): prefer the newest version of flash, etc. here? |
296 | 296 |
297 VLOG_IF(1, PluginList::DebugPluginLoading()) << "Using " << info.path.value(); | 297 VLOG_IF(1, PluginList::DebugPluginLoading()) << "Using " << info.path.value(); |
298 | 298 |
299 return true; | 299 return true; |
300 } | 300 } |
301 | 301 |
302 } // namespace npapi | 302 } // namespace npapi |
303 } // namespace webkit | 303 } // namespace webkit |
OLD | NEW |