| 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 |