Index: third_party/libxslt/libxslt/extensions.c |
=================================================================== |
--- third_party/libxslt/libxslt/extensions.c (revision 39981) |
+++ third_party/libxslt/libxslt/extensions.c (working copy) |
@@ -34,8 +34,10 @@ |
#ifdef _WIN32 |
#include <stdlib.h> /* for _MAX_PATH */ |
+#ifndef PATH_MAX |
#define PATH_MAX _MAX_PATH |
#endif |
+#endif |
#ifdef WITH_XSLT_DEBUG |
#define WITH_XSLT_DEBUG_EXTENSIONS |
@@ -84,6 +86,7 @@ |
static xmlHashTablePtr xsltElementsHash = NULL; |
static xmlHashTablePtr xsltTopLevelsHash = NULL; |
static xmlHashTablePtr xsltModuleHash = NULL; |
+static xmlMutexPtr xsltExtMutex = NULL; |
/************************************************************************ |
* * |
@@ -337,10 +340,14 @@ |
return (-1); |
} |
+ xmlMutexLock(xsltExtMutex); |
+ |
/* have we attempted to register this module already? */ |
if (xmlHashLookup(xsltModuleHash, URI) != NULL) { |
+ xmlMutexUnlock(xsltExtMutex); |
return (-1); |
} |
+ xmlMutexUnlock(xsltExtMutex); |
/* transform extension namespace into a module name */ |
protocol = xmlStrstr(URI, BAD_CAST "://"); |
@@ -366,16 +373,17 @@ |
/* determine module directory */ |
ext_directory = (xmlChar *) getenv("LIBXSLT_PLUGINS_PATH"); |
+ if (NULL == ext_directory) { |
+ ext_directory = BAD_CAST LIBXSLT_DEFAULT_PLUGINS_PATH(); |
+ if (NULL == ext_directory) |
+ return (-1); |
+ } |
#ifdef WITH_XSLT_DEBUG_EXTENSIONS |
- xsltGenericDebug(xsltGenericDebugContext, |
- "LIBXSLT_PLUGINS_PATH is %s\n", ext_directory); |
+ else |
+ xsltGenericDebug(xsltGenericDebugContext, |
+ "LIBXSLT_PLUGINS_PATH is %s\n", ext_directory); |
#endif |
- if (NULL == ext_directory) |
- ext_directory = BAD_CAST LIBXSLT_DEFAULT_PLUGINS_PATH(); |
- if (NULL == ext_directory) |
- return (-1); |
- |
/* build the module filename, and confirm the module exists */ |
xmlStrPrintf((xmlChar *) module_filename, sizeof(module_filename), |
BAD_CAST "%s/%s%s", |
@@ -427,7 +435,9 @@ |
(*regfunc) (); |
/* register this module in our hash */ |
+ xmlMutexLock(xsltExtMutex); |
xmlHashAddEntry(xsltModuleHash, URI, (void *) m); |
+ xmlMutexUnlock(xsltExtMutex); |
} else { |
#ifdef WITH_XSLT_DEBUG_EXTENSIONS |
@@ -446,7 +456,7 @@ |
} |
#else |
static int |
-xsltExtModuleRegisterDynamic(const xmlChar * ATTRIBUTE_UNUSED URI) |
+xsltExtModuleRegisterDynamic(const xmlChar * URI ATTRIBUTE_UNUSED) |
{ |
return -1; |
} |
@@ -538,10 +548,14 @@ |
if (xsltExtensionsHash != NULL) { |
xsltExtModulePtr module; |
+ xmlMutexLock(xsltExtMutex); |
module = xmlHashLookup(xsltExtensionsHash, URI); |
+ xmlMutexUnlock(xsltExtMutex); |
if (NULL == module) { |
if (!xsltExtModuleRegisterDynamic(URI)) { |
+ xmlMutexLock(xsltExtMutex); |
module = xmlHashLookup(xsltExtensionsHash, URI); |
+ xmlMutexUnlock(xsltExtMutex); |
} |
} |
if (module != NULL) { |
@@ -573,6 +587,8 @@ |
xsltRegisterExtFunction(xsltTransformContextPtr ctxt, const xmlChar * name, |
const xmlChar * URI, xmlXPathFunction function) |
{ |
+ int ret; |
+ |
if ((ctxt == NULL) || (name == NULL) || |
(URI == NULL) || (function == NULL)) |
return (-1); |
@@ -583,8 +599,11 @@ |
ctxt->extFunctions = xmlHashCreate(10); |
if (ctxt->extFunctions == NULL) |
return (-1); |
- return (xmlHashAddEntry2 |
- (ctxt->extFunctions, name, URI, XML_CAST_FPTR(function))); |
+ |
+ ret = xmlHashAddEntry2(ctxt->extFunctions, name, URI, |
+ XML_CAST_FPTR(function)); |
+ |
+ return(ret); |
} |
/** |
@@ -659,7 +678,12 @@ |
return(NULL); |
} |
+ xmlMutexLock(xsltExtMutex); |
+ |
module = xmlHashLookup(xsltExtensionsHash, URI); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
if (module == NULL) { |
#ifdef WITH_XSLT_DEBUG_EXTENSIONS |
xsltGenericDebug(xsltGenericDebugContext, |
@@ -853,7 +877,12 @@ |
void *extData; |
xsltExtModulePtr module; |
+ xmlMutexLock(xsltExtMutex); |
+ |
module = xmlHashLookup(xsltExtensionsHash, URI); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
if (module == NULL) { |
#ifdef WITH_XSLT_DEBUG_EXTENSIONS |
xsltGenericDebug(xsltGenericDebugContext, |
@@ -1233,18 +1262,27 @@ |
if (xsltExtensionsHash == NULL) |
return (-1); |
+ xmlMutexLock(xsltExtMutex); |
+ |
module = xmlHashLookup(xsltExtensionsHash, URI); |
if (module != NULL) { |
if ((module->initFunc == initFunc) && |
(module->shutdownFunc == shutdownFunc)) |
- return (0); |
- return (-1); |
+ ret = 0; |
+ else |
+ ret = -1; |
+ goto done; |
} |
module = xsltNewExtModule(initFunc, shutdownFunc, |
styleInitFunc, styleShutdownFunc); |
- if (module == NULL) |
- return (-1); |
+ if (module == NULL) { |
+ ret = -1; |
+ goto done; |
+ } |
ret = xmlHashAddEntry(xsltExtensionsHash, URI, (void *) module); |
+ |
+done: |
+ xmlMutexUnlock(xsltExtMutex); |
return (ret); |
} |
@@ -1285,9 +1323,13 @@ |
if (xsltExtensionsHash == NULL) |
return (-1); |
- ret = |
- xmlHashRemoveEntry(xsltExtensionsHash, URI, |
- (xmlHashDeallocator) xsltFreeExtModule); |
+ xmlMutexLock(xsltExtMutex); |
+ |
+ ret = xmlHashRemoveEntry(xsltExtensionsHash, URI, |
+ (xmlHashDeallocator) xsltFreeExtModule); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
return (ret); |
} |
@@ -1302,9 +1344,13 @@ |
if (xsltExtensionsHash == NULL) |
return; |
+ xmlMutexLock(xsltExtMutex); |
+ |
xmlHashFree(xsltExtensionsHash, |
(xmlHashDeallocator) xsltFreeExtModule); |
xsltExtensionsHash = NULL; |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
/** |
@@ -1349,9 +1395,13 @@ |
if (xsltFunctionsHash == NULL) |
return (-1); |
+ xmlMutexLock(xsltExtMutex); |
+ |
xmlHashUpdateEntry2(xsltFunctionsHash, name, URI, |
XML_CAST_FPTR(function), NULL); |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
return (0); |
} |
@@ -1372,13 +1422,21 @@ |
if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
XML_CAST_FPTR(ret) = xmlHashLookup2(xsltFunctionsHash, name, URI); |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
/* if lookup fails, attempt a dynamic load on supported platforms */ |
if (NULL == ret) { |
if (!xsltExtModuleRegisterDynamic(URI)) { |
+ xmlMutexLock(xsltExtMutex); |
+ |
XML_CAST_FPTR(ret) = |
xmlHashLookup2(xsltFunctionsHash, name, URI); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
} |
@@ -1397,10 +1455,18 @@ |
int |
xsltUnregisterExtModuleFunction(const xmlChar * name, const xmlChar * URI) |
{ |
+ int ret; |
+ |
if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (-1); |
- return xmlHashRemoveEntry2(xsltFunctionsHash, name, URI, NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
+ ret = xmlHashRemoveEntry2(xsltFunctionsHash, name, URI, NULL); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
+ return(ret); |
} |
/** |
@@ -1411,8 +1477,12 @@ |
static void |
xsltUnregisterAllExtModuleFunction(void) |
{ |
+ xmlMutexLock(xsltExtMutex); |
+ |
xmlHashFree(xsltFunctionsHash, NULL); |
xsltFunctionsHash = NULL; |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
@@ -1492,8 +1562,13 @@ |
(inst->type != XML_ELEMENT_NODE) || (inst->ns == NULL)) |
return (NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
ext = (xsltExtElementPtr) |
xmlHashLookup2(xsltElementsHash, inst->name, inst->ns->href); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
/* |
* EXT TODO: Now what? |
*/ |
@@ -1547,6 +1622,8 @@ |
xsltPreComputeFunction precomp, |
xsltTransformFunction transform) |
{ |
+ int ret; |
+ |
xsltExtElementPtr ext; |
if ((name == NULL) || (URI == NULL) || (transform == NULL)) |
@@ -1557,13 +1634,20 @@ |
if (xsltElementsHash == NULL) |
return (-1); |
+ xmlMutexLock(xsltExtMutex); |
+ |
ext = xsltNewExtElement(precomp, transform); |
- if (ext == NULL) |
- return (-1); |
+ if (ext == NULL) { |
+ ret = -1; |
+ goto done; |
+ } |
xmlHashUpdateEntry2(xsltElementsHash, name, URI, (void *) ext, |
(xmlHashDeallocator) xsltFreeExtElement); |
+done: |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
return (0); |
} |
@@ -1589,10 +1673,14 @@ |
if ((ctxt != NULL) && (ctxt->extElements != NULL)) { |
XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->extElements, name, URI); |
- if (ret != NULL) |
- return (ret); |
+ if (ret != NULL) { |
+ return(ret); |
+ } |
} |
- return xsltExtModuleElementLookup(name, URI); |
+ |
+ ret = xsltExtModuleElementLookup(name, URI); |
+ |
+ return (ret); |
} |
/** |
@@ -1612,14 +1700,24 @@ |
if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI); |
- /* if function lookup fails, attempt a dynamic load on supported platforms */ |
- ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI); |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
+ /* |
+ * if function lookup fails, attempt a dynamic load on |
+ * supported platforms |
+ */ |
if (NULL == ext) { |
if (!xsltExtModuleRegisterDynamic(URI)) { |
+ xmlMutexLock(xsltExtMutex); |
+ |
ext = (xsltExtElementPtr) |
xmlHashLookup2(xsltElementsHash, name, URI); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
} |
@@ -1646,12 +1744,20 @@ |
if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI); |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
if (ext == NULL) { |
if (!xsltExtModuleRegisterDynamic(URI)) { |
+ xmlMutexLock(xsltExtMutex); |
+ |
ext = (xsltExtElementPtr) |
xmlHashLookup2(xsltElementsHash, name, URI); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
} |
@@ -1672,11 +1778,19 @@ |
int |
xsltUnregisterExtModuleElement(const xmlChar * name, const xmlChar * URI) |
{ |
+ int ret; |
+ |
if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (-1); |
- return xmlHashRemoveEntry2(xsltElementsHash, name, URI, |
- (xmlHashDeallocator) xsltFreeExtElement); |
+ xmlMutexLock(xsltExtMutex); |
+ |
+ ret = xmlHashRemoveEntry2(xsltElementsHash, name, URI, |
+ (xmlHashDeallocator) xsltFreeExtElement); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
+ return(ret); |
} |
/** |
@@ -1687,8 +1801,12 @@ |
static void |
xsltUnregisterAllExtModuleElement(void) |
{ |
+ xmlMutexLock(xsltExtMutex); |
+ |
xmlHashFree(xsltElementsHash, (xmlHashDeallocator) xsltFreeExtElement); |
xsltElementsHash = NULL; |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
/** |
@@ -1713,9 +1831,13 @@ |
if (xsltTopLevelsHash == NULL) |
return (-1); |
+ xmlMutexLock(xsltExtMutex); |
+ |
xmlHashUpdateEntry2(xsltTopLevelsHash, name, URI, |
XML_CAST_FPTR(function), NULL); |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
return (0); |
} |
@@ -1736,12 +1858,20 @@ |
if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
XML_CAST_FPTR(ret) = xmlHashLookup2(xsltTopLevelsHash, name, URI); |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
/* if lookup fails, attempt a dynamic load on supported platforms */ |
if (NULL == ret) { |
if (!xsltExtModuleRegisterDynamic(URI)) { |
+ xmlMutexLock(xsltExtMutex); |
+ |
XML_CAST_FPTR(ret) = xmlHashLookup2(xsltTopLevelsHash, name, URI); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
} |
@@ -1760,10 +1890,18 @@ |
int |
xsltUnregisterExtModuleTopLevel(const xmlChar * name, const xmlChar * URI) |
{ |
+ int ret; |
+ |
if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL)) |
return (-1); |
- return xmlHashRemoveEntry2(xsltTopLevelsHash, name, URI, NULL); |
+ xmlMutexLock(xsltExtMutex); |
+ |
+ ret = xmlHashRemoveEntry2(xsltTopLevelsHash, name, URI, NULL); |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
+ |
+ return(ret); |
} |
/** |
@@ -1774,8 +1912,12 @@ |
static void |
xsltUnregisterAllExtModuleTopLevel(void) |
{ |
+ xmlMutexLock(xsltExtMutex); |
+ |
xmlHashFree(xsltTopLevelsHash, NULL); |
xsltTopLevelsHash = NULL; |
+ |
+ xmlMutexUnlock(xsltExtMutex); |
} |
/** |
@@ -2086,6 +2228,7 @@ |
void |
xsltRegisterTestModule(void) |
{ |
+ xsltInitGlobals(); |
xsltRegisterExtModuleFull((const xmlChar *) XSLT_DEFAULT_URL, |
xsltExtInitTest, xsltExtShutdownTest, |
xsltExtStyleInitTest, |
@@ -2100,7 +2243,8 @@ |
} |
static void |
-xsltHashScannerModuleFree(void *payload, void *data ATTRIBUTE_UNUSED, |
+xsltHashScannerModuleFree(void *payload ATTRIBUTE_UNUSED, |
+ void *data ATTRIBUTE_UNUSED, |
xmlChar * name ATTRIBUTE_UNUSED) |
{ |
#ifdef WITH_MODULES |
@@ -2109,6 +2253,19 @@ |
} |
/** |
+ * xsltInitGlobals: |
+ * |
+ * Initialize the global variables for extensions |
+ */ |
+void |
+xsltInitGlobals(void) |
+{ |
+ if (xsltExtMutex == NULL) { |
+ xsltExtMutex = xmlNewMutex(); |
+ } |
+} |
+ |
+/** |
* xsltCleanupGlobals: |
* |
* Unregister all global variables set up by the XSLT library |
@@ -2121,13 +2278,17 @@ |
xsltUnregisterAllExtModuleElement(); |
xsltUnregisterAllExtModuleTopLevel(); |
+ xmlMutexLock(xsltExtMutex); |
/* cleanup dynamic module hash */ |
if (NULL != xsltModuleHash) { |
xmlHashScan(xsltModuleHash, xsltHashScannerModuleFree, 0); |
xmlHashFree(xsltModuleHash, NULL); |
xsltModuleHash = NULL; |
} |
+ xmlMutexUnlock(xsltExtMutex); |
+ xmlFreeMutex(xsltExtMutex); |
+ xsltExtMutex = NULL; |
xsltUninit(); |
} |
@@ -2170,25 +2331,31 @@ |
fprintf(output, "No registered extension functions\n"); |
else { |
fprintf(output, "Registered Extension Functions:\n"); |
+ xmlMutexLock(xsltExtMutex); |
xmlHashScanFull(xsltFunctionsHash, |
(xmlHashScannerFull) |
xsltDebugDumpExtensionsCallback, output); |
+ xmlMutexUnlock(xsltExtMutex); |
} |
if (!xsltElementsHash) |
fprintf(output, "\nNo registered extension elements\n"); |
else { |
fprintf(output, "\nRegistered Extension Elements:\n"); |
+ xmlMutexLock(xsltExtMutex); |
xmlHashScanFull(xsltElementsHash, |
(xmlHashScannerFull) |
xsltDebugDumpExtensionsCallback, output); |
+ xmlMutexUnlock(xsltExtMutex); |
} |
if (!xsltExtensionsHash) |
fprintf(output, "\nNo registered extension modules\n"); |
else { |
fprintf(output, "\nRegistered Extension Modules:\n"); |
+ xmlMutexLock(xsltExtMutex); |
xmlHashScanFull(xsltExtensionsHash, |
(xmlHashScannerFull) |
xsltDebugDumpExtModulesCallback, output); |
+ xmlMutexUnlock(xsltExtMutex); |
} |
} |