From 6b678a4e9b7bf0fcbdfbe49d75fa8911807fe9d1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 5 Jun 2023 12:09:29 +0200 Subject: [PATCH] xslt: Import upstream release 1.1.38. --- libs/xslt/libxslt/attributes.c | 19 +- libs/xslt/libxslt/attributes.h | 1 + libs/xslt/libxslt/attrvt.c | 33 ++-- libs/xslt/libxslt/documents.c | 2 + libs/xslt/libxslt/extensions.c | 16 +- libs/xslt/libxslt/functions.c | 145 +++++++++++--- libs/xslt/libxslt/imports.c | 60 +++--- libs/xslt/libxslt/keys.c | 26 +-- libs/xslt/libxslt/numbers.c | 96 ++++++---- libs/xslt/libxslt/pattern.c | 92 +++------ libs/xslt/libxslt/preproc.c | 10 - libs/xslt/libxslt/templates.c | 4 +- libs/xslt/libxslt/transform.c | 117 ++++++++---- libs/xslt/libxslt/variables.c | 96 +++++----- libs/xslt/libxslt/variables.h | 6 +- libs/xslt/libxslt/xslt.c | 91 ++++----- libs/xslt/libxslt/xsltInternals.h | 18 +- libs/xslt/libxslt/xsltconfig.h | 6 +- libs/xslt/libxslt/xsltlocale.c | 150 +++++++++------ libs/xslt/libxslt/xsltlocale.h | 112 ++++------- libs/xslt/libxslt/xsltutils.c | 386 +++++++++++++++++++++++++++++--------- libs/xslt/libxslt/xsltutils.h | 37 +++- 22 files changed, 949 insertions(+), 574 deletions(-) rewrite libs/xslt/libxslt/xsltlocale.h (62%) diff --git a/libs/xslt/libxslt/attributes.c b/libs/xslt/libxslt/attributes.c index 8a64f3e7b3e..4cc49d0d1a5 100644 --- a/libs/xslt/libxslt/attributes.c +++ b/libs/xslt/libxslt/attributes.c @@ -87,6 +87,7 @@ typedef xsltAttrSetContext *xsltAttrSetContextPtr; struct _xsltAttrSetContext { xsltStylesheetPtr topStyle; xsltStylesheetPtr style; + int error; }; static void @@ -274,7 +275,7 @@ xsltAddUseAttrSetList(xsltUseAttrSetPtr list, const xmlChar *ncname, * Returns the newly allocated xsltAttrSetPtr or NULL in case of error. */ static xsltAttrSetPtr -xsltNewAttrSet() { +xsltNewAttrSet(void) { xsltAttrSetPtr cur; cur = (xsltAttrSetPtr) xmlMalloc(sizeof(xsltAttrSet)); @@ -421,9 +422,12 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) { set = xmlHashLookup2(style->attributeSets, ncname, nsUri); if (set == NULL) { set = xsltNewAttrSet(); - if (set == NULL) + if ((set == NULL) || + (xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set) < 0)) { + xsltGenericError(xsltGenericErrorContext, "memory error\n"); + xsltFreeAttrSet(set); return; - xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set); + } } /* @@ -663,6 +667,12 @@ xsltResolveSASCallback(void *payload, void *data, xsltStylesheetPtr topStyle = asctx->topStyle; xsltStylesheetPtr style = asctx->style; + if (asctx->error) { + if (style != topStyle) + xsltFreeAttrSet(set); + return; + } + xsltResolveAttrSet(set, topStyle, style, name, ns, 1); /* Move attribute sets to top stylesheet. */ @@ -675,6 +685,8 @@ xsltResolveSASCallback(void *payload, void *data, xsltGenericError(xsltGenericErrorContext, "xsl:attribute-set : internal error, can't move imported " " attribute set %s\n", name); + asctx->error = 1; + xsltFreeAttrSet(set); } } } @@ -695,6 +707,7 @@ xsltResolveStylesheetAttributeSet(xsltStylesheetPtr style) { "Resolving attribute sets references\n"); #endif asctx.topStyle = style; + asctx.error = 0; cur = style; while (cur != NULL) { if (cur->attributeSets != NULL) { diff --git a/libs/xslt/libxslt/attributes.h b/libs/xslt/libxslt/attributes.h index 05b8a6e938e..d9b99a74aa1 100644 --- a/libs/xslt/libxslt/attributes.h +++ b/libs/xslt/libxslt/attributes.h @@ -13,6 +13,7 @@ #include #include "xsltexports.h" +#include "xsltInternals.h" #ifdef __cplusplus extern "C" { diff --git a/libs/xslt/libxslt/attrvt.c b/libs/xslt/libxslt/attrvt.c index a885526e7ed..9d74a81b49c 100644 --- a/libs/xslt/libxslt/attrvt.c +++ b/libs/xslt/libxslt/attrvt.c @@ -154,12 +154,9 @@ xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val) { if (avt->nb_seg >= avt->max_seg) { size_t size = sizeof(xsltAttrVT) + (avt->max_seg + MAX_AVT_SEG) * sizeof(void *); - xsltAttrVTPtr tmp = (xsltAttrVTPtr) xmlRealloc(avt, size); - if (tmp == NULL) { - xsltFreeAttrVT(avt); + avt = (xsltAttrVTPtr) xmlRealloc(avt, size); + if (avt == NULL) return NULL; - } - avt = tmp; memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *)); avt->max_seg += MAX_AVT_SEG; } @@ -182,7 +179,8 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { const xmlChar *cur; xmlChar *ret = NULL; xmlChar *expr = NULL; - xsltAttrVTPtr avt; + xmlXPathCompExprPtr comp = NULL; + xsltAttrVTPtr avt, tmp; int i = 0, lastavt = 0; if ((style == NULL) || (attr == NULL) || (attr->children == NULL)) @@ -246,8 +244,9 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { str = cur; if (avt->nb_seg == 0) avt->strstart = 1; - if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL) + if ((tmp = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL) goto error; + avt = tmp; ret = NULL; lastavt = 0; } @@ -280,8 +279,6 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { XSLT_TODO goto error; } else { - xmlXPathCompExprPtr comp; - comp = xsltXPathCompile(style, expr); if (comp == NULL) { xsltTransformError(NULL, style, attr->parent, @@ -293,14 +290,23 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { if (avt->nb_seg == 0) avt->strstart = 0; if (lastavt == 1) { - if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL) + if ((tmp = xsltSetAttrVTsegment(avt, NULL)) == NULL) { + xsltTransformError(NULL, style, attr->parent, + "out of memory\n"); goto error; + } + avt = tmp; } - if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) + if ((tmp = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) { + xsltTransformError(NULL, style, attr->parent, + "out of memory\n"); goto error; + } + avt = tmp; lastavt = 1; xmlFree(expr); expr = NULL; + comp = NULL; } cur++; str = cur; @@ -325,8 +331,9 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { str = cur; if (avt->nb_seg == 0) avt->strstart = 1; - if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL) + if ((tmp = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL) goto error; + avt = tmp; ret = NULL; } @@ -350,6 +357,8 @@ error: xmlFree(ret); if (expr != NULL) xmlFree(expr); + if (comp != NULL) + xmlXPathFreeCompExpr(comp); } diff --git a/libs/xslt/libxslt/documents.c b/libs/xslt/libxslt/documents.c index 4aad11bbd1a..51865b859db 100644 --- a/libs/xslt/libxslt/documents.c +++ b/libs/xslt/libxslt/documents.c @@ -399,6 +399,8 @@ xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) { return(NULL); ret = xsltNewStyleDocument(style, doc); + if (ret == NULL) + xmlFreeDoc(doc); return(ret); } diff --git a/libs/xslt/libxslt/extensions.c b/libs/xslt/libxslt/extensions.c index ea5e83535f7..f9ca08e7db7 100644 --- a/libs/xslt/libxslt/extensions.c +++ b/libs/xslt/libxslt/extensions.c @@ -28,6 +28,7 @@ #include #include "xslt.h" #include "xsltInternals.h" +#include "xsltlocale.h" #include "xsltutils.h" #include "imports.h" #include "extensions.h" @@ -738,8 +739,11 @@ xsltStyleInitializeStylesheetModule(xsltStylesheetPtr style, * Store the user-data in the context of the given stylesheet. */ dataContainer = xsltNewExtData(module, userData); - if (dataContainer == NULL) + if (dataContainer == NULL) { + if (module->styleShutdownFunc) + module->styleShutdownFunc(style, URI, userData); return (NULL); + } if (xmlHashAddEntry(style->extInfos, URI, (void *) dataContainer) < 0) @@ -920,9 +924,8 @@ xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI) return (NULL); data = xsltNewExtData(module, extData); - if (data == NULL) - return (NULL); - if (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0) { + if ((data == NULL) || + (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0)) { xsltTransformError(ctxt, NULL, NULL, "Failed to register module data: %s\n", URI); @@ -994,6 +997,8 @@ xsltInitCtxtExt(void *payload, void *data, const xmlChar * URI) } ctxtData = xsltNewExtData(module, extData); if (ctxtData == NULL) { + if (module->shutdownFunc) + module->shutdownFunc(ctxt->ctxt, URI, extData); ctxt->ret = -1; return; } @@ -1001,6 +1006,9 @@ xsltInitCtxtExt(void *payload, void *data, const xmlChar * URI) if (ctxt->ctxt->extInfos == NULL) ctxt->ctxt->extInfos = xmlHashCreate(10); if (ctxt->ctxt->extInfos == NULL) { + if (module->shutdownFunc) + module->shutdownFunc(ctxt->ctxt, URI, extData); + xsltFreeExtData(ctxtData); ctxt->ret = -1; return; } diff --git a/libs/xslt/libxslt/functions.c b/libs/xslt/libxslt/functions.c index ed2b002362d..283ff24b858 100644 --- a/libs/xslt/libxslt/functions.c +++ b/libs/xslt/libxslt/functions.c @@ -242,14 +242,14 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) obj2 = valuePop(ctxt); } - if (ctxt->value->type == XPATH_NODESET) { + if ((ctxt->value != NULL) && (ctxt->value->type == XPATH_NODESET)) { int i; xmlXPathObjectPtr newobj, ret; obj = valuePop(ctxt); ret = xmlXPathNewNodeSet(NULL); - if ((obj != NULL) && obj->nodesetval) { + if ((obj != NULL) && (obj->nodesetval != NULL) && (ret != NULL)) { for (i = 0; i < obj->nodesetval->nodeNr; i++) { valuePush(ctxt, xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i])); @@ -261,11 +261,15 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) xmlXPathNewNodeSet(obj->nodesetval-> nodeTab[i])); } + if (ctxt->error) + break; xsltDocumentFunction(ctxt, 2); newobj = valuePop(ctxt); - ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, - newobj->nodesetval); - xmlXPathFreeObject(newobj); + if (newobj != NULL) { + ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, + newobj->nodesetval); + xmlXPathFreeObject(newobj); + } } } @@ -280,7 +284,7 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) * Make sure it's converted to a string */ xmlXPathStringFunction(ctxt, 1); - if (ctxt->value->type != XPATH_STRING) { + if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "document() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; @@ -379,6 +383,12 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr newobj, ret; ret = xmlXPathNewNodeSet(NULL); + if (ret == NULL) { + ctxt->error = XPATH_MEMORY_ERROR; + xmlXPathFreeObject(obj1); + xmlXPathFreeObject(obj2); + return; + } if (obj2->nodesetval != NULL) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) { @@ -388,8 +398,9 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathStringFunction(ctxt, 1); xsltKeyFunction(ctxt, 2); newobj = valuePop(ctxt); - ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, - newobj->nodesetval); + if (newobj != NULL) + ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, + newobj->nodesetval); xmlXPathFreeObject(newobj); } } @@ -446,13 +457,13 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ */ valuePush(ctxt, obj2); xmlXPathStringFunction(ctxt, 1); - if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { + obj2 = valuePop(ctxt); + if ((obj2 == NULL) || (obj2->type != XPATH_STRING)) { xsltTransformError(tctxt, NULL, tctxt->inst, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; goto error; } - obj2 = valuePop(ctxt); value = obj2->stringval; /* @@ -555,6 +566,10 @@ xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){ obj = valuePop(ctxt); if (obj->type != XPATH_STRING) { obj = xmlXPathConvertString(obj); + if (obj == NULL) { + xmlXPathErr(ctxt, XPATH_MEMORY_ERROR); + return; + } } str = obj->stringval; @@ -647,7 +662,8 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) return; } - if (formatValues != NULL) { + if ((ctxt->error == 0) && + (formatValues != NULL) && (formatObj != NULL) && (numberObj != NULL)) { if (xsltFormatNumberConversion(formatValues, formatObj->stringval, numberObj->floatval, @@ -672,11 +688,16 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) */ void xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ - static char base_address; + xsltTransformContextPtr tctxt; xmlNodePtr cur = NULL; xmlXPathObjectPtr obj = NULL; - long val; - xmlChar str[30]; + char *str; + const xmlChar *nsPrefix = NULL; + void **psviPtr; + unsigned long id; + size_t size, nsPrefixSize; + + tctxt = xsltXPathGetTransformContext(ctxt); if (nargs == 0) { cur = ctxt->context->node; @@ -686,16 +707,15 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { ctxt->error = XPATH_INVALID_TYPE; - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + xsltTransformError(tctxt, NULL, NULL, "generate-id() : invalid arg expecting a node-set\n"); - return; + goto out; } obj = valuePop(ctxt); nodelist = obj->nodesetval; if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { - xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewCString("")); - return; + goto out; } cur = nodelist->nodeTab[0]; for (i = 1;i < nodelist->nodeNr;i++) { @@ -704,22 +724,93 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ cur = nodelist->nodeTab[i]; } } else { - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, + xsltTransformError(tctxt, NULL, NULL, "generate-id() : invalid number of args %d\n", nargs); ctxt->error = XPATH_INVALID_ARITY; - return; + goto out; } - if (obj) - xmlXPathFreeObject(obj); + size = 30; /* for "id%lu" */ + + if (cur->type == XML_NAMESPACE_DECL) { + xmlNsPtr ns = (xmlNsPtr) cur; - val = (long)((char *)cur - (char *)&base_address); - if (val >= 0) { - snprintf((char *)str, sizeof(str), "idp%ld", val); + nsPrefix = ns->prefix; + if (nsPrefix == NULL) + nsPrefix = BAD_CAST ""; + nsPrefixSize = xmlStrlen(nsPrefix); + /* For "ns" and hex-encoded string */ + size += nsPrefixSize * 2 + 2; + + /* Parent is stored in 'next'. */ + cur = (xmlNodePtr) ns->next; + } + + psviPtr = xsltGetPSVIPtr(cur); + if (psviPtr == NULL) { + xsltTransformError(tctxt, NULL, NULL, + "generate-id(): invalid node type %d\n", cur->type); + ctxt->error = XPATH_INVALID_TYPE; + goto out; + } + + if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) { + id = (unsigned long) (size_t) *psviPtr; } else { - snprintf((char *)str, sizeof(str), "idm%ld", -val); + if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) { + /* Text nodes store big line numbers in psvi. */ + cur->line = 0; + } else if (*psviPtr != NULL) { + xsltTransformError(tctxt, NULL, NULL, + "generate-id(): psvi already set\n"); + ctxt->error = XPATH_MEMORY_ERROR; + goto out; + } + + if (tctxt->currentId == ULONG_MAX) { + xsltTransformError(tctxt, NULL, NULL, + "generate-id(): id overflow\n"); + ctxt->error = XPATH_MEMORY_ERROR; + goto out; + } + + id = ++tctxt->currentId; + *psviPtr = (void *) (size_t) id; + xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID); } - valuePush(ctxt, xmlXPathNewString(str)); + + str = xmlMalloc(size); + if (str == NULL) { + xsltTransformError(tctxt, NULL, NULL, + "generate-id(): out of memory\n"); + ctxt->error = XPATH_MEMORY_ERROR; + goto out; + } + if (nsPrefix == NULL) { + snprintf(str, size, "id%lu", id); + } else { + size_t i, j; + + snprintf(str, size, "id%luns", id); + + /* + * Only ASCII alphanumerics are allowed, so we hex-encode the prefix. + */ + j = strlen(str); + for (i = 0; i < nsPrefixSize; i++) { + int v; + + v = nsPrefix[i] >> 4; + str[j++] = v < 10 ? '0' + v : 'A' + (v - 10); + v = nsPrefix[i] & 15; + str[j++] = v < 10 ? '0' + v : 'A' + (v - 10); + } + str[j] = '\0'; + } + valuePush(ctxt, xmlXPathWrapString(BAD_CAST str)); + +out: + xmlXPathFreeObject(obj); } /** diff --git a/libs/xslt/libxslt/imports.c b/libs/xslt/libxslt/imports.c index 4f5de03fa3f..bf2196e9936 100644 --- a/libs/xslt/libxslt/imports.c +++ b/libs/xslt/libxslt/imports.c @@ -53,6 +53,35 @@ static void xsltFixImportedCompSteps(xsltStylesheetPtr master, } } +static int +xsltCheckCycle(xsltStylesheetPtr style, const xmlChar *URI) { + xsltStylesheetPtr ancestor; + xsltDocumentPtr docptr; + + /* + * in order to detect recursion, we check all previously included + * stylesheets. + */ + docptr = style->includes; + while (docptr != NULL) { + if (xmlStrEqual(docptr->doc->URL, URI)) + return(-1); + docptr = docptr->includes; + } + + /* + * Also check imported stylesheets. + */ + ancestor = style; + while (ancestor != NULL) { + if (xmlStrEqual(ancestor->doc->URL, URI)) + return(-1); + ancestor = ancestor->parent; + } + + return(0); +} + /** * xsltParseStylesheetImport: * @style: the XSLT stylesheet @@ -91,16 +120,10 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) { goto error; } - res = style; - while (res != NULL) { - if (res->doc == NULL) - break; - if (xmlStrEqual(res->doc->URL, URI)) { - xsltTransformError(NULL, style, cur, - "xsl:import : recursion detected on imported URL %s\n", URI); - goto error; - } - res = res->parent; + if (xsltCheckCycle(style, URI) < 0) { + xsltTransformError(NULL, style, cur, + "xsl:import : recursion detected on imported URL %s\n", URI); + goto error; } /* @@ -170,7 +193,6 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) { xmlChar *URI = NULL; xsltStylesheetPtr result; xsltDocumentPtr include; - xsltDocumentPtr docptr; int oldNopreproc; if ((cur == NULL) || (style == NULL)) @@ -191,18 +213,10 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) { goto error; } - /* - * in order to detect recursion, we check all previously included - * stylesheets. - */ - docptr = style->includes; - while (docptr != NULL) { - if (xmlStrEqual(docptr->doc->URL, URI)) { - xsltTransformError(NULL, style, cur, - "xsl:include : recursion detected on included URL %s\n", URI); - goto error; - } - docptr = docptr->includes; + if (xsltCheckCycle(style, URI) < 0) { + xsltTransformError(NULL, style, cur, + "xsl:include : recursion detected on included URL %s\n", URI); + goto error; } include = xsltLoadStyleDocument(style, URI); diff --git a/libs/xslt/libxslt/keys.c b/libs/xslt/libxslt/keys.c index ca0779c5be2..f23cc4e9fca 100644 --- a/libs/xslt/libxslt/keys.c +++ b/libs/xslt/libxslt/keys.c @@ -294,6 +294,8 @@ xsltAddKey(xsltStylesheetPtr style, const xmlChar *name, #endif key = xsltNewKeyDef(name, nameURI); + if (key == NULL) + return(-1); key->match = xmlStrdup(match); key->use = xmlStrdup(use); key->inst = inst; @@ -827,31 +829,17 @@ fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel); keylist = xmlXPathNodeSetCreate(cur); if (keylist == NULL) goto error; - xmlHashAddEntry(table->keys, str, keylist); + if (xmlHashAddEntry(table->keys, str, keylist) < 0) { + xmlXPathFreeNodeSet(keylist); + goto error; + } } else { /* * TODO: How do we know if this function failed? */ xmlXPathNodeSetAdd(keylist, cur); } - switch (cur->type) { - case XML_ELEMENT_NODE: - case XML_TEXT_NODE: - case XML_CDATA_SECTION_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: - cur->psvi = keyDef; - break; - case XML_ATTRIBUTE_NODE: - ((xmlAttrPtr) cur)->psvi = keyDef; - break; - case XML_DOCUMENT_NODE: - case XML_HTML_DOCUMENT_NODE: - ((xmlDocPtr) cur)->psvi = keyDef; - break; - default: - break; - } + xsltSetSourceNodeFlags(ctxt, cur, XSLT_SOURCE_NODE_HAS_KEY); xmlFree(str); str = NULL; diff --git a/libs/xslt/libxslt/numbers.c b/libs/xslt/libxslt/numbers.c index 9c74f0d48d5..3cd881e3c8d 100644 --- a/libs/xslt/libxslt/numbers.c +++ b/libs/xslt/libxslt/numbers.c @@ -116,7 +116,7 @@ xsltIsLetterDigit(int val) { #define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1) static int -xsltIsDigitZero(unsigned int ch) +xsltIsDigitZero(int ch) { /* * Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt @@ -183,7 +183,7 @@ xsltNumberFormatDecimal(xmlBufferPtr buffer, i = -1; break; } - *(--pointer) = (xmlChar)val; + *(--pointer) = val; } else { /* @@ -353,8 +353,7 @@ xsltNumberFormatTokenize(const xmlChar *format, * Insert initial non-alphanumeric token. * There is always such a token in the list, even if NULL */ - while (!xsltIsLetterDigit(val = xmlStringCurrentChar(NULL, format+ix, - &len))) { + while (!xsltIsLetterDigit(val = xsltGetUTF8CharZ(format+ix, &len))) { if (format[ix] == 0) /* if end of format string */ break; /* while */ ix += len; @@ -377,19 +376,19 @@ xsltNumberFormatTokenize(const xmlChar *format, tokens->end = NULL; } - val = xmlStringCurrentChar(NULL, format+ix, &len); + val = xsltGetUTF8CharZ(format+ix, &len); if (IS_DIGIT_ONE(val) || IS_DIGIT_ZERO(val)) { tokens->tokens[tokens->nTokens].width = 1; while (IS_DIGIT_ZERO(val)) { tokens->tokens[tokens->nTokens].width++; ix += len; - val = xmlStringCurrentChar(NULL, format+ix, &len); + val = xsltGetUTF8CharZ(format+ix, &len); } if (IS_DIGIT_ONE(val)) { tokens->tokens[tokens->nTokens].token = val - 1; ix += len; - val = xmlStringCurrentChar(NULL, format+ix, &len); + val = xsltGetUTF8CharZ(format+ix, &len); } else { tokens->tokens[tokens->nTokens].token = '0'; tokens->tokens[tokens->nTokens].width = 1; @@ -400,7 +399,7 @@ xsltNumberFormatTokenize(const xmlChar *format, (val == 'i') ) { tokens->tokens[tokens->nTokens].token = val; ix += len; - val = xmlStringCurrentChar(NULL, format+ix, &len); + val = xsltGetUTF8CharZ(format+ix, &len); } else { /* XSLT section 7.7 * "Any other format token indicates a numbering sequence @@ -422,7 +421,7 @@ xsltNumberFormatTokenize(const xmlChar *format, */ while (xsltIsLetterDigit(val)) { ix += len; - val = xmlStringCurrentChar(NULL, format+ix, &len); + val = xsltGetUTF8CharZ(format+ix, &len); } /* @@ -433,7 +432,7 @@ xsltNumberFormatTokenize(const xmlChar *format, if (val == 0) break; /* while */ ix += len; - val = xmlStringCurrentChar(NULL, format+ix, &len); + val = xsltGetUTF8CharZ(format+ix, &len); } if (ix > j) tokens->end = xmlStrndup(&format[j], ix - j); @@ -965,6 +964,7 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self, xmlChar *the_format, *prefix = NULL, *suffix = NULL; xmlChar *nprefix, *nsuffix = NULL; int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length; + int exp10; double scale; int j, len = 0; int self_grouping_len; @@ -985,32 +985,12 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self, "Invalid format (0-length)\n"); } *result = NULL; - switch (xmlXPathIsInf(number)) { - case -1: - if (self->minusSign == NULL) - *result = xmlStrdup(BAD_CAST "-"); - else - *result = xmlStrdup(self->minusSign); - /* Intentional fall-through */ - case 1: - if ((self == NULL) || (self->infinity == NULL)) - *result = xmlStrcat(*result, BAD_CAST "Infinity"); - else - *result = xmlStrcat(*result, self->infinity); - return(status); - default: - if (xmlXPathIsNaN(number)) { - if ((self == NULL) || (self->noNumber == NULL)) - *result = xmlStrdup(BAD_CAST "NaN"); - else - *result = xmlStrdup(self->noNumber); - return(status); - } - } - - buffer = xmlBufferCreate(); - if (buffer == NULL) { - return XPATH_MEMORY_ERROR; + if (xmlXPathIsNaN(number)) { + if ((self == NULL) || (self->noNumber == NULL)) + *result = xmlStrdup(BAD_CAST "NaN"); + else + *result = xmlStrdup(self->noNumber); + return(status); } format_info.integer_hash = 0; @@ -1283,6 +1263,30 @@ OUTPUT_NUMBER: format_info.add_decimal = TRUE; } + /* Apply multiplier */ + number *= (double)format_info.multiplier; + switch (xmlXPathIsInf(number)) { + case -1: + if (self->minusSign == NULL) + *result = xmlStrdup(BAD_CAST "-"); + else + *result = xmlStrdup(self->minusSign); + /* Intentional fall-through */ + case 1: + if ((self == NULL) || (self->infinity == NULL)) + *result = xmlStrcat(*result, BAD_CAST "Infinity"); + else + *result = xmlStrcat(*result, self->infinity); + return(status); + default: + break; + } + + buffer = xmlBufferCreate(); + if (buffer == NULL) { + return XPATH_MEMORY_ERROR; + } + /* Ready to output our number. First see if "default sign" is required */ if (default_sign != 0) xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1)); @@ -1297,10 +1301,24 @@ OUTPUT_NUMBER: j += len; } + /* Round to n digits */ + number = fabs(number); + exp10 = format_info.frac_digits + format_info.frac_hash; + /* DBL_MAX_10_EXP should be 308 on IEEE platforms. */ + if (exp10 > DBL_MAX_10_EXP) { + if (format_info.frac_digits > DBL_MAX_10_EXP) { + format_info.frac_digits = DBL_MAX_10_EXP; + format_info.frac_hash = 0; + } else { + format_info.frac_hash = DBL_MAX_10_EXP - format_info.frac_digits; + } + exp10 = DBL_MAX_10_EXP; + } + scale = pow(10.0, (double) exp10); + number += .5 / scale; + number -= fmod(number, 1 / scale); + /* Next do the integer part of the number */ - number = fabs(number) * (double)format_info.multiplier; - scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash)); - number = floor((scale * number + 0.5)) / scale; if ((self->grouping != NULL) && (self->grouping[0] != 0)) { int gchar; diff --git a/libs/xslt/libxslt/pattern.c b/libs/xslt/libxslt/pattern.c index da3444f230e..581f17919fe 100644 --- a/libs/xslt/libxslt/pattern.c +++ b/libs/xslt/libxslt/pattern.c @@ -311,10 +311,6 @@ xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp, "xsltCompMatchAdd: memory re-allocation failure.\n"); if (ctxt->style != NULL) ctxt->style->errors++; - if (value) - xmlFree(value); - if (value2) - xmlFree(value2); return (-1); } comp->maxStep *= 2; @@ -483,16 +479,12 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) { static int xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, int step, xmlNodePtr node) { - if ((states->states == NULL) || (states->maxstates <= 0)) { - states->maxstates = 4; - states->nbstates = 0; - states->states = xmlMalloc(4 * sizeof(xsltStepState)); - } - else if (states->maxstates <= states->nbstates) { + if (states->maxstates <= states->nbstates) { xsltStepState *tmp; + int newMax = states->maxstates == 0 ? 4 : 2 * states->maxstates; tmp = (xsltStepStatePtr) xmlRealloc(states->states, - 2 * states->maxstates * sizeof(xsltStepState)); + newMax * sizeof(xsltStepState)); if (tmp == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltPatPushState: memory re-allocation failure.\n"); @@ -500,7 +492,7 @@ xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, return(-1); } states->states = tmp; - states->maxstates *= 2; + states->maxstates = newMax; } states->states[states->nbstates].step = step; states->states[states->nbstates++].node = node; @@ -1234,10 +1226,10 @@ xsltScanLiteral(xsltParserContextPtr ctxt) { if (CUR == '"') { NEXT; cur = q = CUR_PTR; - val = xmlStringCurrentChar(NULL, cur, &len); + val = xsltGetUTF8CharZ(cur, &len); while ((xmlIsCharQ(val)) && (val != '"')) { cur += len; - val = xmlStringCurrentChar(NULL, cur, &len); + val = xsltGetUTF8CharZ(cur, &len); } if (!xmlIsCharQ(val)) { ctxt->error = 1; @@ -1250,10 +1242,10 @@ xsltScanLiteral(xsltParserContextPtr ctxt) { } else if (CUR == '\'') { NEXT; cur = q = CUR_PTR; - val = xmlStringCurrentChar(NULL, cur, &len); + val = xsltGetUTF8CharZ(cur, &len); while ((xmlIsCharQ(val)) && (val != '\'')) { cur += len; - val = xmlStringCurrentChar(NULL, cur, &len); + val = xsltGetUTF8CharZ(cur, &len); } if (!xmlIsCharQ(val)) { ctxt->error = 1; @@ -1288,7 +1280,7 @@ xsltScanNCName(xsltParserContextPtr ctxt) { SKIP_BLANKS; cur = q = CUR_PTR; - val = xmlStringCurrentChar(NULL, cur, &len); + val = xsltGetUTF8CharZ(cur, &len); if (!xmlIsBaseCharQ(val) && !xmlIsIdeographicQ(val) && (val != '_')) return(NULL); @@ -1299,7 +1291,7 @@ xsltScanNCName(xsltParserContextPtr ctxt) { xmlIsCombiningQ(val) || xmlIsExtenderQ(val)) { cur += len; - val = xmlStringCurrentChar(NULL, cur, &len); + val = xsltGetUTF8CharZ(cur, &len); } ret = xmlStrndup(q, cur - q); CUR_PTR = cur; @@ -1512,6 +1504,7 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) { xmlChar *name = NULL; const xmlChar *URI = NULL; xmlChar *URL = NULL; + xmlChar *ret = NULL; int level; xsltAxis axis = 0; @@ -1588,7 +1581,6 @@ parse_node_test: xsltTransformError(NULL, NULL, NULL, "xsltCompileStepPattern : Name expected\n"); ctxt->error = 1; - xmlFree(URL); goto error; } } else { @@ -1651,7 +1643,6 @@ parse_predicate: level = 0; while (CUR == '[') { const xmlChar *q; - xmlChar *ret = NULL; level++; NEXT; @@ -1695,6 +1686,10 @@ error: xmlFree(token); if (name != NULL) xmlFree(name); + if (URL != NULL) + xmlFree(URL); + if (ret != NULL) + xmlFree(ret); } /** @@ -2087,6 +2082,8 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, if (pat == NULL) return(-1); while (pat) { + int success = 0; + next = pat->next; pat->next = NULL; name = NULL; @@ -2158,17 +2155,15 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, if (name != NULL) { if (style->templatesHash == NULL) { style->templatesHash = xmlHashCreate(1024); - if (style->templatesHash == NULL) { - xsltFreeCompMatch(pat); - return(-1); - } - xmlHashAddEntry3(style->templatesHash, name, mode, modeURI, pat); + success = (style->templatesHash != NULL) && + (xmlHashAddEntry3(style->templatesHash, name, mode, + modeURI, pat) >= 0); } else { list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash, name, mode, modeURI); if (list == NULL) { - xmlHashAddEntry3(style->templatesHash, name, - mode, modeURI, pat); + success = (xmlHashAddEntry3(style->templatesHash, name, + mode, modeURI, pat) >= 0); } else { /* * Note '<=' since one must choose among the matching @@ -2188,6 +2183,7 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, pat->next = list->next; list->next = pat; } + success = 1; } } } else if (top != NULL) { @@ -2207,10 +2203,13 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, pat->next = list->next; list->next = pat; } - } else { + success = 1; + } + if (success == 0) { xsltTransformError(NULL, style, NULL, "xsltAddTemplate: invalid compiled pattern\n"); xsltFreeCompMatch(pat); + xsltFreeCompMatchList(next); return(-1); } #ifdef WITH_XSLT_DEBUG_PATTERN @@ -2283,7 +2282,6 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, const xmlChar *name = NULL; xsltCompMatchPtr list = NULL; float priority; - int keyed = 0; if ((ctxt == NULL) || (node == NULL)) return(NULL); @@ -2361,37 +2359,25 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, list = curstyle->rootMatch; else list = curstyle->elemMatch; - if (node->psvi != NULL) keyed = 1; break; case XML_ATTRIBUTE_NODE: { - xmlAttrPtr attr; - list = curstyle->attrMatch; - attr = (xmlAttrPtr) node; - if (attr->psvi != NULL) keyed = 1; break; } case XML_PI_NODE: list = curstyle->piMatch; - if (node->psvi != NULL) keyed = 1; break; case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: { - xmlDocPtr doc; - list = curstyle->rootMatch; - doc = (xmlDocPtr) node; - if (doc->psvi != NULL) keyed = 1; break; } case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: list = curstyle->textMatch; - if (node->psvi != NULL) keyed = 1; break; case XML_COMMENT_NODE: list = curstyle->commentMatch; - if (node->psvi != NULL) keyed = 1; break; case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: @@ -2461,7 +2447,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, } keyed_match: - if (keyed) { + if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY) { list = curstyle->keyMatch; while ((list != NULL) && ((ret == NULL) || @@ -2489,27 +2475,7 @@ keyed_match: if (xsltComputeAllKeys(ctxt, node) == -1) goto error; - switch (node->type) { - case XML_ELEMENT_NODE: - if (node->psvi != NULL) keyed = 1; - break; - case XML_ATTRIBUTE_NODE: - if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1; - break; - case XML_TEXT_NODE: - case XML_CDATA_SECTION_NODE: - case XML_COMMENT_NODE: - case XML_PI_NODE: - if (node->psvi != NULL) keyed = 1; - break; - case XML_DOCUMENT_NODE: - case XML_HTML_DOCUMENT_NODE: - if (((xmlDocPtr) node)->psvi != NULL) keyed = 1; - break; - default: - break; - } - if (keyed) + if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY) goto keyed_match; } if (ret != NULL) diff --git a/libs/xslt/libxslt/preproc.c b/libs/xslt/libxslt/preproc.c index 7d2fa2213fc..fae69a09d48 100644 --- a/libs/xslt/libxslt/preproc.c +++ b/libs/xslt/libxslt/preproc.c @@ -392,8 +392,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) { break; case XSLT_FUNC_SORT: { xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp; - if (item->locale != (xsltLocale)0) - xsltFreeLocale(item->locale); if (item->comp != NULL) xmlXPathFreeCompExpr(item->comp); } @@ -496,8 +494,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) { break; } #else - if (comp->locale != (xsltLocale)0) - xsltFreeLocale(comp->locale); if (comp->comp != NULL) xmlXPathFreeCompExpr(comp->comp); if (comp->numdata.countPat != NULL) @@ -743,12 +739,6 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { comp->lang = xsltEvalStaticAttrValueTemplate(style, inst, (const xmlChar *)"lang", NULL, &comp->has_lang); - if (comp->lang != NULL) { - comp->locale = xsltNewLocale(comp->lang); - } - else { - comp->locale = (xsltLocale)0; - } comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); if (comp->select == NULL) { diff --git a/libs/xslt/libxslt/templates.c b/libs/xslt/libxslt/templates.c index 4108ed26e47..f08b9bda418 100644 --- a/libs/xslt/libxslt/templates.c +++ b/libs/xslt/libxslt/templates.c @@ -151,7 +151,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp, if (res != NULL) { if (res->type != XPATH_STRING) res = xmlXPathConvertString(res); - if (res->type == XPATH_STRING) { + if ((res != NULL) && (res->type == XPATH_STRING)) { ret = res->stringval; res->stringval = NULL; } else { @@ -229,7 +229,7 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt, insert = xmlNewDocNode(ctxt->output, NULL, (const xmlChar *)"fake", NULL); if (insert == NULL) { - xsltTransformError(ctxt, NULL, contextNode, + xsltTransformError(ctxt, NULL, inst, "Failed to create temporary node\n"); return(NULL); } diff --git a/libs/xslt/libxslt/transform.c b/libs/xslt/libxslt/transform.c index cb43bb47d99..0fc0400c1f9 100644 --- a/libs/xslt/libxslt/transform.c +++ b/libs/xslt/libxslt/transform.c @@ -40,6 +40,7 @@ #include "xslt.h" #include "xsltInternals.h" #include "xsltutils.h" +#include "xsltlocale.h" #include "pattern.h" #include "transform.h" #include "variables.h" @@ -119,26 +120,18 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, static int templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value) { - if (ctxt->templMax == 0) { - ctxt->templMax = 4; - ctxt->templTab = - (xsltTemplatePtr *) xmlMalloc(ctxt->templMax * - sizeof(ctxt->templTab[0])); - if (ctxt->templTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (0); - } - } - else if (ctxt->templNr >= ctxt->templMax) { - ctxt->templMax *= 2; - ctxt->templTab = - (xsltTemplatePtr *) xmlRealloc(ctxt->templTab, - ctxt->templMax * - sizeof(ctxt->templTab[0])); - if (ctxt->templTab == NULL) { + if (ctxt->templNr >= ctxt->templMax) { + xsltTemplatePtr *tmp; + int newMax = ctxt->templMax == 0 ? 4 : ctxt->templMax * 2; + + tmp = (xsltTemplatePtr *) xmlRealloc(ctxt->templTab, + newMax * sizeof(*tmp)); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); return (0); } + ctxt->templTab = tmp; + ctxt->templMax = newMax; } ctxt->templTab[ctxt->templNr] = value; ctxt->templ = value; @@ -492,7 +485,7 @@ void xsltDebugSetDefaultTrace(xsltDebugTraceCodes val) { * * Returns the current default debug tracing level mask */ -xsltDebugTraceCodes xsltDebugGetDefaultTrace() { +xsltDebugTraceCodes xsltDebugGetDefaultTrace(void) { return xsltDefaultTrace; } @@ -706,6 +699,10 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { cur->xinclude = xsltGetXIncludeDefault(); cur->keyInitLevel = 0; + cur->newLocale = xsltNewLocale; + cur->freeLocale = xsltFreeLocale; + cur->genSortKey = xsltStrxfrm; + return(cur); internal_err: @@ -716,7 +713,7 @@ internal_err: /** * xsltFreeTransformContext: - * @ctxt: an XSLT parser context + * @ctxt: an XSLT transform context * * Free up the memory allocated by @ctxt */ @@ -1090,8 +1087,10 @@ xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target, if (xmlDictOwns(ctxt->dict, cur->content)) copy->content = cur->content; else { - if ((copy->content = xmlStrdup(cur->content)) == NULL) + if ((copy->content = xmlStrdup(cur->content)) == NULL) { + xmlFreeNode(copy); return NULL; + } } ctxt->lasttext = NULL; @@ -2224,26 +2223,18 @@ xsltLocalVariablePush(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, int level) { - if (ctxt->varsMax == 0) { - ctxt->varsMax = 10; - ctxt->varsTab = - (xsltStackElemPtr *) xmlMalloc(ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (-1); - } - } if (ctxt->varsNr >= ctxt->varsMax) { - ctxt->varsMax *= 2; - ctxt->varsTab = - (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, - ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { + xsltStackElemPtr *tmp; + int newMax = ctxt->varsMax == 0 ? 10 : 2 * ctxt->varsMax; + + tmp = (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, + newMax * sizeof(*tmp)); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); return (-1); } + ctxt->varsTab = tmp; + ctxt->varsMax = newMax; } ctxt->varsTab[ctxt->varsNr++] = variable; ctxt->vars = variable; @@ -2275,17 +2266,17 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base) do { tmp = cur; cur = (xmlDocPtr) cur->next; - if (tmp->psvi == XSLT_RVT_LOCAL) { + if (tmp->compression == XSLT_RVT_LOCAL) { xsltReleaseRVT(ctxt, tmp); - } else if (tmp->psvi == XSLT_RVT_GLOBAL) { + } else if (tmp->compression == XSLT_RVT_GLOBAL) { xsltRegisterPersistRVT(ctxt, tmp); - } else if (tmp->psvi == XSLT_RVT_FUNC_RESULT) { + } else if (tmp->compression == XSLT_RVT_FUNC_RESULT) { /* * This will either register the RVT again or move it to the * context variable. */ xsltRegisterLocalRVT(ctxt, tmp); - tmp->psvi = XSLT_RVT_FUNC_RESULT; + tmp->compression = XSLT_RVT_FUNC_RESULT; } else { xmlGenericError(xmlGenericErrorContext, "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n", @@ -5747,6 +5738,49 @@ xsltCountKeys(xsltTransformContextPtr ctxt) } /** + * xsltCleanupSourceDoc: + * @doc: Document + * + * Resets source node flags and ids stored in 'psvi' member. + */ +static void +xsltCleanupSourceDoc(xmlDocPtr doc) { + xmlNodePtr cur = (xmlNodePtr) doc; + void **psviPtr; + + while (1) { + xsltClearSourceNodeFlags(cur, XSLT_SOURCE_NODE_MASK); + psviPtr = xsltGetPSVIPtr(cur); + if (psviPtr) + *psviPtr = NULL; + + if (cur->type == XML_ELEMENT_NODE) { + xmlAttrPtr prop = cur->properties; + + while (prop) { + prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27); + prop->psvi = NULL; + prop = prop->next; + } + } + + if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) { + cur = cur->children; + } else { + if (cur == (xmlNodePtr) doc) + return; + while (cur->next == NULL) { + cur = cur->parent; + if (cur == (xmlNodePtr) doc) + return; + } + + cur = cur->next; + } + } +} + +/** * xsltApplyStylesheetInternal: * @style: a parsed XSLT stylesheet * @doc: a parsed XML document @@ -6144,6 +6178,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc, printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars); #endif + if (ctxt->sourceDocDirty) + xsltCleanupSourceDoc(doc); + if ((ctxt != NULL) && (userCtxt == NULL)) xsltFreeTransformContext(ctxt); diff --git a/libs/xslt/libxslt/variables.c b/libs/xslt/libxslt/variables.c index 60341d55f30..c0055c21b60 100644 --- a/libs/xslt/libxslt/variables.c +++ b/libs/xslt/libxslt/variables.c @@ -123,7 +123,7 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) return(-1); RVT->prev = NULL; - RVT->psvi = XSLT_RVT_LOCAL; + RVT->compression = XSLT_RVT_LOCAL; /* * We'll restrict the lifetime of user-created fragments @@ -163,7 +163,7 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt, return(-1); RVT->prev = NULL; - RVT->psvi = XSLT_RVT_LOCAL; + RVT->compression = XSLT_RVT_LOCAL; /* * When evaluating "select" expressions of xsl:variable @@ -255,7 +255,7 @@ xsltExtensionInstructionResultRegister( * Returns 0 in case of success and -1 in case of error. */ int -xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) { +xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, int val) { int i; xmlNodePtr cur; xmlDocPtr doc; @@ -302,34 +302,36 @@ xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) { return(-1); } if (doc->name && (doc->name[0] == ' ') && - doc->psvi != XSLT_RVT_GLOBAL) { + doc->compression != XSLT_RVT_GLOBAL) { /* * This is a result tree fragment. - * We store ownership information in the @psvi field. + * We store ownership information in the @compression field. * TODO: How do we know if this is a doc acquired via the * document() function? */ #ifdef WITH_XSLT_DEBUG_VARIABLE - XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext, - "Flagging RVT %p: %p -> %p\n", doc, doc->psvi, val)); + XSLT_TRACE(ctxt, XSLT_TRACE_VARIABLES, + xsltGenericDebug(xsltGenericDebugContext, + "Flagging RVT %p: %d -> %d\n", + (void *) doc, doc->compression, val)); #endif if (val == XSLT_RVT_LOCAL) { - if (doc->psvi == XSLT_RVT_FUNC_RESULT) - doc->psvi = XSLT_RVT_LOCAL; + if (doc->compression == XSLT_RVT_FUNC_RESULT) + doc->compression = XSLT_RVT_LOCAL; } else if (val == XSLT_RVT_GLOBAL) { - if (doc->psvi != XSLT_RVT_LOCAL) { + if (doc->compression != XSLT_RVT_LOCAL) { xmlGenericError(xmlGenericErrorContext, - "xsltFlagRVTs: Invalid transition %p => GLOBAL\n", - doc->psvi); - doc->psvi = XSLT_RVT_GLOBAL; + "xsltFlagRVTs: Invalid transition %d => GLOBAL\n", + doc->compression); + doc->compression = XSLT_RVT_GLOBAL; return(-1); } /* Will be registered as persistant in xsltReleaseLocalRVTs. */ - doc->psvi = XSLT_RVT_GLOBAL; + doc->compression = XSLT_RVT_GLOBAL; } else if (val == XSLT_RVT_FUNC_RESULT) { - doc->psvi = val; + doc->compression = val; } } } @@ -377,7 +379,7 @@ xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) /* * Reset the ownership information. */ - RVT->psvi = NULL; + RVT->compression = 0; RVT->next = (xmlNodePtr) ctxt->cache->RVT; ctxt->cache->RVT = RVT; @@ -416,7 +418,7 @@ xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) { if ((ctxt == NULL) || (RVT == NULL)) return(-1); - RVT->psvi = XSLT_RVT_GLOBAL; + RVT->compression = XSLT_RVT_GLOBAL; RVT->prev = NULL; RVT->next = (xmlNodePtr) ctxt->persistRVT; if (ctxt->persistRVT != NULL) @@ -575,15 +577,15 @@ xsltFreeStackElem(xsltStackElemPtr elem) { cur = elem->fragment; elem->fragment = (xmlDocPtr) cur->next; - if (cur->psvi == XSLT_RVT_LOCAL) { + if (cur->compression == XSLT_RVT_LOCAL) { xsltReleaseRVT(elem->context, cur); - } else if (cur->psvi == XSLT_RVT_FUNC_RESULT) { + } else if (cur->compression == XSLT_RVT_FUNC_RESULT) { xsltRegisterLocalRVT(elem->context, cur); - cur->psvi = XSLT_RVT_FUNC_RESULT; + cur->compression = XSLT_RVT_FUNC_RESULT; } else { xmlGenericError(xmlGenericErrorContext, - "xsltFreeStackElem: Unexpected RVT flag %p\n", - cur->psvi); + "xsltFreeStackElem: Unexpected RVT flag %d\n", + cur->compression); } } } @@ -755,26 +757,18 @@ xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) return(-1); do { - if (ctxt->varsMax == 0) { - ctxt->varsMax = 10; - ctxt->varsTab = - (xsltStackElemPtr *) xmlMalloc(ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (-1); - } - } if (ctxt->varsNr >= ctxt->varsMax) { - ctxt->varsMax *= 2; - ctxt->varsTab = - (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, - ctxt->varsMax * - sizeof(ctxt->varsTab[0])); - if (ctxt->varsTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); - return (-1); - } + xsltStackElemPtr *tmp; + int newMax = ctxt->varsMax == 0 ? 10 : 2 * ctxt->varsMax; + + tmp = (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab, + newMax * sizeof(*tmp)); + if (tmp == NULL) { + xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); + return (-1); + } + ctxt->varsTab = tmp; + ctxt->varsMax = newMax; } ctxt->varsTab[ctxt->varsNr++] = elem; ctxt->vars = elem; @@ -986,7 +980,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, * the Result Tree Fragment. */ variable->fragment = container; - container->psvi = XSLT_RVT_LOCAL; + container->compression = XSLT_RVT_LOCAL; oldOutput = ctxt->output; oldInsert = ctxt->insert; @@ -1316,8 +1310,13 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) { if (def == NULL) { def = xsltCopyStackElem(elem); - xmlHashAddEntry2(ctxt->globalVars, - elem->name, elem->nameURI, def); + if (xmlHashAddEntry2(ctxt->globalVars, + elem->name, elem->nameURI, def) < 0) { + xmlGenericError(xmlGenericErrorContext, + "hash update failed\n"); + xsltFreeStackElem(def); + return(-1); + } } else if ((elem->comp != NULL) && (elem->comp->type == XSLT_FUNC_VARIABLE)) { /* @@ -1681,7 +1680,7 @@ xsltProcessUserParamInternal(xsltTransformContextPtr ctxt, int xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { - int indx = 0; + size_t indx = 0; const xmlChar *name; const xmlChar *value; @@ -1711,7 +1710,7 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { int xsltQuoteUserParams(xsltTransformContextPtr ctxt, const char **params) { - int indx = 0; + size_t indx = 0; const xmlChar *name; const xmlChar *value; @@ -1875,7 +1874,10 @@ xsltRegisterVariable(xsltTransformContextPtr ctxt, #endif /* else of XSLT_REFACTORED */ variable = xsltBuildVariable(ctxt, (xsltStylePreCompPtr) comp, tree); - xsltAddStackElem(ctxt, variable); + if (xsltAddStackElem(ctxt, variable) < 0) { + xsltFreeStackElem(variable); + return(-1); + } return(0); } diff --git a/libs/xslt/libxslt/variables.h b/libs/xslt/libxslt/variables.h index 039288fbd50..e2adee0f755 100644 --- a/libs/xslt/libxslt/variables.h +++ b/libs/xslt/libxslt/variables.h @@ -43,7 +43,7 @@ extern "C" { * * RVT is destroyed after the current instructions ends. */ -#define XSLT_RVT_LOCAL ((void *)1) +#define XSLT_RVT_LOCAL 1 /** * XSLT_RVT_FUNC_RESULT: @@ -52,14 +52,14 @@ extern "C" { * destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or * XSLT_RVT_VARIABLE in the template that receives the return value. */ -#define XSLT_RVT_FUNC_RESULT ((void *)2) +#define XSLT_RVT_FUNC_RESULT 2 /** * XSLT_RVT_GLOBAL: * * RVT is part of a global variable. */ -#define XSLT_RVT_GLOBAL ((void *)3) +#define XSLT_RVT_GLOBAL 3 /* * Interfaces for the variable module. diff --git a/libs/xslt/libxslt/xslt.c b/libs/xslt/libxslt/xslt.c index 69116f2be2e..39a700b0c3f 100644 --- a/libs/xslt/libxslt/xslt.c +++ b/libs/xslt/libxslt/xslt.c @@ -91,13 +91,7 @@ const xmlChar *xsltXSLTAttrMarker = (const xmlChar *) "LRE XSLT Attr"; #ifdef XSLT_LOCALE_WINAPI extern xmlRMutexPtr xsltLocaleMutex; #endif -/* - * Harmless but avoiding a problem when compiling against a - * libxml <= 2.3.11 without LIBXML_DEBUG_ENABLED - */ -#ifndef LIBXML_DEBUG_ENABLED -double xmlXPathStringEvalNumber(const xmlChar *str); -#endif + /* * Useful macros */ @@ -157,31 +151,23 @@ exclPrefixPush(xsltStylesheetPtr style, xmlChar * value) { int i; - if (style->exclPrefixMax == 0) { - style->exclPrefixMax = 4; - style->exclPrefixTab = - (xmlChar * *)xmlMalloc(style->exclPrefixMax * - sizeof(style->exclPrefixTab[0])); - if (style->exclPrefixTab == NULL) { - xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); - return (-1); - } - } /* do not push duplicates */ for (i = 0;i < style->exclPrefixNr;i++) { if (xmlStrEqual(style->exclPrefixTab[i], value)) return(-1); } if (style->exclPrefixNr >= style->exclPrefixMax) { - style->exclPrefixMax *= 2; - style->exclPrefixTab = - (xmlChar * *)xmlRealloc(style->exclPrefixTab, - style->exclPrefixMax * - sizeof(style->exclPrefixTab[0])); - if (style->exclPrefixTab == NULL) { + xmlChar **tmp; + size_t max = style->exclPrefixMax ? style->exclPrefixMax * 2 : 4; + + tmp = xmlRealloc(style->exclPrefixTab, + max * sizeof(style->exclPrefixTab[0])); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); return (-1); } + style->exclPrefixTab = tmp; + style->exclPrefixMax = max; } style->exclPrefixTab[style->exclPrefixNr] = value; style->exclPrefix = value; @@ -1117,9 +1103,9 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, xmlNodePtr node) { xmlNsPtr cur; - xmlNsPtr *ret = NULL; + xmlNsPtr *ret = NULL, *tmp; int nbns = 0; - int maxns = 10; + int maxns = 0; int i; if ((style == NULL) || (template == NULL) || (node == NULL) || @@ -1144,17 +1130,6 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, if (xmlStrEqual(cur->href, style->exclPrefixTab[i])) goto skip_ns; } - if (ret == NULL) { - ret = - (xmlNsPtr *) xmlMalloc((maxns + 1) * - sizeof(xmlNsPtr)); - if (ret == NULL) { - xmlGenericError(xmlGenericErrorContext, - "xsltGetInheritedNsList : out of memory!\n"); - return(0); - } - ret[nbns] = NULL; - } /* * Skip shadowed namespace bindings. */ @@ -1165,16 +1140,16 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, } if (i >= nbns) { if (nbns >= maxns) { - maxns *= 2; - ret = (xmlNsPtr *) xmlRealloc(ret, - (maxns + - 1) * - sizeof(xmlNsPtr)); - if (ret == NULL) { + maxns = (maxns == 0) ? 10 : 2 * maxns; + tmp = (xmlNsPtr *) xmlRealloc(ret, + (maxns + 1) * sizeof(xmlNsPtr)); + if (tmp == NULL) { xmlGenericError(xmlGenericErrorContext, "xsltGetInheritedNsList : realloc failed!\n"); + xmlFree(ret); return(0); } + ret = tmp; } ret[nbns++] = cur; ret[nbns] = NULL; @@ -1330,8 +1305,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) if (elements != NULL) { if (style->cdataSection == NULL) style->cdataSection = xmlHashCreate(10); - if (style->cdataSection == NULL) + if (style->cdataSection == NULL) { + xmlFree(elements); return; + } element = elements; while (*element != 0) { @@ -1569,8 +1546,10 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) { if (style->stripSpaces == NULL) style->stripSpaces = xmlHashCreate(10); - if (style->stripSpaces == NULL) + if (style->stripSpaces == NULL) { + xmlFree(elements); return; + } element = elements; while (*element != 0) { @@ -1698,6 +1677,11 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) { if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) return; + if (style->stripSpaces == NULL) + style->stripSpaces = xmlHashCreate(10); + if (style->stripSpaces == NULL) + return; + elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL); if (elements == NULL) { xsltTransformError(NULL, style, cur, @@ -1706,11 +1690,6 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) { return; } - if (style->stripSpaces == NULL) - style->stripSpaces = xmlHashCreate(10); - if (style->stripSpaces == NULL) - return; - element = elements; while (*element != 0) { while (IS_BLANK(*element)) element++; @@ -5526,9 +5505,6 @@ xsltCompileXSLTIncludeElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr node) { return(item); } -/** - * xsltParseFindTopLevelElem: - */ static int xsltParseFindTopLevelElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr cur, @@ -6687,6 +6663,9 @@ xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) { } #endif /* else of XSLT_REFACTORED */ + if (style->parent == NULL) + xsltResolveStylesheetAttributeSet(style); + if (style->errors != 0) { /* * Detach the doc from the stylesheet; otherwise the doc @@ -6701,15 +6680,12 @@ xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) { return(-1); } - if (style->parent == NULL) - xsltResolveStylesheetAttributeSet(style); - return(0); } /** * xsltParseStylesheetDoc: - * @doc: and xmlDoc parsed XML + * @doc: an xmlDoc parsed XML * * parse an XSLT stylesheet, building the associated structures. doc * is kept as a reference within the returned stylesheet, so changes @@ -6844,7 +6820,8 @@ xsltParseStylesheetPI(const xmlChar *value) { if (val == NULL) return(NULL); if ((xmlStrcasecmp(val, BAD_CAST "text/xml")) && - (xmlStrcasecmp(val, BAD_CAST "text/xsl"))) { + (xmlStrcasecmp(val, BAD_CAST "text/xsl")) && + (xmlStrcasecmp(val, BAD_CAST "application/xslt+xml"))) { xmlFree(val); break; } diff --git a/libs/xslt/libxslt/xsltInternals.h b/libs/xslt/libxslt/xsltInternals.h index 14343d2751c..7de638e143d 100644 --- a/libs/xslt/libxslt/xsltInternals.h +++ b/libs/xslt/libxslt/xsltInternals.h @@ -21,7 +21,6 @@ #include #include #include "xsltexports.h" -#include "xsltlocale.h" #include "numbersInternals.h" #ifdef __cplusplus @@ -1047,7 +1046,6 @@ struct _xsltStyleItemSort { int descending; /* sort */ const xmlChar *lang; /* sort */ int has_lang; /* sort */ - xsltLocale locale; /* sort */ const xmlChar *case_order; /* sort */ int lower_first; /* sort */ @@ -1377,7 +1375,6 @@ struct _xsltStylePreComp { int descending; /* sort */ const xmlChar *lang; /* sort */ int has_lang; /* sort */ - xsltLocale locale; /* sort */ const xmlChar *case_order; /* sort */ int lower_first; /* sort */ @@ -1663,6 +1660,13 @@ typedef enum { XSLT_OUTPUT_TEXT } xsltOutputType; +typedef void * +(*xsltNewLocaleFunc)(const xmlChar *lang, int lowerFirst); +typedef void +(*xsltFreeLocaleFunc)(void *locale); +typedef xmlChar * +(*xsltGenSortKeyFunc)(void *locale, const xmlChar *lang); + typedef enum { XSLT_STATE_OK = 0, XSLT_STATE_ERROR, @@ -1786,6 +1790,12 @@ struct _xsltTransformContext { int maxTemplateVars; unsigned long opLimit; unsigned long opCount; + int sourceDocDirty; + unsigned long currentId; /* For generate-id() */ + + xsltNewLocaleFunc newLocale; + xsltFreeLocaleFunc freeLocale; + xsltGenSortKeyFunc genSortKey; }; /** @@ -1915,7 +1925,7 @@ XSLTPUBFUN int XSLTCALL xsltFlagRVTs( xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, - void *val); + int val); XSLTPUBFUN void XSLTCALL xsltFreeRVTs (xsltTransformContextPtr ctxt); XSLTPUBFUN void XSLTCALL diff --git a/libs/xslt/libxslt/xsltconfig.h b/libs/xslt/libxslt/xsltconfig.h index 9fab8fec2ed..f524fbfe1b1 100644 --- a/libs/xslt/libxslt/xsltconfig.h +++ b/libs/xslt/libxslt/xsltconfig.h @@ -20,21 +20,21 @@ extern "C" { * * the version string like "1.2.3" */ -#define LIBXSLT_DOTTED_VERSION "1.1.36" +#define LIBXSLT_DOTTED_VERSION "1.1.38" /** * LIBXSLT_VERSION: * * the version number: 1.2.3 value is 10203 */ -#define LIBXSLT_VERSION 10136 +#define LIBXSLT_VERSION 10138 /** * LIBXSLT_VERSION_STRING: * * the version number string, 1.2.3 value is "10203" */ -#define LIBXSLT_VERSION_STRING "10136" +#define LIBXSLT_VERSION_STRING "10138" /** * LIBXSLT_VERSION_EXTRA: diff --git a/libs/xslt/libxslt/xsltlocale.c b/libs/xslt/libxslt/xsltlocale.c index 39980f8de9d..5a9291887ec 100644 --- a/libs/xslt/libxslt/xsltlocale.c +++ b/libs/xslt/libxslt/xsltlocale.c @@ -19,6 +19,30 @@ #include "xsltlocale.h" #include "xsltutils.h" +#ifdef HAVE_STRXFRM_L + + #define XSLT_LOCALE_POSIX + + #ifdef HAVE_LOCALE_H + #include + #endif + #ifdef HAVE_XLOCALE_H + #include + #endif + +#elif defined(_WIN32) + + #define XSLT_LOCALE_WINAPI + + #include + #include + +#else + + #define XSLT_LOCALE_NONE + +#endif + #define TOUPPER(c) (c & ~0x20) #define TOLOWER(c) (c | 0x20) #define ISALPHA(c) ((unsigned)(TOUPPER(c) - 'A') < 26) @@ -37,8 +61,7 @@ xmlRMutexPtr xsltLocaleMutex = NULL; struct xsltRFC1766Info_s { /*note typedef unsigned char xmlChar !*/ xmlChar tag[XSLTMAX_LANGTAGLEN+1]; - /*note typedef LCID xsltLocale !*/ - xsltLocale lcid; + LCID lcid; }; typedef struct xsltRFC1766Info_s xsltRFC1766Info; @@ -46,14 +69,15 @@ static int xsltLocaleListSize = 0; static xsltRFC1766Info *xsltLocaleList = NULL; -static xsltLocale +static void * xslt_locale_WINAPI(const xmlChar *languageTag) { int k; xsltRFC1766Info *p = xsltLocaleList; for (k=0; ktag, languageTag) == 0) return p->lcid; - return((xsltLocale)0); + if (xmlStrcmp(p->tag, languageTag) == 0) + return(&p->lcid); + return(NULL); } static void xsltEnumSupportedLocales(void); @@ -83,17 +107,17 @@ xsltFreeLocales(void) { * * Returns the locale or NULL on error or if no matching locale was found */ -xsltLocale -xsltNewLocale(const xmlChar *languageTag) { +void * +xsltNewLocale(const xmlChar *languageTag, int lowerFirst ATTRIBUTE_UNUSED) { #ifdef XSLT_LOCALE_POSIX - xsltLocale locale; - char localeName[XSLTMAX_LANGTAGLEN+6]; /* 6 chars for ".utf8\0" */ + locale_t locale; + char localeName[XSLTMAX_LANGTAGLEN+7]; /* 7 chars for ".UTF-8\0" */ const xmlChar *p = languageTag; const char *region = NULL; char *q = localeName; int i, llen; - /* Convert something like "pt-br" to "pt_BR.utf8" */ + /* Convert something like "pt-br" to "pt_BR.UTF-8" */ if (languageTag == NULL) return(NULL); @@ -117,7 +141,7 @@ xsltNewLocale(const xmlChar *languageTag) { if (i == 0 || *p) return(NULL); - memcpy(q, ".utf8", 6); + memcpy(q, ".UTF-8", 7); locale = newlocale(LC_COLLATE_MASK, localeName, NULL); if (locale != NULL) return(locale); @@ -129,7 +153,7 @@ xsltNewLocale(const xmlChar *languageTag) { /* Try locale without territory, e.g. for Esperanto (eo) */ - memcpy(q, ".utf8", 6); + memcpy(q, ".UTF-8", 7); locale = newlocale(LC_COLLATE_MASK, localeName, NULL); if (locale != NULL) return(locale); @@ -147,7 +171,7 @@ xsltNewLocale(const xmlChar *languageTag) { *q++ = '_'; *q++ = region[0]; *q++ = region[1]; - memcpy(q, ".utf8", 6); + memcpy(q, ".UTF-8", 7); locale = newlocale(LC_COLLATE_MASK, localeName, NULL); return(locale); @@ -155,7 +179,7 @@ xsltNewLocale(const xmlChar *languageTag) { #ifdef XSLT_LOCALE_WINAPI { - xsltLocale locale = (xsltLocale)0; + void *locale = NULL; xmlChar localeName[XSLTMAX_LANGTAGLEN+1]; xmlChar *q = localeName; const xmlChar *p = languageTag; @@ -344,10 +368,12 @@ xsltDefaultRegion(const xmlChar *localeName) { * Frees a locale created with xsltNewLocale */ void -xsltFreeLocale(xsltLocale locale) { +xsltFreeLocale(void *locale) { #ifdef XSLT_LOCALE_POSIX if (locale != NULL) freelocale(locale); +#else + (void) locale; #endif } @@ -356,57 +382,82 @@ xsltFreeLocale(xsltLocale locale) { * @locale: locale created with xsltNewLocale * @string: UTF-8 string to transform * - * Transforms a string according to locale. The transformed string must then be - * compared with xsltLocaleStrcmp and freed with xmlFree. + * Transforms a string according to locale. The transformed string must be + * freed with xmlFree. * * Returns the transformed string or NULL on error */ -xsltLocaleChar * -xsltStrxfrm(xsltLocale locale, const xmlChar *string) +xmlChar * +xsltStrxfrm(void *vlocale, const xmlChar *string) { #ifdef XSLT_LOCALE_NONE return(NULL); #else - size_t xstrlen, r; - xsltLocaleChar *xstr; + xmlChar *xstr; #ifdef XSLT_LOCALE_POSIX - xstrlen = strxfrm_l(NULL, (const char *)string, 0, locale) + 1; - xstr = (xsltLocaleChar *) xmlMalloc(xstrlen); + size_t xstrlen, r; + + xstrlen = strxfrm_l(NULL, (const char *)string, 0, vlocale) + 1; + xstr = (xmlChar *) xmlMalloc(xstrlen); if (xstr == NULL) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory error\n"); return(NULL); } - r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, locale); + r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, vlocale); + + if (r >= xstrlen) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n"); + xmlFree(xstr); + return(NULL); + } #endif #ifdef XSLT_LOCALE_WINAPI - xstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0); - if (xstrlen == 0) { + int wstrlen, xstrlen, r; + wchar_t *wstr; + LCID *lcid = vlocale; + + wstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0); + if (wstrlen == 0) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n"); return(NULL); } - xstr = (xsltLocaleChar*) xmlMalloc(xstrlen * sizeof(xsltLocaleChar)); - if (xstr == NULL) { + wstr = (wchar_t *) xmlMalloc(wstrlen * sizeof(wchar_t)); + if (wstr == NULL) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n"); return(NULL); } - r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, xstr, xstrlen); + r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, wstr, wstrlen); if (r == 0) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n"); - xmlFree(xstr); + xmlFree(wstr); return(NULL); } - return(xstr); -#endif /* XSLT_LOCALE_WINAPI */ - - if (r >= xstrlen) { - xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n"); + /* This returns the size in bytes. */ + xstrlen = LCMapStringW(*lcid, LCMAP_SORTKEY, wstr, wstrlen, NULL, 0); + if (xstrlen == 0) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : LCMapStringW failed\n"); + xmlFree(wstr); + return(NULL); + } + xstr = (xmlChar*) xmlMalloc(xstrlen); + if (xstr == NULL) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n"); + xmlFree(wstr); + return(NULL); + } + r = LCMapStringW(*lcid, LCMAP_SORTKEY, wstr, wstrlen, (wchar_t *) xstr, + xstrlen); + xmlFree(wstr); + if (r == 0) { + xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : LCMapStringW failed\n"); xmlFree(xstr); return(NULL); } +#endif /* XSLT_LOCALE_WINAPI */ return(xstr); #endif /* XSLT_LOCALE_NONE */ @@ -414,35 +465,22 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string) /** * xsltLocaleStrcmp: - * @locale: a locale identifier + * @locale: unused * @str1: a string transformed with xsltStrxfrm * @str2: a string transformed with xsltStrxfrm * - * Compares two strings transformed with xsltStrxfrm + * DEPRECATED: Same as xmlStrcmp. + * + * Compares two strings transformed with xsltStrxfrm. * * Returns a value < 0 if str1 sorts before str2, * a value > 0 if str1 sorts after str2, * 0 if str1 and str2 are equal wrt sorting */ int -xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2) { +xsltLocaleStrcmp(void *locale, const xmlChar *str1, const xmlChar *str2) { (void)locale; -#ifdef XSLT_LOCALE_WINAPI -{ - int ret; - if (str1 == str2) return(0); - if (str1 == NULL) return(-1); - if (str2 == NULL) return(1); - ret = CompareStringW(locale, 0, str1, -1, str2, -1); - if (ret == 0) { - xsltTransformError(NULL, NULL, NULL, "xsltLocaleStrcmp : CompareStringW fail\n"); - return(0); - } - return(ret - 2); -} -#else return(xmlStrcmp(str1, str2)); -#endif } #ifdef XSLT_LOCALE_WINAPI @@ -454,7 +492,7 @@ xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocale * * Returns TRUE */ -BOOL CALLBACK +static BOOL CALLBACK xsltCountSupportedLocales(LPSTR lcid) { (void) lcid; ++xsltLocaleListSize; @@ -469,7 +507,7 @@ xsltCountSupportedLocales(LPSTR lcid) { * * Returns TRUE if not at the end of the array */ -BOOL CALLBACK +static BOOL CALLBACK xsltIterateSupportedLocales(LPSTR lcid) { static int count = 0; xmlChar iso639lang [XSLTMAX_ISO639LANGLEN +1]; @@ -477,7 +515,7 @@ xsltIterateSupportedLocales(LPSTR lcid) { int k, l; xsltRFC1766Info *p = xsltLocaleList + count; - k = sscanf(lcid, "%lx", (long*)&p->lcid); + k = sscanf(lcid, "%lx", (unsigned long*)&p->lcid); if (k < 1) goto end; /*don't count terminating null character*/ k = GetLocaleInfoA(p->lcid, LOCALE_SISO639LANGNAME, diff --git a/libs/xslt/libxslt/xsltlocale.h b/libs/xslt/libxslt/xsltlocale.h dissimilarity index 62% index dc5038956e3..10a4402f1f2 100644 --- a/libs/xslt/libxslt/xsltlocale.h +++ b/libs/xslt/libxslt/xsltlocale.h @@ -1,76 +1,36 @@ -/* - * Summary: Locale handling - * Description: Interfaces for locale handling. Needed for language dependent - * sorting. - * - * Copy: See Copyright for the status of this software. - * - * Author: Nick Wellnhofer - */ - -#ifndef __XML_XSLTLOCALE_H__ -#define __XML_XSLTLOCALE_H__ - -#include -#include "xsltexports.h" - -#ifdef HAVE_STRXFRM_L - -/* - * XSLT_LOCALE_POSIX: - * Macro indicating to use POSIX locale extensions - */ -#define XSLT_LOCALE_POSIX - -#ifdef HAVE_LOCALE_H -#include -#endif -#ifdef HAVE_XLOCALE_H -#include -#endif - -typedef locale_t xsltLocale; -typedef xmlChar xsltLocaleChar; - -#elif defined(_WIN32) - -/* - * XSLT_LOCALE_WINAPI: - * Macro indicating to use WinAPI for extended locale support - */ -#define XSLT_LOCALE_WINAPI - -#include -#include - -typedef LCID xsltLocale; -typedef wchar_t xsltLocaleChar; - -#else - -/* - * XSLT_LOCALE_NONE: - * Macro indicating that there's no extended locale support - */ -#define XSLT_LOCALE_NONE - -typedef void *xsltLocale; -typedef xmlChar xsltLocaleChar; - -#endif - -XSLTPUBFUN xsltLocale XSLTCALL - xsltNewLocale (const xmlChar *langName); -XSLTPUBFUN void XSLTCALL - xsltFreeLocale (xsltLocale locale); -XSLTPUBFUN xsltLocaleChar * XSLTCALL - xsltStrxfrm (xsltLocale locale, - const xmlChar *string); -XSLTPUBFUN int XSLTCALL - xsltLocaleStrcmp (xsltLocale locale, - const xsltLocaleChar *str1, - const xsltLocaleChar *str2); -XSLTPUBFUN void XSLTCALL - xsltFreeLocales (void); - -#endif /* __XML_XSLTLOCALE_H__ */ +/* + * Summary: Locale handling + * Description: Interfaces for locale handling. Needed for language dependent + * sorting. + * + * Copy: See Copyright for the status of this software. + * + * Author: Nick Wellnhofer + */ + +#ifndef __XML_XSLTLOCALE_H__ +#define __XML_XSLTLOCALE_H__ + +#include +#include "xsltexports.h" + +XSLTPUBFUN void * XSLTCALL + xsltNewLocale (const xmlChar *langName, + int lowerFirst); +XSLTPUBFUN void XSLTCALL + xsltFreeLocale (void *locale); +XSLTPUBFUN xmlChar * XSLTCALL + xsltStrxfrm (void *locale, + const xmlChar *string); +XSLTPUBFUN void XSLTCALL + xsltFreeLocales (void); + +/* Backward compatibility */ +typedef void *xsltLocale; +typedef xmlChar xsltLocaleChar; +XSLTPUBFUN int XSLTCALL + xsltLocaleStrcmp (void *locale, + const xmlChar *str1, + const xmlChar *str2); + +#endif /* __XML_XSLTLOCALE_H__ */ diff --git a/libs/xslt/libxslt/xsltutils.c b/libs/xslt/libxslt/xsltutils.c index f352ca1b2ae..3705d28f16e 100644 --- a/libs/xslt/libxslt/xsltutils.c +++ b/libs/xslt/libxslt/xsltutils.c @@ -42,6 +42,7 @@ #include "transform.h" #if defined(_WIN32) +#include #define XSLT_WIN32_PERFORMANCE_COUNTER #endif @@ -304,6 +305,66 @@ error: return(-1); } +/** + * xsltGetUTF8CharZ: + * @utf: a sequence of UTF-8 encoded bytes + * @len: a pointer to @bytes len + * + * Read one UTF8 Char from a null-terminated string. + * + * Returns the char value or -1 in case of error and update @len with the + * number of bytes used + */ +int +xsltGetUTF8CharZ(const unsigned char *utf, int *len) { + unsigned int c; + + if (utf == NULL) + goto error; + if (len == NULL) + goto error; + + c = utf[0]; + if (c & 0x80) { + if ((utf[1] & 0xc0) != 0x80) + goto error; + if ((c & 0xe0) == 0xe0) { + if ((utf[2] & 0xc0) != 0x80) + goto error; + if ((c & 0xf0) == 0xf0) { + if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80) + goto error; + *len = 4; + /* 4-byte code */ + c = (utf[0] & 0x7) << 18; + c |= (utf[1] & 0x3f) << 12; + c |= (utf[2] & 0x3f) << 6; + c |= utf[3] & 0x3f; + } else { + /* 3-byte code */ + *len = 3; + c = (utf[0] & 0xf) << 12; + c |= (utf[1] & 0x3f) << 6; + c |= utf[2] & 0x3f; + } + } else { + /* 2-byte code */ + *len = 2; + c = (utf[0] & 0x1f) << 6; + c |= utf[1] & 0x3f; + } + } else { + /* 1-byte code */ + *len = 1; + } + return(c); + +error: + if (len != NULL) + *len = 0; + return(-1); +} + #ifdef XSLT_REFACTORED /** @@ -947,10 +1008,11 @@ xsltDocumentSortFunction(xmlNodeSetPtr list) { } /** - * xsltComputeSortResultiInternal: + * xsltComputeSortResultInternal: * @ctxt: a XSLT process context - * @sort: node list - * @xfrm: Transform strings according to locale + * @sort: xsl:sort node + * @number: data-type is number + * @locale: transform strings according to locale * * reorder the current node list accordingly to the set of sorting * requirement provided by the array of nodes. @@ -959,11 +1021,11 @@ xsltDocumentSortFunction(xmlNodeSetPtr list) { */ static xmlXPathObjectPtr * xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort, - int xfrm) { + int number, void *locale) { #ifdef XSLT_REFACTORED xsltStyleItemSortPtr comp; #else - xsltStylePreCompPtr comp; + const xsltStylePreComp *comp; #endif xmlXPathObjectPtr *results = NULL; xmlNodeSetPtr list = NULL; @@ -1031,10 +1093,12 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort, if (res != NULL) { if (res->type != XPATH_STRING) res = xmlXPathConvertString(res); - if (comp->number) + if (number) res = xmlXPathConvertNumber(res); + } + if (res != NULL) { res->index = i; /* Save original pos for dupl resolv */ - if (comp->number) { + if (number) { if (res->type == XPATH_NUMBER) { results[i] = res; } else { @@ -1046,10 +1110,17 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort, } } else { if (res->type == XPATH_STRING) { - if ((xfrm) && (comp->locale != (xsltLocale)0)) { + if (locale != NULL) { xmlChar *str = res->stringval; - res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str); - xmlFree(str); + xmlChar *sortKey = ctxt->genSortKey(locale, str); + + if (sortKey == NULL) { + xsltTransformError(ctxt, NULL, sort, + "xsltComputeSortResult: sort key is null\n"); + } else { + res->stringval = sortKey; + xmlFree(str); + } } results[i] = res; @@ -1088,7 +1159,13 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort, */ xmlXPathObjectPtr * xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) { - return xsltComputeSortResultInternal(ctxt, sort, /* xfrm */ 0); + const xsltStylePreComp *comp = sort->psvi; + int number = 0; + + if (comp != NULL) + number = comp->number; + return xsltComputeSortResultInternal(ctxt, sort, number, + /* locale */ NULL); } /** @@ -1106,20 +1183,19 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, #ifdef XSLT_REFACTORED xsltStyleItemSortPtr comp; #else - xsltStylePreCompPtr comp; + const xsltStylePreComp *comp; #endif xmlXPathObjectPtr *resultsTab[XSLT_MAX_SORT]; xmlXPathObjectPtr *results = NULL, *res; xmlNodeSetPtr list = NULL; - int descending, number, desc, numb; int len = 0; int i, j, incr; int tst; int depth; xmlNodePtr node; xmlXPathObjectPtr tmp; - int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT], - templang[XSLT_MAX_SORT]; + int number[XSLT_MAX_SORT], desc[XSLT_MAX_SORT]; + void *locale[XSLT_MAX_SORT]; if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) || (nbsorts >= XSLT_MAX_SORT)) @@ -1135,72 +1211,74 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, return; /* nothing to do */ for (j = 0; j < nbsorts; j++) { + xmlChar *lang; + comp = sorts[j]->psvi; - tempstype[j] = 0; if ((comp->stype == NULL) && (comp->has_stype != 0)) { - comp->stype = + xmlChar *stype = xsltEvalAttrValueTemplate(ctxt, sorts[j], - (const xmlChar *) "data-type", - NULL); - if (comp->stype != NULL) { - tempstype[j] = 1; - if (xmlStrEqual(comp->stype, (const xmlChar *) "text")) - comp->number = 0; - else if (xmlStrEqual(comp->stype, (const xmlChar *) "number")) - comp->number = 1; + BAD_CAST "data-type", NULL); + number[j] = 0; + if (stype != NULL) { + if (xmlStrEqual(stype, (const xmlChar *) "text")) + ; + else if (xmlStrEqual(stype, (const xmlChar *) "number")) + number[j] = 1; else { xsltTransformError(ctxt, NULL, sorts[j], "xsltDoSortFunction: no support for data-type = %s\n", - comp->stype); - comp->number = 0; /* use default */ + stype); } + xmlFree(stype); } - } - temporder[j] = 0; + } else { + number[j] = comp->number; + } if ((comp->order == NULL) && (comp->has_order != 0)) { - comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j], - (const xmlChar *) "order", - NULL); - if (comp->order != NULL) { - temporder[j] = 1; - if (xmlStrEqual(comp->order, (const xmlChar *) "ascending")) - comp->descending = 0; - else if (xmlStrEqual(comp->order, - (const xmlChar *) "descending")) - comp->descending = 1; + xmlChar *order = xsltEvalAttrValueTemplate(ctxt, sorts[j], + BAD_CAST "order", NULL); + desc[j] = 0; + if (order != NULL) { + if (xmlStrEqual(order, (const xmlChar *) "ascending")) + ; + else if (xmlStrEqual(order, (const xmlChar *) "descending")) + desc[j] = 1; else { xsltTransformError(ctxt, NULL, sorts[j], "xsltDoSortFunction: invalid value %s for order\n", - comp->order); - comp->descending = 0; /* use default */ + order); } + xmlFree(order); } + } else { + desc[j] = comp->descending; } - templang[j] = 0; if ((comp->lang == NULL) && (comp->has_lang != 0)) { - xmlChar *lang = xsltEvalAttrValueTemplate(ctxt, sorts[j], + lang = xsltEvalAttrValueTemplate(ctxt, sorts[j], (xmlChar *) "lang", NULL); - if (lang != NULL) { - templang[j] = 1; - comp->locale = xsltNewLocale(lang); + } else { + lang = (xmlChar *) comp->lang; + } + if (lang != NULL) { + locale[j] = ctxt->newLocale(lang, comp->lower_first); + if (lang != comp->lang) xmlFree(lang); - } - } + } else { + locale[j] = NULL; + } } len = list->nodeNr; - resultsTab[0] = xsltComputeSortResultInternal(ctxt, sorts[0], - /* xfrm */ 1); + resultsTab[0] = xsltComputeSortResultInternal(ctxt, sorts[0], number[0], + locale[0]); for (i = 1;i < XSLT_MAX_SORT;i++) resultsTab[i] = NULL; results = resultsTab[0]; comp = sorts[0]->psvi; - descending = comp->descending; - number = comp->number; if (results == NULL) goto cleanup; @@ -1215,7 +1293,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, if (results[j] == NULL) tst = 1; else { - if (number) { + if (number[0]) { /* We make NaN smaller than number in accordance with XSLT spec */ if (xmlXPathIsNaN(results[j]->floatval)) { @@ -1232,16 +1310,11 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, results[j + incr]->floatval) tst = 1; else tst = -1; - } else if(comp->locale != (xsltLocale)0) { - tst = xsltLocaleStrcmp( - comp->locale, - (xsltLocaleChar *) results[j]->stringval, - (xsltLocaleChar *) results[j + incr]->stringval); } else { tst = xmlStrcmp(results[j]->stringval, results[j + incr]->stringval); } - if (descending) + if (desc[0]) tst = -tst; } if (tst == 0) { @@ -1255,8 +1328,6 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, comp = sorts[depth]->psvi; if (comp == NULL) break; - desc = comp->descending; - numb = comp->number; /* * Compute the result of the next level for the @@ -1266,7 +1337,8 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, resultsTab[depth] = xsltComputeSortResultInternal(ctxt, sorts[depth], - /* xfrm */ 1); + number[depth], + locale[depth]); res = resultsTab[depth]; if (res == NULL) break; @@ -1276,7 +1348,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, } else if (res[j+incr] == NULL) { tst = -1; } else { - if (numb) { + if (number[depth]) { /* We make NaN smaller than number in accordance with XSLT spec */ if (xmlXPathIsNaN(res[j]->floatval)) { @@ -1295,16 +1367,11 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, res[j + incr]->floatval) tst = 1; else tst = -1; - } else if(comp->locale != (xsltLocale)0) { - tst = xsltLocaleStrcmp( - comp->locale, - (xsltLocaleChar *) res[j]->stringval, - (xsltLocaleChar *) res[j + incr]->stringval); } else { tst = xmlStrcmp(res[j]->stringval, res[j + incr]->stringval); } - if (desc) + if (desc[depth]) tst = -tst; } @@ -1348,21 +1415,9 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, cleanup: for (j = 0; j < nbsorts; j++) { - comp = sorts[j]->psvi; - if (tempstype[j] == 1) { - /* The data-type needs to be recomputed each time */ - xmlFree((void *)(comp->stype)); - comp->stype = NULL; - } - if (temporder[j] == 1) { - /* The order needs to be recomputed each time */ - xmlFree((void *)(comp->order)); - comp->order = NULL; - } - if (templang[j] == 1) { - xsltFreeLocale(comp->locale); - comp->locale = (xsltLocale)0; - } + if (locale[j] != NULL) { + ctxt->freeLocale(locale[j]); + } if (resultsTab[j] != NULL) { for (i = 0;i < len;i++) xmlXPathFreeObject(resultsTab[j][i]); @@ -1402,6 +1457,8 @@ xsltDoSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr * sorts, * xsltSetSortFunc: * @handler: the new handler function * + * DEPRECATED: Use xsltSetCtxtLocaleHandlers. + * * Function to reset the global handler for XSLT sorting. * If the handler is NULL, the default sort function will be used. */ @@ -1418,6 +1475,8 @@ xsltSetSortFunc(xsltSortFunc handler) { * @ctxt: a XSLT process context * @handler: the new handler function * + * DEPRECATED: Use xsltSetCtxtLocaleHandlers. + * * Function to set the handler for XSLT sorting * for the specified context. * If the handler is NULL, then the global @@ -1428,6 +1487,28 @@ xsltSetCtxtSortFunc(xsltTransformContextPtr ctxt, xsltSortFunc handler) { ctxt->sortfunc = handler; } +/** + * xsltSetCtxtLocaleHandlers: + * @ctxt: an XSLT transform context + * @newLocale: locale constructor + * @freeLocale: locale destructor + * @genSortKey: sort key generator + * + * Set the locale handlers. + */ +void +xsltSetCtxtLocaleHandlers(xsltTransformContextPtr ctxt, + xsltNewLocaleFunc newLocale, + xsltFreeLocaleFunc freeLocale, + xsltGenSortKeyFunc genSortKey) { + if (ctxt == NULL) + return; + + ctxt->newLocale = newLocale; + ctxt->freeLocale = freeLocale; + ctxt->genSortKey = genSortKey; +} + /************************************************************************ * * * Parsing options * @@ -1807,6 +1888,8 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, (const xmlChar *) "UTF-8"))) encoder = NULL; buf = xmlAllocOutputBuffer(encoder); + if (buf == NULL) + xmlCharEncCloseFunc(encoder); } else { buf = xmlAllocOutputBuffer(NULL); } @@ -1834,6 +1917,141 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, return 0; } +/** + * xsltGetSourceNodeFlags: + * @node: Node from source document + * + * Returns the flags for a source node. + */ +int +xsltGetSourceNodeFlags(xmlNodePtr node) { + /* + * Squeeze the bit flags into the upper bits of + * + * - 'int properties' member in struct _xmlDoc + * - 'xmlAttributeType atype' member in struct _xmlAttr + * - 'unsigned short extra' member in struct _xmlNode + */ + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + return ((xmlDocPtr) node)->properties >> 27; + + case XML_ATTRIBUTE_NODE: + return ((xmlAttrPtr) node)->atype >> 27; + + case XML_ELEMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + return node->extra >> 12; + + default: + return 0; + } +} + +/** + * xsltSetSourceNodeFlags: + * @node: Node from source document + * @flags: Flags + * + * Sets the specified flags to 1. + * + * Returns 0 on success, -1 on error. + */ +int +xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, + int flags) { + if (node->doc == ctxt->initialContextDoc) + ctxt->sourceDocDirty = 1; + + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + ((xmlDocPtr) node)->properties |= flags << 27; + return 0; + + case XML_ATTRIBUTE_NODE: + ((xmlAttrPtr) node)->atype |= flags << 27; + return 0; + + case XML_ELEMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + node->extra |= flags << 12; + return 0; + + default: + return -1; + } +} + +/** + * xsltClearSourceNodeFlags: + * @node: Node from source document + * @flags: Flags + * + * Sets the specified flags to 0. + * + * Returns 0 on success, -1 on error. + */ +int +xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + ((xmlDocPtr) node)->properties &= ~(flags << 27); + return 0; + + case XML_ATTRIBUTE_NODE: + ((xmlAttrPtr) node)->atype &= ~(flags << 27); + return 0; + + case XML_ELEMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + node->extra &= ~(flags << 12); + return 0; + + default: + return -1; + } +} + +/** + * xsltGetPSVIPtr: + * @cur: Node + * + * Returns a pointer to the psvi member of a node or NULL on error. + */ +void ** +xsltGetPSVIPtr(xmlNodePtr cur) { + switch (cur->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + return &((xmlDocPtr) cur)->psvi; + + case XML_ATTRIBUTE_NODE: + return &((xmlAttrPtr) cur)->psvi; + + case XML_ELEMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + return &cur->psvi; + + default: + return NULL; + } +} + #ifdef WITH_PROFILER /************************************************************************ diff --git a/libs/xslt/libxslt/xsltutils.h b/libs/xslt/libxslt/xsltutils.h index 7f35cc7ed20..ed0bfd91f07 100644 --- a/libs/xslt/libxslt/xsltutils.h +++ b/libs/xslt/libxslt/xsltutils.h @@ -91,6 +91,13 @@ XSLTPUBFUN const xmlChar * XSLTCALL XSLTPUBFUN int XSLTCALL xsltGetUTF8Char (const unsigned char *utf, int *len); +#ifdef IN_LIBXSLT +/** DOC_DISABLE */ +XSLTPUBFUN int XSLTCALL + xsltGetUTF8CharZ (const unsigned char *utf, + int *len); +/** DOC_ENABLE */ +#endif /* * XSLT Debug Tracing Tracing Types @@ -179,6 +186,11 @@ XSLTPUBFUN void XSLTCALL xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt, xsltSortFunc handler); XSLTPUBFUN void XSLTCALL + xsltSetCtxtLocaleHandlers (xsltTransformContextPtr ctxt, + xsltNewLocaleFunc newLocale, + xsltFreeLocaleFunc freeLocale, + xsltGenSortKeyFunc genSortKey); +XSLTPUBFUN void XSLTCALL xsltDefaultSortFunction (xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts); @@ -244,6 +256,24 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL const xmlChar *str, int flags); +#ifdef IN_LIBXSLT +/** DOC_DISABLE */ +#define XSLT_SOURCE_NODE_MASK 15u +#define XSLT_SOURCE_NODE_HAS_KEY 1u +#define XSLT_SOURCE_NODE_HAS_ID 2u +int +xsltGetSourceNodeFlags(xmlNodePtr node); +int +xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, + int flags); +int +xsltClearSourceNodeFlags(xmlNodePtr node, int flags); +void ** +xsltGetPSVIPtr(xmlNodePtr cur); +/** DOC_ENABLE */ +#endif + +#ifdef WITH_PROFILER /* * Profiling. */ @@ -257,6 +287,7 @@ XSLTPUBFUN long XSLTCALL xsltTimestamp (void); XSLTPUBFUN void XSLTCALL xsltCalibrateAdjust (long delta); +#endif /** * XSLT_TIMESTAMP_TICS_PER_SEC: @@ -289,10 +320,11 @@ typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node, typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source); typedef void (*xsltDropCallCallback) (void); -XSLTPUBFUN void XSLTCALL - xsltSetDebuggerStatus (int value); XSLTPUBFUN int XSLTCALL xsltGetDebuggerStatus (void); +#ifdef WITH_DEBUGGER +XSLTPUBFUN void XSLTCALL + xsltSetDebuggerStatus (int value); XSLTPUBFUN int XSLTCALL xsltSetDebuggerCallbacks (int no, void *block); XSLTPUBFUN int XSLTCALL @@ -300,6 +332,7 @@ XSLTPUBFUN int XSLTCALL xmlNodePtr source); XSLTPUBFUN void XSLTCALL xslDropCall (void); +#endif #ifdef __cplusplus } -- 2.11.4.GIT