Home | History | Annotate | Download | only in qt
      1 /*
      2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "PluginPackage.h"
     29 
     30 #include "MIMETypeRegistry.h"
     31 #include "npruntime_impl.h"
     32 #include "PluginDatabase.h"
     33 #include "PluginDebug.h"
     34 #include <wtf/text/CString.h>
     35 
     36 namespace WebCore {
     37 
     38 bool PluginPackage::fetchInfo()
     39 {
     40     if (!load())
     41         return false;
     42 
     43     NPP_GetValueProcPtr gv = (NPP_GetValueProcPtr)m_module->resolve("NP_GetValue");
     44     typedef char *(*NPP_GetMIMEDescriptionProcPtr)();
     45     NPP_GetMIMEDescriptionProcPtr gm =
     46         (NPP_GetMIMEDescriptionProcPtr)m_module->resolve("NP_GetMIMEDescription");
     47     if (!gm || !gv)
     48         return false;
     49 
     50     char *buf = 0;
     51     NPError err = gv(0, NPPVpluginNameString, (void*) &buf);
     52     if (err != NPERR_NO_ERROR)
     53         return false;
     54 
     55     m_name = buf;
     56     err = gv(0, NPPVpluginDescriptionString, (void*) &buf);
     57     if (err != NPERR_NO_ERROR)
     58         return false;
     59 
     60     m_description = buf;
     61     determineModuleVersionFromDescription();
     62 
     63     String mimeDescription = gm();
     64     setMIMEDescription(mimeDescription);
     65     m_infoIsFromCache = false;
     66 
     67     return true;
     68 }
     69 
     70 void PluginPackage::setMIMEDescription(const String& mimeDescription)
     71 {
     72     m_fullMIMEDescription = mimeDescription.lower();
     73 
     74     Vector<String> types;
     75     mimeDescription.lower().split(UChar(';'), false, types);
     76     for (unsigned i = 0; i < types.size(); ++i) {
     77         Vector<String> mime;
     78         types[i].split(UChar(':'), true, mime);
     79         if (mime.size() > 0) {
     80             Vector<String> exts;
     81             if (mime.size() > 1)
     82                 mime[1].split(UChar(','), false, exts);
     83             determineQuirks(mime[0]);
     84             m_mimeToExtensions.add(mime[0], exts);
     85             if (mime.size() > 2)
     86                 m_mimeToDescriptions.add(mime[0], mime[2]);
     87         }
     88     }
     89 }
     90 
     91 static NPError staticPluginQuirkRequiresGtkToolKit_NPN_GetValue(NPP instance, NPNVariable variable, void* value)
     92 {
     93     if (variable == NPNVToolkit) {
     94         *static_cast<uint32_t*>(value) = 2;
     95         return NPERR_NO_ERROR;
     96     }
     97 
     98     return NPN_GetValue(instance, variable, value);
     99 }
    100 
    101 static void initializeGtk(QLibrary* module = 0)
    102 {
    103     // Ensures missing Gtk initialization in some versions of Adobe's flash player
    104     // plugin do not cause crashes. See BR# 40567, 44324, and 44405 for details.
    105     if (module) {
    106         typedef void *(*gtk_init_ptr)(int*, char***);
    107         gtk_init_ptr gtkInit = (gtk_init_ptr)module->resolve("gtk_init");
    108         if (gtkInit) {
    109             // Prevent gtk_init() from replacing the X error handlers, since the Gtk
    110             // handlers abort when they receive an X error, thus killing the viewer.
    111 #ifdef Q_WS_X11
    112             int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0);
    113             int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0);
    114 #endif
    115             gtkInit(0, 0);
    116 #ifdef Q_WS_X11
    117             XSetErrorHandler(old_error_handler);
    118             XSetIOErrorHandler(old_io_error_handler);
    119 #endif
    120             return;
    121         }
    122     }
    123 
    124     QLibrary library(QLatin1String("libgtk-x11-2.0.so.0"));
    125     if (library.load()) {
    126         typedef void *(*gtk_init_check_ptr)(int*, char***);
    127         gtk_init_check_ptr gtkInitCheck = (gtk_init_check_ptr)library.resolve("gtk_init_check");
    128         // NOTE: We're using gtk_init_check() since gtk_init() calls exit() on failure.
    129         if (gtkInitCheck)
    130             (void) gtkInitCheck(0, 0);
    131     }
    132 }
    133 
    134 bool PluginPackage::load()
    135 {
    136     if (m_isLoaded) {
    137         m_loadCount++;
    138         return true;
    139     }
    140 
    141     m_module = new QLibrary((QString)m_path);
    142     m_module->setLoadHints(QLibrary::ResolveAllSymbolsHint);
    143     if (!m_module->load()) {
    144         LOG(Plugins, "%s not loaded (%s)", m_path.utf8().data(),
    145                 m_module->errorString().toLatin1().constData());
    146         return false;
    147     }
    148 
    149     m_isLoaded = true;
    150 
    151     NP_InitializeFuncPtr NP_Initialize;
    152     NPError npErr;
    153 
    154     NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize");
    155     m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown");
    156 
    157     if (!NP_Initialize || !m_NPP_Shutdown)
    158         goto abort;
    159 
    160     memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
    161     m_pluginFuncs.size = sizeof(m_pluginFuncs);
    162 
    163     initializeBrowserFuncs();
    164 
    165     if (m_path.contains("npwrapper.")) {
    166         // nspluginwrapper relies on the toolkit value to know if glib is available
    167         // It does so in NP_Initialize with a null instance, therefore it is done this way:
    168         m_browserFuncs.getvalue = staticPluginQuirkRequiresGtkToolKit_NPN_GetValue;
    169         // Workaround Adobe's failure to properly initialize Gtk in some versions
    170         // of their flash player plugin.
    171         initializeGtk();
    172     } else if (m_path.contains("flashplayer")) {
    173         // Workaround Adobe's failure to properly initialize Gtk in some versions
    174         // of their flash player plugin.
    175         initializeGtk(m_module);
    176     }
    177 
    178 #if defined(XP_UNIX)
    179     npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
    180 #else
    181     npErr = NP_Initialize(&m_browserFuncs);
    182 #endif
    183     if (npErr != NPERR_NO_ERROR)
    184         goto abort;
    185 
    186     m_loadCount++;
    187     return true;
    188 
    189 abort:
    190     unloadWithoutShutdown();
    191     return false;
    192 }
    193 
    194 uint16_t PluginPackage::NPVersion() const
    195 {
    196     return NP_VERSION_MINOR;
    197 }
    198 
    199 }
    200