summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/plugin_lib_posix.cc53
1 files changed, 53 insertions, 0 deletions
diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc
index 1097b24..e738b67 100644
--- a/webkit/glue/plugins/plugin_lib_posix.cc
+++ b/webkit/glue/plugins/plugin_lib_posix.cc
@@ -64,7 +64,57 @@ bool ELFMatchesCurrentArchitecture(const FilePath& filename) {
return false;
}
+// This structure matches enough of nspluginwrapper's NPW_PluginInfo
+// for us to extract the real plugin path.
+struct __attribute__((packed)) NSPluginWrapperInfo {
+ char ident[32]; // NSPluginWrapper magic identifier (includes version).
+ char path[PATH_MAX]; // Path to wrapped plugin.
+};
+
+// Test a plugin for whether it's been wrapped by NSPluginWrapper, and
+// if so attempt to unwrap it. Pass in an opened plugin handle; on
+// success, |dl| and |unwrapped_path| will be filled in with the newly
+// opened plugin. On failure, params are left unmodified.
+void UnwrapNSPluginWrapper(void **dl, FilePath* unwrapped_path) {
+ NSPluginWrapperInfo* info =
+ reinterpret_cast<NSPluginWrapperInfo*>(dlsym(*dl, "NPW_Plugin"));
+ if (!info)
+ return; // Not a NSPW plugin.
+
+ // Here we could check the NSPW ident field for the versioning
+ // information, but the path field is available in all versions
+ // anyway.
+
+ // Grab the path to the wrapped plugin. Just in case the structure
+ // format changes, protect against the path not being null-terminated.
+ char* path_end = static_cast<char*>(memchr(info->path, '\0',
+ sizeof(info->path)));
+ if (!path_end)
+ path_end = info->path + sizeof(info->path);
+ FilePath path = FilePath(std::string(info->path, path_end - info->path));
+
+ if (!ELFMatchesCurrentArchitecture(path)) {
+ LOG(WARNING) << path.value() << " is nspluginwrapper wrapping a "
+ << "plugin for a different architecture; it will "
+ << "work better if you instead use a native plugin.";
+ return;
+ }
+
+ void* newdl = base::LoadNativeLibrary(path);
+ if (!newdl) {
+ // We couldn't load the unwrapped plugin for some reason, despite
+ // being able to load the wrapped one. Just use the wrapped one.
+ return;
+ }
+
+ // Unload the wrapped plugin, and use the wrapped plugin instead.
+ base::UnloadNativeLibrary(*dl);
+ *dl = newdl;
+ *unwrapped_path = path;
+}
+
} // anonymous namespace
+
namespace NPAPI {
bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
@@ -82,6 +132,9 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
info->path = filename;
+ // Attempt to swap in the wrapped plugin if this is nspluginwrapper.
+ UnwrapNSPluginWrapper(&dl, &info->path);
+
// See comments in plugin_lib_mac regarding this symbol.
typedef const char* (*NP_GetMimeDescriptionType)();
NP_GetMimeDescriptionType NP_GetMIMEDescription =