Edit

kc3-lang/libxml2/xmlmodule.c

Branch :

  • Show log

    Commit

  • Author : Gaurav
    Date : 2014-02-18 11:47:43
    Hash : 085b997c
    Message : Avoid a possible NULL pointer dereference For https://bugzilla.gnome.org/show_bug.cgi?id=708355

  • xmlmodule.c
  • /*
     * xmlmodule.c : basic API for dynamic module loading added 2.6.17
     *
     * See Copyright for the status of this software.
     *
     * joelwreed@comcast.net
     *
     * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
     */
    
    #define IN_LIBXML
    #include "libxml.h"
    
    #include <string.h>
    #include <libxml/xmlmemory.h>
    #include <libxml/xmlerror.h>
    #include <libxml/xmlmodule.h>
    #include <libxml/globals.h>
    
    #ifdef LIBXML_MODULES_ENABLED
    
    struct _xmlModule {
        unsigned char *name;
        void *handle;
    };
    
    static void *xmlModulePlatformOpen(const char *name);
    static int xmlModulePlatformClose(void *handle);
    static int xmlModulePlatformSymbol(void *handle, const char *name, void **result);
    
    /************************************************************************
     *									*
     *		module memory error handler				*
     *									*
     ************************************************************************/
    
    /**
     * xmlModuleErrMemory:
     * @extra:  extra information
     *
     * Handle an out of memory condition
     */
    static void
    xmlModuleErrMemory(xmlModulePtr module, const char *extra)
    {
        const char *name = NULL;
    
        if (module != NULL) {
            name = (const char *) module->name;
        }
    
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
                        name, NULL, 0, 0,
                        "Memory allocation failed : %s\n", extra);
    }
    
    /**
     * xmlModuleOpen:
     * @name: the module name
     * @options: a set of xmlModuleOption
     *
     * Opens a module/shared library given its name or path
     * NOTE: that due to portability issues, behaviour can only be
     * guaranteed with @name using ASCII. We canot guarantee that
     * an UTF-8 string would work, which is why name is a const char *
     * and not a const xmlChar * .
     * TODO: options are not yet implemented.
     *
     * Returns a handle for the module or NULL in case of error
     */
    xmlModulePtr
    xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
    {
        xmlModulePtr module;
    
        module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
        if (module == NULL) {
            xmlModuleErrMemory(NULL, "creating module");
            return (NULL);
        }
    
        memset(module, 0, sizeof(xmlModule));
    
        module->handle = xmlModulePlatformOpen(name);
    
        if (module->handle == NULL) {
            xmlFree(module);
            __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                            XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
                            name, NULL, 0, 0, "failed to open %s\n", name);
            return(NULL);
        }
    
        module->name = xmlStrdup((const xmlChar *) name);
        return (module);
    }
    
    /**
     * xmlModuleSymbol:
     * @module: the module
     * @name: the name of the symbol
     * @symbol: the resulting symbol address
     *
     * Lookup for a symbol address in the given module
     * NOTE: that due to portability issues, behaviour can only be
     * guaranteed with @name using ASCII. We canot guarantee that
     * an UTF-8 string would work, which is why name is a const char *
     * and not a const xmlChar * .
     *
     * Returns 0 if the symbol was found, or -1 in case of error
     */
    int
    xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
    {
        int rc = -1;
    
        if ((NULL == module) || (symbol == NULL) || (name == NULL)) {
            __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                            XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
                            NULL, NULL, 0, 0, "null parameter\n");
            return rc;
        }
    
        rc = xmlModulePlatformSymbol(module->handle, name, symbol);
    
        if (rc == -1) {
            __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                            XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
                            name, NULL, 0, 0,
                            "failed to find symbol: %s\n",
    			(name == NULL ? "NULL" : name));
            return rc;
        }
    
        return rc;
    }
    
    /**
     * xmlModuleClose:
     * @module: the module handle
     *
     * The close operations unload the associated module and free the
     * data associated to the module.
     *
     * Returns 0 in case of success, -1 in case of argument error and -2
     *         if the module could not be closed/unloaded.
     */
    int
    xmlModuleClose(xmlModulePtr module)
    {
        int rc;
    
        if (NULL == module) {
            __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                            XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
                            NULL, NULL, 0, 0, "null module pointer\n");
            return -1;
        }
    
        rc = xmlModulePlatformClose(module->handle);
    
        if (rc != 0) {
            __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                            XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
                            (const char *) module->name, NULL, 0, 0,
                            "failed to close: %s\n", module->name);
            return -2;
        }
    
        rc = xmlModuleFree(module);
        return (rc);
    }
    
    /**
     * xmlModuleFree:
     * @module: the module handle
     *
     * The free operations free the data associated to the module
     * but does not unload the associated shared library which may still
     * be in use.
     *
     * Returns 0 in case of success, -1 in case of argument error
     */
    int
    xmlModuleFree(xmlModulePtr module)
    {
        if (NULL == module) {
            __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                            XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, NULL,
                            NULL, NULL, 0, 0, "null module pointer\n");
            return -1;
        }
    
        xmlFree(module->name);
        xmlFree(module);
    
        return (0);
    }
    
    #if defined(HAVE_DLOPEN) && !defined(_WIN32)
    #ifdef HAVE_DLFCN_H
    #include <dlfcn.h>
    #endif
    
    #ifndef RTLD_GLOBAL            /* For Tru64 UNIX 4.0 */
    #define RTLD_GLOBAL 0
    #endif
    
    /**
     * xmlModulePlatformOpen:
     * @name: path to the module
     *
     * returns a handle on success, and zero on error.
     */
    
    static void *
    xmlModulePlatformOpen(const char *name)
    {
        return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
    }
    
    /*
     * xmlModulePlatformClose:
     * @handle: handle to the module
     *
     * returns 0 on success, and non-zero on error.
     */
    
    static int
    xmlModulePlatformClose(void *handle)
    {
        return dlclose(handle);
    }
    
    /*
     * xmlModulePlatformSymbol:
     * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
     * returns 0 on success and the loaded symbol in result, and -1 on error.
     */
    
    static int
    xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
    {
        *symbol = dlsym(handle, name);
        if (dlerror() != NULL) {
    	return -1;
        }
        return 0;
    }
    
    #else /* ! HAVE_DLOPEN */
    
    #ifdef HAVE_SHLLOAD             /* HAVE_SHLLOAD */
    #ifdef HAVE_DL_H
    #include <dl.h>
    #endif
    /*
     * xmlModulePlatformOpen:
     * returns a handle on success, and zero on error.
     */
    
    static void *
    xmlModulePlatformOpen(const char *name)
    {
        return shl_load(name, BIND_IMMEDIATE, 0L);
    }
    
    /*
     * xmlModulePlatformClose:
     * returns 0 on success, and non-zero on error.
     */
    
    static int
    xmlModulePlatformClose(void *handle)
    {
        return shl_unload(handle);
    }
    
    /*
     * xmlModulePlatformSymbol:
     * http://docs.hp.com/en/B2355-90683/shl_load.3X.html
     * returns 0 on success and the loaded symbol in result, and -1 on error.
     */
    
    static int
    xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
    {
        int rc;
    
        errno = 0;
        rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
        return rc;
    }
    
    #endif /* HAVE_SHLLOAD */
    #endif /* ! HAVE_DLOPEN */
    
    #ifdef _WIN32
    
    #include <windows.h>
    
    /*
     * xmlModulePlatformOpen:
     * returns a handle on success, and zero on error.
     */
    
    static void *
    xmlModulePlatformOpen(const char *name)
    {
        return LoadLibraryA(name);
    }
    
    /*
     * xmlModulePlatformClose:
     * returns 0 on success, and non-zero on error.
     */
    
    static int
    xmlModulePlatformClose(void *handle)
    {
        int rc;
    
        rc = FreeLibrary(handle);
        return (0 == rc);
    }
    
    /*
     * xmlModulePlatformSymbol:
     * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
     * returns 0 on success and the loaded symbol in result, and -1 on error.
     */
    
    static int
    xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
    {
    #ifdef _WIN32_WCE
        /*
         * GetProcAddressA seems only available on WinCE
         */
        *symbol = GetProcAddressA(handle, name);
    #else
        *symbol = GetProcAddress(handle, name);
    #endif
        return (NULL == *symbol) ? -1 : 0;
    }
    
    #endif /* _WIN32 */
    
    #ifdef HAVE_BEOS
    
    #include <kernel/image.h>
    
    /*
     * xmlModulePlatformOpen:
     * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
     * returns a handle on success, and zero on error.
     */
    
    static void *
    xmlModulePlatformOpen(const char *name)
    {
        return (void *) load_add_on(name);
    }
    
    /*
     * xmlModulePlatformClose:
     * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
     * returns 0 on success, and non-zero on error.
     */
    
    static int
    xmlModulePlatformClose(void *handle)
    {
        status_t rc;
    
        rc = unload_add_on((image_id) handle);
    
        if (rc == B_OK)
            return 0;
        else
            return -1;
    }
    
    /*
     * xmlModulePlatformSymbol:
     * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
     * returns 0 on success and the loaded symbol in result, and -1 on error.
     */
    
    static int
    xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
    {
        status_t rc;
    
        rc = get_image_symbol((image_id) handle, name, B_SYMBOL_TYPE_ANY, symbol);
    
        return (rc == B_OK) ? 0 : -1;
    }
    
    #endif /* HAVE_BEOS */
    
    #ifdef HAVE_OS2
    
    #include <os2.h>
    
    /*
     * xmlModulePlatformOpen:
     * os2 api info: http://www.edm2.com/os2api/Dos/DosLoadModule.html
     * returns a handle on success, and zero on error.
     */
    
    static void *
    xmlModulePlatformOpen(const char *name)
    {
        char errbuf[256];
        void *handle;
        int rc;
    
        rc = DosLoadModule(errbuf, sizeof(errbuf) - 1, name, &handle);
    
        if (rc)
            return 0;
        else
            return (handle);
    }
    
    /*
     * xmlModulePlatformClose:
     * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
     * returns 0 on success, and non-zero on error.
     */
    
    static int
    xmlModulePlatformClose(void *handle)
    {
        return DosFreeModule(handle);
    }
    
    /*
     * xmlModulePlatformSymbol:
     * os2 api info: http://www.edm2.com/os2api/Dos/DosQueryProcAddr.html
     * returns 0 on success and the loaded symbol in result, and -1 on error.
     */
    
    static int
    xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
    {
        int rc;
    
        rc = DosQueryProcAddr(handle, 0, name, symbol);
    
        return (rc == NO_ERROR) ? 0 : -1;
    }
    
    #endif /* HAVE_OS2 */
    
    #define bottom_xmlmodule
    #include "elfgcchack.h"
    #endif /* LIBXML_MODULES_ENABLED */