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_lib.h" | 5 #include "webkit/plugins/npapi/plugin_lib.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #if defined(OS_OPENBSD) | 8 #if defined(OS_OPENBSD) |
9 #include <sys/exec_elf.h> | 9 #include <sys/exec_elf.h> |
10 #else | 10 #else |
(...skipping 24 matching lines...) Expand all Loading... |
35 // Copied from nsplugindefs.h instead of including the file since it has a bunch | 35 // Copied from nsplugindefs.h instead of including the file since it has a bunch |
36 // of dependencies. | 36 // of dependencies. |
37 enum nsPluginVariable { | 37 enum nsPluginVariable { |
38 nsPluginVariable_NameString = 1, | 38 nsPluginVariable_NameString = 1, |
39 nsPluginVariable_DescriptionString = 2 | 39 nsPluginVariable_DescriptionString = 2 |
40 }; | 40 }; |
41 | 41 |
42 // Read the ELF header and return true if it is usable on | 42 // Read the ELF header and return true if it is usable on |
43 // the current architecture (e.g. 32-bit ELF on 32-bit build). | 43 // the current architecture (e.g. 32-bit ELF on 32-bit build). |
44 // Returns false on other errors as well. | 44 // Returns false on other errors as well. |
45 bool ELFMatchesCurrentArchitecture(const FilePath& filename) { | 45 bool ELFMatchesCurrentArchitecture(const base::FilePath& filename) { |
46 // First make sure we can open the file and it is in fact, a regular file. | 46 // First make sure we can open the file and it is in fact, a regular file. |
47 struct stat stat_buf; | 47 struct stat stat_buf; |
48 // Open with O_NONBLOCK so we don't block on pipes. | 48 // Open with O_NONBLOCK so we don't block on pipes. |
49 int fd = open(filename.value().c_str(), O_RDONLY|O_NONBLOCK); | 49 int fd = open(filename.value().c_str(), O_RDONLY|O_NONBLOCK); |
50 if (fd < 0) | 50 if (fd < 0) |
51 return false; | 51 return false; |
52 bool ret = (fstat(fd, &stat_buf) >= 0 && S_ISREG(stat_buf.st_mode)); | 52 bool ret = (fstat(fd, &stat_buf) >= 0 && S_ISREG(stat_buf.st_mode)); |
53 if (HANDLE_EINTR(close(fd)) < 0) | 53 if (HANDLE_EINTR(close(fd)) < 0) |
54 return false; | 54 return false; |
55 if (!ret) | 55 if (!ret) |
(...skipping 28 matching lines...) Expand all Loading... |
84 // for us to extract the real plugin path. | 84 // for us to extract the real plugin path. |
85 struct __attribute__((packed)) NSPluginWrapperInfo { | 85 struct __attribute__((packed)) NSPluginWrapperInfo { |
86 char ident[32]; // NSPluginWrapper magic identifier (includes version). | 86 char ident[32]; // NSPluginWrapper magic identifier (includes version). |
87 char path[PATH_MAX]; // Path to wrapped plugin. | 87 char path[PATH_MAX]; // Path to wrapped plugin. |
88 }; | 88 }; |
89 | 89 |
90 // Test a plugin for whether it's been wrapped by NSPluginWrapper, and | 90 // Test a plugin for whether it's been wrapped by NSPluginWrapper, and |
91 // if so attempt to unwrap it. Pass in an opened plugin handle; on | 91 // if so attempt to unwrap it. Pass in an opened plugin handle; on |
92 // success, |dl| and |unwrapped_path| will be filled in with the newly | 92 // success, |dl| and |unwrapped_path| will be filled in with the newly |
93 // opened plugin. On failure, params are left unmodified. | 93 // opened plugin. On failure, params are left unmodified. |
94 void UnwrapNSPluginWrapper(void **dl, FilePath* unwrapped_path) { | 94 void UnwrapNSPluginWrapper(void **dl, base::FilePath* unwrapped_path) { |
95 NSPluginWrapperInfo* info = | 95 NSPluginWrapperInfo* info = |
96 reinterpret_cast<NSPluginWrapperInfo*>(dlsym(*dl, "NPW_Plugin")); | 96 reinterpret_cast<NSPluginWrapperInfo*>(dlsym(*dl, "NPW_Plugin")); |
97 if (!info) | 97 if (!info) |
98 return; // Not a NSPW plugin. | 98 return; // Not a NSPW plugin. |
99 | 99 |
100 // Here we could check the NSPW ident field for the versioning | 100 // Here we could check the NSPW ident field for the versioning |
101 // information, but the path field is available in all versions | 101 // information, but the path field is available in all versions |
102 // anyway. | 102 // anyway. |
103 | 103 |
104 // Grab the path to the wrapped plugin. Just in case the structure | 104 // Grab the path to the wrapped plugin. Just in case the structure |
105 // format changes, protect against the path not being null-terminated. | 105 // format changes, protect against the path not being null-terminated. |
106 char* path_end = static_cast<char*>(memchr(info->path, '\0', | 106 char* path_end = static_cast<char*>(memchr(info->path, '\0', |
107 sizeof(info->path))); | 107 sizeof(info->path))); |
108 if (!path_end) | 108 if (!path_end) |
109 path_end = info->path + sizeof(info->path); | 109 path_end = info->path + sizeof(info->path); |
110 FilePath path = FilePath(std::string(info->path, path_end - info->path)); | 110 base::FilePath path = base::FilePath( |
| 111 std::string(info->path, path_end - info->path)); |
111 | 112 |
112 if (!ELFMatchesCurrentArchitecture(path)) { | 113 if (!ELFMatchesCurrentArchitecture(path)) { |
113 LOG(WARNING) << path.value() << " is nspluginwrapper wrapping a " | 114 LOG(WARNING) << path.value() << " is nspluginwrapper wrapping a " |
114 << "plugin for a different architecture; it will " | 115 << "plugin for a different architecture; it will " |
115 << "work better if you instead use a native plugin."; | 116 << "work better if you instead use a native plugin."; |
116 return; | 117 return; |
117 } | 118 } |
118 | 119 |
119 std::string error; | 120 std::string error; |
120 void* newdl = base::LoadNativeLibrary(path, &error); | 121 void* newdl = base::LoadNativeLibrary(path, &error); |
(...skipping 11 matching lines...) Expand all Loading... |
132 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 133 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
133 << "Using unwrapped version " << unwrapped_path->value() | 134 << "Using unwrapped version " << unwrapped_path->value() |
134 << " of nspluginwrapper-wrapped plugin."; | 135 << " of nspluginwrapper-wrapped plugin."; |
135 base::UnloadNativeLibrary(*dl); | 136 base::UnloadNativeLibrary(*dl); |
136 *dl = newdl; | 137 *dl = newdl; |
137 *unwrapped_path = path; | 138 *unwrapped_path = path; |
138 } | 139 } |
139 | 140 |
140 } // namespace | 141 } // namespace |
141 | 142 |
142 bool PluginLib::ReadWebPluginInfo(const FilePath& filename, | 143 bool PluginLib::ReadWebPluginInfo(const base::FilePath& filename, |
143 WebPluginInfo* info) { | 144 WebPluginInfo* info) { |
144 // The file to reference is: | 145 // The file to reference is: |
145 // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirU
nix.cpp | 146 // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginsDirU
nix.cpp |
146 | 147 |
147 // Skip files that aren't appropriate for our architecture. | 148 // Skip files that aren't appropriate for our architecture. |
148 if (!ELFMatchesCurrentArchitecture(filename)) { | 149 if (!ELFMatchesCurrentArchitecture(filename)) { |
149 LOG_IF(ERROR, PluginList::DebugPluginLoading()) | 150 LOG_IF(ERROR, PluginList::DebugPluginLoading()) |
150 << "Skipping plugin " << filename.value() | 151 << "Skipping plugin " << filename.value() |
151 << " because it doesn't match the current architecture."; | 152 << " because it doesn't match the current architecture."; |
152 return false; | 153 return false; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 break; | 299 break; |
299 } | 300 } |
300 } | 301 } |
301 if (!version.empty()) { | 302 if (!version.empty()) { |
302 info->version = UTF8ToUTF16(version); | 303 info->version = UTF8ToUTF16(version); |
303 } | 304 } |
304 } | 305 } |
305 | 306 |
306 } // namespace npapi | 307 } // namespace npapi |
307 } // namespace webkit | 308 } // namespace webkit |
OLD | NEW |