~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
23
 * THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API)
 
28
 
 
29
#include "NetscapePluginModule.h"
 
30
 
 
31
#include "PluginProcessProxy.h"
 
32
#include "NetscapeBrowserFuncs.h"
 
33
#include <WebCore/FileSystem.h>
 
34
#include <errno.h>
 
35
#include <fcntl.h>
 
36
#include <sys/stat.h>
 
37
#include <sys/types.h>
 
38
#include <unistd.h>
 
39
 
 
40
using namespace WebCore;
 
41
 
 
42
namespace WebKit {
 
43
 
 
44
class StdoutDevNullRedirector {
 
45
public:
 
46
    StdoutDevNullRedirector();
 
47
    ~StdoutDevNullRedirector();
 
48
 
 
49
private:
 
50
    int m_savedStdout;
 
51
};
 
52
 
 
53
StdoutDevNullRedirector::StdoutDevNullRedirector()
 
54
    : m_savedStdout(-1)
 
55
{
 
56
    int newStdout = open("/dev/null", O_WRONLY);
 
57
    if (newStdout == -1)
 
58
        return;
 
59
    m_savedStdout = dup(STDOUT_FILENO);
 
60
    dup2(newStdout, STDOUT_FILENO);
 
61
}
 
62
 
 
63
StdoutDevNullRedirector::~StdoutDevNullRedirector()
 
64
{
 
65
    if (m_savedStdout != -1)
 
66
        dup2(m_savedStdout, STDOUT_FILENO);
 
67
}
 
68
 
 
69
 
 
70
static void parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
 
71
{
 
72
    ASSERT_ARG(result, result.isEmpty());
 
73
 
 
74
    Vector<String> types;
 
75
    mimeDescription.lower().split(UChar(';'), false, types);
 
76
    result.reserveInitialCapacity(types.size());
 
77
 
 
78
    size_t mimeInfoCount = 0;
 
79
    for (size_t i = 0; i < types.size(); ++i) {
 
80
        Vector<String> mimeTypeParts;
 
81
        types[i].split(UChar(':'), true, mimeTypeParts);
 
82
        if (mimeTypeParts.size() <= 0)
 
83
            continue;
 
84
 
 
85
        result.uncheckedAppend(MimeClassInfo());
 
86
        MimeClassInfo& mimeInfo = result[mimeInfoCount++];
 
87
        mimeInfo.type = mimeTypeParts[0];
 
88
 
 
89
        if (mimeTypeParts.size() > 1)
 
90
            mimeTypeParts[1].split(UChar(','), false, mimeInfo.extensions);
 
91
 
 
92
        if (mimeTypeParts.size() > 2)
 
93
            mimeInfo.desc = mimeTypeParts[2];
 
94
    }
 
95
}
 
96
 
 
97
bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
 
98
{
 
99
    ASSERT(m_isInitialized);
 
100
 
 
101
    Module* module = m_module.get();
 
102
    NPP_GetValueProcPtr NPP_GetValue = module->functionPointer<NPP_GetValueProcPtr>("NP_GetValue");
 
103
    if (!NPP_GetValue)
 
104
        return false;
 
105
 
 
106
    NP_GetMIMEDescriptionFuncPtr NP_GetMIMEDescription = module->functionPointer<NP_GetMIMEDescriptionFuncPtr>("NP_GetMIMEDescription");
 
107
    if (!NP_GetMIMEDescription)
 
108
        return false;
 
109
 
 
110
    char* buffer;
 
111
    NPError error = NPP_GetValue(0, NPPVpluginNameString, &buffer);
 
112
    if (error == NPERR_NO_ERROR)
 
113
        metaData.name = String::fromUTF8(buffer);
 
114
 
 
115
    error = NPP_GetValue(0, NPPVpluginDescriptionString, &buffer);
 
116
    if (error == NPERR_NO_ERROR)
 
117
        metaData.description = String::fromUTF8(buffer);
 
118
 
 
119
    String mimeDescription = String::fromUTF8(NP_GetMIMEDescription());
 
120
    if (mimeDescription.isNull())
 
121
        return false;
 
122
 
 
123
    metaData.mimeDescription = mimeDescription;
 
124
 
 
125
    return true;
 
126
}
 
127
 
 
128
bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
 
129
{
 
130
    RawPluginMetaData metaData;
 
131
    if (!PluginProcessProxy::scanPlugin(pluginPath, metaData))
 
132
        return false;
 
133
 
 
134
    plugin.path = pluginPath;
 
135
    plugin.info.file = pathGetFileName(pluginPath);
 
136
    plugin.info.name = metaData.name;
 
137
    plugin.info.desc = metaData.description;
 
138
    parseMIMEDescription(metaData.mimeDescription, plugin.info.mimes);
 
139
 
 
140
    return true;
 
141
}
 
142
 
 
143
void NetscapePluginModule::determineQuirks()
 
144
{
 
145
#if CPU(X86_64)
 
146
    RawPluginMetaData metaData;
 
147
    if (!getPluginInfoForLoadedPlugin(metaData))
 
148
        return;
 
149
 
 
150
    Vector<MimeClassInfo> mimeTypes;
 
151
    parseMIMEDescription(metaData.mimeDescription, mimeTypes);
 
152
    for (size_t i = 0; i < mimeTypes.size(); ++i) {
 
153
        if (mimeTypes[i].type == "application/x-shockwave-flash") {
 
154
            m_pluginQuirks.add(PluginQuirks::IgnoreRightClickInWindowlessMode);
 
155
            break;
 
156
        }
 
157
    }
 
158
#endif
 
159
}
 
160
 
 
161
static String truncateToSingleLine(const String& string)
 
162
{
 
163
    unsigned oldLength = string.length();
 
164
    UChar* buffer;
 
165
    String stringBuffer(StringImpl::createUninitialized(oldLength + 1, buffer));
 
166
 
 
167
    unsigned newLength = 0;
 
168
    const UChar* start = string.characters();
 
169
    for (const UChar* c = start; c < start + oldLength; ++c) {
 
170
        if (*c != UChar('\n'))
 
171
            buffer[newLength++] = *c;
 
172
    }
 
173
    buffer[newLength++] = UChar('\n');
 
174
 
 
175
    if (newLength == oldLength + 1)
 
176
        return stringBuffer;
 
177
    return String(stringBuffer.characters16(), newLength);
 
178
}
 
179
 
 
180
bool NetscapePluginModule::scanPlugin(const String& pluginPath)
 
181
{
 
182
    RawPluginMetaData metaData;
 
183
 
 
184
    {
 
185
        // Don't allow the plugin to pollute the standard output.
 
186
        StdoutDevNullRedirector stdOutRedirector;
 
187
 
 
188
        // We are loading the plugin here since it does not seem to be a standardized way to
 
189
        // get the needed informations from a UNIX plugin without loading it.
 
190
        RefPtr<NetscapePluginModule> pluginModule = NetscapePluginModule::getOrCreate(pluginPath);
 
191
        if (!pluginModule)
 
192
            return false;
 
193
 
 
194
        pluginModule->incrementLoadCount();
 
195
        bool success = pluginModule->getPluginInfoForLoadedPlugin(metaData);
 
196
        pluginModule->decrementLoadCount();
 
197
 
 
198
        if (!success)
 
199
            return false;
 
200
    }
 
201
 
 
202
    // Write data to standard output for the UI process.
 
203
    String output[3] = {
 
204
        truncateToSingleLine(metaData.name),
 
205
        truncateToSingleLine(metaData.description),
 
206
        truncateToSingleLine(metaData.mimeDescription)
 
207
    };
 
208
    for (unsigned i = 0; i < 3; ++i) {
 
209
        const String& line = output[i];
 
210
        const char* current = reinterpret_cast<const char*>(line.characters16());
 
211
        const char* end = reinterpret_cast<const char*>(line.characters16()) + (line.length() * sizeof(UChar));
 
212
        while (current < end) {
 
213
            int result;
 
214
            while ((result = fputc(*current, stdout)) == EOF && errno == EINTR) { }
 
215
            ASSERT(result != EOF);
 
216
            ++current;
 
217
        }
 
218
    }
 
219
 
 
220
    fflush(stdout);
 
221
 
 
222
    return true;
 
223
}
 
224
 
 
225
} // namespace WebKit
 
226
 
 
227
#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API)