summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/plugin_lib_posix.cc
diff options
context:
space:
mode:
authorpvalchev@google.com <pvalchev@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-03 23:42:08 +0000
committerpvalchev@google.com <pvalchev@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-03 23:42:08 +0000
commit428caf008d98f93d3bcf4b93f566573b62e916ab (patch)
tree79354ad6e86fc1b762efa918f470194d55c380e9 /webkit/glue/plugins/plugin_lib_posix.cc
parentb9cd85d797204e52a9e15f0b9560e82ce3b47a80 (diff)
downloadchromium_src-428caf008d98f93d3bcf4b93f566573b62e916ab.zip
chromium_src-428caf008d98f93d3bcf4b93f566573b62e916ab.tar.gz
chromium_src-428caf008d98f93d3bcf4b93f566573b62e916ab.tar.bz2
OpenBSD has sys/exec_elf.h for the ELF defines, not elf.h
rename 'linux' files to 'posix' (and exclude them on mac) Review URL: http://codereview.chromium.org/562023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38041 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins/plugin_lib_posix.cc')
-rw-r--r--webkit/glue/plugins/plugin_lib_posix.cc163
1 files changed, 163 insertions, 0 deletions
diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc
new file mode 100644
index 0000000..a16ca8d
--- /dev/null
+++ b/webkit/glue/plugins/plugin_lib_posix.cc
@@ -0,0 +1,163 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/plugins/plugin_lib.h"
+
+#include <dlfcn.h>
+#if defined(OS_OPENBSD)
+#include <sys/exec_elf.h>
+#else
+#include <elf.h>
+#endif
+
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "webkit/glue/plugins/plugin_list.h"
+
+// These headers must be included in this order to make the declaration gods
+// happy.
+#include "base/third_party/nspr/prcpucfg_linux.h"
+
+namespace {
+
+// Copied from nsplugindefs.h instead of including the file since it has a bunch
+// of dependencies.
+enum nsPluginVariable {
+ nsPluginVariable_NameString = 1,
+ nsPluginVariable_DescriptionString = 2
+};
+
+// Read the ELF header and return true if it is usable on
+// the current architecture (e.g. 32-bit ELF on 32-bit build).
+// Returns false on other errors as well.
+bool ELFMatchesCurrentArchitecture(const FilePath& filename) {
+ FILE* file = fopen(filename.value().c_str(), "rb");
+ if (!file)
+ return false;
+
+ char buffer[5];
+ if (fread(buffer, 5, 1, file) != 1) {
+ fclose(file);
+ return false;
+ }
+ fclose(file);
+
+ if (buffer[0] != ELFMAG0 ||
+ buffer[1] != ELFMAG1 ||
+ buffer[2] != ELFMAG2 ||
+ buffer[3] != ELFMAG3) {
+ // Not an ELF file, perhaps?
+ return false;
+ }
+
+ int elf_class = buffer[EI_CLASS];
+#if defined(ARCH_CPU_32_BITS)
+ if (elf_class == ELFCLASS32)
+ return true;
+#elif defined(ARCH_CPU_64_BITS)
+ if (elf_class == ELFCLASS64)
+ return true;
+#endif
+
+ return false;
+}
+
+} // anonymous namespace
+namespace NPAPI {
+
+bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
+ WebPluginInfo* info) {
+ // The file to reference is:
+ // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirUnix.cpp
+
+ // Skip files that aren't appropriate for our architecture.
+ if (!ELFMatchesCurrentArchitecture(filename))
+ return false;
+
+ void* dl = base::LoadNativeLibrary(filename);
+ if (!dl)
+ return false;
+
+ info->path = filename;
+
+ // See comments in plugin_lib_mac regarding this symbol.
+ typedef const char* (*NP_GetMimeDescriptionType)();
+ NP_GetMimeDescriptionType NP_GetMIMEDescription =
+ reinterpret_cast<NP_GetMimeDescriptionType>(
+ dlsym(dl, "NP_GetMIMEDescription"));
+ const char* mime_description = NULL;
+ if (NP_GetMIMEDescription)
+ mime_description = NP_GetMIMEDescription();
+
+ if (mime_description)
+ ParseMIMEDescription(mime_description, &info->mime_types);
+
+ // The plugin name and description live behind NP_GetValue calls.
+ typedef NPError (*NP_GetValueType)(void* unused,
+ nsPluginVariable variable,
+ void* value_out);
+ NP_GetValueType NP_GetValue =
+ reinterpret_cast<NP_GetValueType>(dlsym(dl, "NP_GetValue"));
+ if (NP_GetValue) {
+ const char* name = NULL;
+ NP_GetValue(NULL, nsPluginVariable_NameString, &name);
+ if (name)
+ info->name = UTF8ToWide(name);
+
+ const char* description = NULL;
+ NP_GetValue(NULL, nsPluginVariable_DescriptionString, &description);
+ if (description)
+ info->desc = UTF8ToWide(description);
+ }
+
+ // Intentionally not unloading the plugin here, it can lead to crashes.
+
+ return true;
+}
+
+// static
+void PluginLib::ParseMIMEDescription(
+ const std::string& description,
+ std::vector<WebPluginMimeType>* mime_types) {
+ // We parse the description here into WebPluginMimeType structures.
+ // Naively from the NPAPI docs you'd think you could use
+ // string-splitting, but the Firefox parser turns out to do something
+ // different: find the first colon, then the second, then a semi.
+ //
+ // See ParsePluginMimeDescription near
+ // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirUtils.h#53
+
+ std::string::size_type ofs = 0;
+ for (;;) {
+ WebPluginMimeType mime_type;
+
+ std::string::size_type end = description.find(':', ofs);
+ if (end == std::string::npos)
+ break;
+ mime_type.mime_type = description.substr(ofs, end - ofs);
+ ofs = end + 1;
+
+ end = description.find(':', ofs);
+ if (end == std::string::npos)
+ break;
+ const std::string extensions = description.substr(ofs, end - ofs);
+ SplitString(extensions, ',', &mime_type.file_extensions);
+ ofs = end + 1;
+
+ end = description.find(';', ofs);
+ // It's ok for end to run off the string here. If there's no
+ // trailing semicolon we consume the remainder of the string.
+ if (end != std::string::npos) {
+ mime_type.description = UTF8ToWide(description.substr(ofs, end - ofs));
+ } else {
+ mime_type.description = UTF8ToWide(description.substr(ofs));
+ }
+ mime_types->push_back(mime_type);
+ if (end == std::string::npos)
+ break;
+ ofs = end + 1;
+ }
+}
+
+} // namespace NPAPI