xslt: Import upstream release 1.1.42.

This commit is contained in:
Alexandre Julliard 2024-10-12 19:23:21 +02:00
parent 9d9447775c
commit 785bfba136
11 changed files with 140 additions and 82 deletions

View file

@ -88,8 +88,6 @@ xsltDocDefaultLoaderFunc(const xmlChar * URI, xmlDictPtr dict, int options,
return(NULL);
}
inputPush(pctxt, inputStream);
if (pctxt->directory == NULL)
pctxt->directory = xmlParserGetDirectory((const char *) URI);
xmlParseDocument(pctxt);
@ -435,4 +433,3 @@ xsltFindDocument (xsltTransformContextPtr ctxt, xmlDocPtr doc) {
return(ctxt->document);
return(NULL);
}

View file

@ -415,6 +415,7 @@ xsltExtModuleRegisterDynamic(const xmlChar * URI)
module_filename, URI);
#endif
#if LIBXML_VERSION < 21300
if (1 != xmlCheckFilename(module_filename)) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
@ -425,6 +426,7 @@ xsltExtModuleRegisterDynamic(const xmlChar * URI)
xmlFree(ext_name);
return (-1);
}
#endif
/* attempt to open the module */
m = xmlModuleOpen(module_filename, 0);

View file

@ -96,45 +96,25 @@ xsltXPathFunctionLookup (void *vctxt,
************************************************************************/
static void
xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt,
const xmlChar* URI, const xmlChar *fragment)
{
xsltTransformContextPtr tctxt;
xmlURIPtr uri;
xmlChar *fragment;
xsltDocumentPtr idoc; /* document info */
xmlDocPtr doc;
xmlXPathContextPtr xptrctxt = NULL;
xmlXPathObjectPtr resObj = NULL;
(void) xptrctxt;
tctxt = xsltXPathGetTransformContext(ctxt);
if (tctxt == NULL) {
xsltTransformError(NULL, NULL, NULL,
"document() : internal error tctxt == NULL\n");
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
return;
goto out_fragment;
}
uri = xmlParseURI((const char *) URI);
if (uri == NULL) {
xsltTransformError(tctxt, NULL, NULL,
"document() : failed to parse URI\n");
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
return;
}
/*
* check for and remove fragment identifier
*/
fragment = (xmlChar *)uri->fragment;
if (fragment != NULL) {
xmlChar *newURI;
uri->fragment = NULL;
newURI = xmlSaveUri(uri);
idoc = xsltLoadDocument(tctxt, newURI);
xmlFree(newURI);
} else
idoc = xsltLoadDocument(tctxt, URI);
xmlFreeURI(uri);
idoc = xsltLoadDocument(tctxt, URI);
if (idoc == NULL) {
if ((URI == NULL) ||
@ -147,12 +127,7 @@ xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
*/
doc = tctxt->style->doc;
} else {
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
if (fragment != NULL)
xmlFree(fragment);
return;
goto out_fragment;
}
} else
doc = idoc->doc;
@ -164,7 +139,7 @@ xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
/* use XPointer of HTML location for fragment ID */
#ifdef LIBXML_XPTR_ENABLED
xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
xptrctxt = xmlXPathNewContext(doc);
if (xptrctxt == NULL) {
xsltTransformError(tctxt, NULL, NULL,
"document() : internal error xptrctxt == NULL\n");
@ -199,7 +174,6 @@ out_fragment:
if (resObj == NULL)
resObj = xmlXPathNewNodeSet(NULL);
valuePush(ctxt, resObj);
xmlFree(fragment);
}
/**
@ -215,7 +189,8 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
xmlXPathObjectPtr obj, obj2 = NULL;
xmlChar *base = NULL, *URI;
xmlChar *newURI = NULL;
xmlChar *fragment = NULL;
if ((nargs < 1) || (nargs > 2)) {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
@ -297,7 +272,32 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else {
xsltTransformContextPtr tctxt;
xmlURIPtr uri;
const xmlChar *url;
tctxt = xsltXPathGetTransformContext(ctxt);
url = obj->stringval;
uri = xmlParseURI((const char *) url);
if (uri == NULL) {
xsltTransformError(tctxt, NULL, NULL,
"document() : failed to parse URI '%s'\n", url);
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
goto error;
}
/*
* check for and remove fragment identifier
*/
fragment = (xmlChar *)uri->fragment;
if (fragment != NULL) {
uri->fragment = NULL;
newURI = xmlSaveUri(uri);
url = newURI;
}
xmlFreeURI(uri);
if ((obj2 != NULL) && (obj2->nodesetval != NULL) &&
(obj2->nodesetval->nodeNr > 0) &&
IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) {
@ -318,7 +318,8 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
(xmlNodePtr) tctxt->style->doc);
}
}
URI = xmlBuildURI(obj->stringval, base);
URI = xmlBuildURI(url, base);
if (base != NULL)
xmlFree(base);
if (URI == NULL) {
@ -331,10 +332,14 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
}
} else {
xsltDocumentFunctionLoadDocument( ctxt, URI );
xsltDocumentFunctionLoadDocument(ctxt, URI, fragment);
xmlFree(URI);
}
}
error:
xmlFree(newURI);
xmlFree(fragment);
xmlXPathFreeObject(obj);
if (obj2 != NULL)
xmlXPathFreeObject(obj2);
@ -695,7 +700,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
const xmlChar *nsPrefix = NULL;
void **psviPtr;
unsigned long id;
size_t size, nsPrefixSize;
size_t size, nsPrefixSize = 0;
tctxt = xsltXPathGetTransformContext(ctxt);

View file

@ -33,4 +33,10 @@
#define mkdir(p,m) _mkdir(p)
#endif
#ifdef __GNUC__
#define ATTRIBUTE_UNUSED __attribute__((unused))
#else
#define ATTRIBUTE_UNUSED
#endif
#endif /* ! __XSLT_LIBXSLT_H__ */

View file

@ -422,6 +422,19 @@ xsltCheckRead(xsltSecurityPrefsPtr sec,
xmlURIPtr uri;
xsltSecurityCheck check;
if (xmlStrstr(URL, BAD_CAST "://") == NULL) {
check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_FILE);
if (check != NULL) {
ret = check(sec, ctxt, (const char *) URL);
if (ret == 0) {
xsltTransformError(ctxt, NULL, NULL,
"Local file read for %s refused\n", URL);
return(0);
}
}
return(1);
}
uri = xmlParseURI((const char *)URL);
if (uri == NULL) {
xsltTransformError(ctxt, NULL, NULL,

View file

@ -1010,10 +1010,10 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
if (result == NULL) {
result = xmlXPathNewCString("");
} else {
/*
* Freeing is not handled there anymore.
* QUESTION TODO: What does the above comment mean?
*/
/*
* This stops older libxml2 versions from freeing the nodes
* in the tree.
*/
result->boolval = 0;
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
@ -1232,7 +1232,11 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
if (result == NULL) {
result = xmlXPathNewCString("");
} else {
result->boolval = 0; /* Freeing is not handled there anymore */
/*
* This stops older libxml2 versions from freeing the nodes
* in the tree.
*/
result->boolval = 0;
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
#ifdef LIBXML_DEBUG_ENABLED
@ -2375,5 +2379,3 @@ local_variable_found:
return(valueObj);
}

View file

@ -4460,6 +4460,8 @@ xsltParseSequenceConstructor(xsltCompilerCtxtPtr cctxt, xmlNodePtr cur)
* NOTE that this content model does *not* allow xsl:param.
*/
while (cur != NULL) {
cctxt->style->principal->opCount += 1;
if (deleteNode != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
xsltGenericDebug(xsltGenericDebugContext,
@ -4500,7 +4502,11 @@ xsltParseSequenceConstructor(xsltCompilerCtxtPtr cctxt, xmlNodePtr cur)
* Leave the contained text-node in the tree.
*/
xmlUnlinkNode(tmp);
xmlAddPrevSibling(cur, tmp);
if (xmlAddPrevSibling(cur, tmp) == NULL) {
xsltTransformError(ctxt, NULL, NULL,
"out of memory\n");
xmlFreeNode(tmp);
}
} else {
tmp = NULL;
xsltTransformError(NULL, cctxt->style, cur,
@ -4854,6 +4860,8 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
* user-defined extension instruction if needed).
*/
do {
style->principal->opCount += 1;
if ((child->type == XML_ELEMENT_NODE) &&
IS_XSLT_ELEM_FAST(child) &&
IS_XSLT_NAME(child, "param"))
@ -4897,6 +4905,8 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
cur = templ->children;
delete = NULL;
while (cur != NULL) {
style->principal->opCount += 1;
if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
xsltGenericDebug(xsltGenericDebugContext,
@ -4986,7 +4996,11 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
next = text->next;
xmlUnlinkNode(text);
xmlAddPrevSibling(cur, text);
if (xmlAddPrevSibling(cur, text) == NULL) {
xsltTransformError(NULL, style, NULL,
"out of memory\n");
xmlFreeNode(text);
}
text = next;
}
}
@ -5366,6 +5380,15 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
(template->type != XML_ELEMENT_NODE))
return;
if (style->principal->opLimit > 0) {
if (style->principal->opCount > style->principal->opLimit) {
xsltTransformError(NULL, style, NULL,
"XSLT parser operation limit exceeded\n");
style->errors++;
return;
}
}
/*
* Create and link the structure
*/
@ -6090,6 +6113,15 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
if ((top == NULL) || (top->type != XML_ELEMENT_NODE))
return;
if (style->principal->opLimit > 0) {
if (style->principal->opCount > style->principal->opLimit) {
xsltTransformError(NULL, style, NULL,
"XSLT parser operation limit exceeded\n");
style->errors++;
return;
}
}
prop = xmlGetNsProp(top, (const xmlChar *)"version", NULL);
if (prop == NULL) {
xsltTransformError(NULL, style, top,
@ -6113,6 +6145,8 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
*/
cur = top->children;
while (cur != NULL) {
style->principal->opCount += 1;
if (IS_BLANK_NODE(cur)) {
cur = cur->next;
continue;
@ -6129,6 +6163,8 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
* process other top-level elements
*/
while (cur != NULL) {
style->principal->opCount += 1;
if (IS_BLANK_NODE(cur)) {
cur = cur->next;
continue;

View file

@ -1634,6 +1634,9 @@ struct _xsltStylesheet {
xmlHashTablePtr namedTemplates; /* hash table of named templates */
xmlXPathContextPtr xpathCtxt;
unsigned long opLimit;
unsigned long opCount;
};
typedef struct _xsltTransformCache xsltTransformCache;
@ -1989,4 +1992,3 @@ XSLTPUBFUN int XSLTCALL
#endif
#endif /* __XML_XSLT_H__ */

View file

@ -20,21 +20,21 @@ extern "C" {
*
* the version string like "1.2.3"
*/
#define LIBXSLT_DOTTED_VERSION "1.1.39"
#define LIBXSLT_DOTTED_VERSION "1.1.42"
/**
* LIBXSLT_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
#define LIBXSLT_VERSION 10139
#define LIBXSLT_VERSION 10142
/**
* LIBXSLT_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
#define LIBXSLT_VERSION_STRING "10139"
#define LIBXSLT_VERSION_STRING "10142"
/**
* LIBXSLT_VERSION_EXTRA:

View file

@ -143,7 +143,7 @@ xsltNewLocale(const xmlChar *languageTag, int lowerFirst ATTRIBUTE_UNUSED) {
return(NULL);
memcpy(q, ".UTF-8", 7);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
locale = newlocale(LC_ALL_MASK, localeName, NULL);
if (locale != NULL)
return(locale);
@ -155,7 +155,7 @@ xsltNewLocale(const xmlChar *languageTag, int lowerFirst ATTRIBUTE_UNUSED) {
/* Try locale without territory, e.g. for Esperanto (eo) */
memcpy(q, ".UTF-8", 7);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
locale = newlocale(LC_ALL_MASK, localeName, NULL);
if (locale != NULL)
return(locale);
@ -173,7 +173,7 @@ xsltNewLocale(const xmlChar *languageTag, int lowerFirst ATTRIBUTE_UNUSED) {
*q++ = region[0];
*q++ = region[1];
memcpy(q, ".UTF-8", 7);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
locale = newlocale(LC_ALL_MASK, localeName, NULL);
return(locale);
#endif

View file

@ -1750,13 +1750,12 @@ xsltSaveResultToFilename(const char *URL, xmlDocPtr result,
XSLT_GET_IMPORT_PTR(encoding, style, encoding)
if (encoding != NULL) {
xmlCharEncodingHandlerPtr encoder;
xmlCharEncodingHandlerPtr encoder = NULL;
encoder = xmlFindCharEncodingHandler((char *)encoding);
if ((encoder != NULL) &&
(xmlStrEqual((const xmlChar *)encoder->name,
(const xmlChar *) "UTF-8")))
encoder = NULL;
/* Don't use UTF-8 dummy encoder */
if ((xmlStrcasecmp(encoding, BAD_CAST "UTF-8") != 0) &&
(xmlStrcasecmp(encoding, BAD_CAST "UTF8") != 0))
encoder = xmlFindCharEncodingHandler((char *) encoding);
buf = xmlOutputBufferCreateFilename(URL, encoder, compression);
} else {
buf = xmlOutputBufferCreateFilename(URL, NULL, compression);
@ -1793,13 +1792,12 @@ xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style) {
XSLT_GET_IMPORT_PTR(encoding, style, encoding)
if (encoding != NULL) {
xmlCharEncodingHandlerPtr encoder;
xmlCharEncodingHandlerPtr encoder = NULL;
encoder = xmlFindCharEncodingHandler((char *)encoding);
if ((encoder != NULL) &&
(xmlStrEqual((const xmlChar *)encoder->name,
(const xmlChar *) "UTF-8")))
encoder = NULL;
/* Don't use UTF-8 dummy encoder */
if ((xmlStrcasecmp(encoding, BAD_CAST "UTF-8") != 0) &&
(xmlStrcasecmp(encoding, BAD_CAST "UTF8") != 0))
encoder = xmlFindCharEncodingHandler((char *) encoding);
buf = xmlOutputBufferCreateFile(file, encoder);
} else {
buf = xmlOutputBufferCreateFile(file, NULL);
@ -1837,13 +1835,12 @@ xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) {
XSLT_GET_IMPORT_PTR(encoding, style, encoding)
if (encoding != NULL) {
xmlCharEncodingHandlerPtr encoder;
xmlCharEncodingHandlerPtr encoder = NULL;
encoder = xmlFindCharEncodingHandler((char *)encoding);
if ((encoder != NULL) &&
(xmlStrEqual((const xmlChar *)encoder->name,
(const xmlChar *) "UTF-8")))
encoder = NULL;
/* Don't use UTF-8 dummy encoder */
if ((xmlStrcasecmp(encoding, BAD_CAST "UTF-8") != 0) &&
(xmlStrcasecmp(encoding, BAD_CAST "UTF8") != 0))
encoder = xmlFindCharEncodingHandler((char *) encoding);
buf = xmlOutputBufferCreateFd(fd, encoder);
} else {
buf = xmlOutputBufferCreateFd(fd, NULL);
@ -1880,13 +1877,12 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
XSLT_GET_IMPORT_PTR(encoding, style, encoding)
if (encoding != NULL) {
xmlCharEncodingHandlerPtr encoder;
xmlCharEncodingHandlerPtr encoder = NULL;
encoder = xmlFindCharEncodingHandler((char *)encoding);
if ((encoder != NULL) &&
(xmlStrEqual((const xmlChar *)encoder->name,
(const xmlChar *) "UTF-8")))
encoder = NULL;
/* Don't use UTF-8 dummy encoder */
if ((xmlStrcasecmp(encoding, BAD_CAST "UTF-8") != 0) &&
(xmlStrcasecmp(encoding, BAD_CAST "UTF8") != 0))
encoder = xmlFindCharEncodingHandler((char *) encoding);
buf = xmlAllocOutputBuffer(encoder);
if (buf == NULL)
xmlCharEncCloseFunc(encoder);
@ -2728,4 +2724,3 @@ xslDropCall(void)
}
#endif /* WITH_DEBUGGER */