[LIBXSLT] Update to version 1.1.34. CORE-16952

This commit is contained in:
Thomas Faber 2020-04-24 09:25:23 +02:00
parent f22fa382fe
commit b01a480163
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
22 changed files with 657 additions and 374 deletions

View file

@ -64,7 +64,6 @@ endif
libxslt_la_LIBADD = $(LIBXML_LIBS) $(EXTRA_LIBS) $(M_LIBS)
libxslt_la_LDFLAGS = \
$(WIN32_EXTRA_LDFLAGS) \
$(LIBXSLT_VERSION_SCRIPT) \
-version-info $(LIBXSLT_VERSION_INFO)

View file

@ -5,9 +5,154 @@
http://xmlsoft.org/XSLT/news.html
See the git page at
http://git.gnome.org/browse/libxslt/
https://gitlab.gnome.org/GNOME/libxslt
to get a description of the recent commits.Those are the public releases made:
v1.1.33: Jan 03 2019:
- Portability:
Variables need 'extern' in static lib on Cygwin (Nick Wellnhofer),
Really declare dllexport/dllimport for Cygwin (Michael Haubenwallner),
Fix callback signatures in Python bindings (Nick Wellnhofer),
Fix transform callback signatures (Nick Wellnhofer),
Fix extension callback signatures (Nick Wellnhofer),
Fix deallocator signatures (Nick Wellnhofer),
Fix XPath callback signatures (Nick Wellnhofer),
Fix hash callback signatures (Nick Wellnhofer)
- Bug Fixes:
Don't cache direct evaluation of patterns with variables (Nick Wellnhofer),
Move function result RVTs to context variable (Nick Wellnhofer),
Fix EXSLT functions returning RVTs from outer scopes (Nick Wellnhofer),
Fix handling of RVTs returned from nested EXSLT functions (Nick Wellnhofer),
Fix typos (Nick Wellnhofer)
- Improvements:
Run Travis ASan tests with "sudo: required" (Nick Wellnhofer)
- Cleanups:
Remove doc/libxslt-decl.txt (Nick Wellnhofer),
Docs for 1.1.32 release (Daniel Veillard)
1.1.32: Nov 02 2017:
- Portability:
Add missing limits.h include (Nick Wellnhofer),
Also run Windows tests with --maxdepth 200 (Nick Wellnhofer),
Disable some MSVC warnings (Nick Wellnhofer),
Fix deprecated Travis compiler flag (Nick Wellnhofer),
Run general tests with maxdepth=200 (Nick Wellnhofer),
Use _WIN32 macro instead of WIN32 (Nick Wellnhofer),
Fix xsltproc newlines on Windows (Nick Wellnhofer),
Fix Windows compiler warnings (Nick Wellnhofer),
Rework locale feature tests (Nick Wellnhofer)
- Improvements:
Rebuild win32/libxslt.def.src (Nick Wellnhofer),
Fix compiler warnings in Python bindings (Nick Wellnhofer)
v1.1.31: Oct 06 2017:
- Portability:
Fix win32/configure.js (Nick Wellnhofer)
- Bug Fixes:
Fix pkg-config related regressions in configure script (Nick Wellnhofer)
- Improvements:
Adjust expected error output for libxml2 changes (Nick Wellnhofer),
Misc autoconf updates (Nick Wellnhofer)
v1.1.30: Sep 04 2017:
- Documentation:
Misc doc fixes (Nick Wellnhofer)
- Portability:
Look for libxml2 via pkg-config first (Elliott Sales de Andrade),
Change default SOPREFIX on Windows to "bin" (Nick Wellnhofer),
Add WIN32_EXTRA_LDFLAGS to tests/plugins/Makefile.am (Michael Haubenwallner)
- Bug Fixes:
Also fix memory hazards in exsltFuncResultElem (Nick Wellnhofer),
Fix NULL deref in xsltDefaultSortFunction (Nick Wellnhofer),
Fix memory hazards in exsltFuncFunctionFunction (Nick Wellnhofer),
Fix memory leaks in EXSLT error paths (Nick Wellnhofer),
Fix memory leak in str:concat with empty node-set (Nick Wellnhofer),
Fix memory leaks in error paths (Nick Wellnhofer),
Switch to xmlUTF8Strsize in numbers.c (Nick Wellnhofer),
Fix NULL pointer deref in xsltFormatNumberFunction (Nick Wellnhofer),
Fix UTF-8 check in str:padding (Nick Wellnhofer),
Fix xmlStrPrintf argument (Nick Wellnhofer),
Check for overflow in _exsltDateParseGYear (Nick Wellnhofer),
Fix double to int conversion (Nick Wellnhofer),
Check for overflow in exsltDateParseDuration (Nick Wellnhofer),
Change version of xsltMaxVars back to 1.0.24 (Nick Wellnhofer),
Disable xsltCopyTextString optimization for extensions (Nick Wellnhofer),
Create DOCTYPE for HTML version 5 (Nick Wellnhofer),
Make xsl:decimal-format work with namespaces (Nick Wellnhofer),
Remove norm:localTime extension function (Nick Wellnhofer),
Check for integer overflow in xsltAddTextString (Nick Wellnhofer),
Detect infinite recursion when evaluating function arguments (Nick Wellnhofer),
Fix memory leak in xsltElementAvailableFunction (Nick Wellnhofer),
Fix for pattern predicates calling functions (Nick Wellnhofer),
Fix cmd.exe invocations in Makefile.mingw (Nick Wellnhofer),
Don't try to install index.sgml (Nick Wellnhofer),
Fix symbols.xml (Nick Wellnhofer),
Fix heap overread in xsltFormatNumberConversion (Nick Wellnhofer),
Fix <xsl:number level="any"/> for non-element nodes (Nick Wellnhofer),
Fix unreachable code in xsltAddChild (mahendra.n),
Change version number in xsl:version warning (Nick Wellnhofer),
Avoid infinite recursion after failed param evaluation (Nick Wellnhofer),
Stop if potential recursion is detected (Nick Wellnhofer),
Consider built-in templates in apply-imports (Nick Wellnhofer),
Fix precedence with multiple attribute sets (Nick Wellnhofer),
Rework attribute set resolution (Nick Wellnhofer)
- Improvements:
Add .travis.yml (Nick Wellnhofer),
Silence tests a little (Nick Wellnhofer),
Set LIBXML_SRC to absolute path (Nick Wellnhofer),
Add missing #include (Nick Wellnhofer),
Adjust expected error messages in tests (Nick Wellnhofer),
Make xsltDebug more quiet (Nick Wellnhofer),
New-line terminate error message that missed this convention (Jan Pokorný),
Use xmlBuffers in EXSLT string functions (Nick Wellnhofer),
Switch to xmlUTF8Strsize in EXSLT string functions (Nick Wellnhofer),
Check for return value of xmlUTF8Strlen (Nick Wellnhofer),
Avoid double/long round trip in FORMAT_ITEM (Nick Wellnhofer),
Separate date and duration structs (Nick Wellnhofer),
Check for overflow in _exsltDateDifference (Nick Wellnhofer),
Clamp seconds field of durations (Nick Wellnhofer),
Change _exsltDateAddDurCalc parameter types (Nick Wellnhofer),
Fix date:difference with time zones (Nick Wellnhofer),
Rework division/remainder arithmetic in date.c (Nick Wellnhofer),
Remove exsltDateCastDateToNumber (Nick Wellnhofer),
Change internal representation of years (Nick Wellnhofer),
Optimize IS_LEAP (Nick Wellnhofer),
Link libraries with libm (Jussi Kukkonen),
Rename xsltCopyTreeInternal to xsltCopyTree (Nick Wellnhofer),
Update linker version script (Nick Wellnhofer),
Add local wildcard to version script (Nick Wellnhofer),
Make some symbols static (Nick Wellnhofer),
Remove redundant NULL check in xsltNumberComp (mahendra.n),
Fix forwards compatibility for imported stylesheets (Nick Wellnhofer),
Reduce warnings in forwards-compatible mode (Nick Wellnhofer),
Precompute XSLT elements after preprocessing (Nick Wellnhofer),
Fix whitespace in xsltParseStylesheetTop (Nick Wellnhofer),
Consolidate recursion checks (Nick Wellnhofer),
Treat XSLT_STATE_STOPPED same as errors (Nick Wellnhofer),
Make sure that XSLT_STATE_STOPPED isn't overwritten (Nick Wellnhofer),
Add comment regarding built-in templates and params (Nick Wellnhofer),
Rewrite memory management of local RVTs (Nick Wellnhofer),
Validate QNames of attribute sets (Nick Wellnhofer),
Add xsl:attribute-set regression tests (Nick Wellnhofer),
Ignore imported stylesheets in xsltApplyAttributeSet (Nick Wellnhofer)
1.1.29: May 24 2016:
- Security:
CVE-2015-7995 Fix for type confusion in preprocessing attributes (Daniel Veillard)

View file

@ -36,7 +36,12 @@ struct _xsltAttrVT {
/*
* the content is an alternate of string and xmlXPathCompExprPtr
*/
void *segments[MAX_AVT_SEG];
#if __STDC_VERSION__ >= 199901L
/* Using a C99 flexible array member avoids false positives under UBSan */
void *segments[];
#else
void *segments[1];
#endif
};
/**
@ -50,15 +55,16 @@ struct _xsltAttrVT {
static xsltAttrVTPtr
xsltNewAttrVT(xsltStylesheetPtr style) {
xsltAttrVTPtr cur;
size_t size = sizeof(xsltAttrVT) + MAX_AVT_SEG * sizeof(void*);
cur = (xsltAttrVTPtr) xmlMalloc(sizeof(xsltAttrVT));
cur = (xsltAttrVTPtr) xmlMalloc(size);
if (cur == NULL) {
xsltTransformError(NULL, style, NULL,
"xsltNewAttrVTPtr : malloc failed\n");
if (style != NULL) style->errors++;
return(NULL);
}
memset(cur, 0, sizeof(xsltAttrVT));
memset(cur, 0, size);
cur->nb_seg = 0;
cur->max_seg = MAX_AVT_SEG;
@ -134,11 +140,14 @@ xsltFreeAVTList(void *avt) {
static xsltAttrVTPtr
xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val) {
if (avt->nb_seg >= avt->max_seg) {
avt = (xsltAttrVTPtr) xmlRealloc(avt, sizeof(xsltAttrVT) +
avt->max_seg * sizeof(void *));
if (avt == NULL) {
size_t size = sizeof(xsltAttrVT) +
(avt->max_seg + MAX_AVT_SEG) * sizeof(void *);
xsltAttrVTPtr tmp = (xsltAttrVTPtr) xmlRealloc(avt, size);
if (tmp == NULL) {
xsltFreeAttrVT(avt);
return NULL;
}
avt = tmp;
memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *));
avt->max_seg += MAX_AVT_SEG;
}
@ -152,7 +161,7 @@ xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val) {
* @attr: the attribute coming from the stylesheet.
*
* Precompile an attribute in a stylesheet, basically it checks if it is
* an attrubute value template, and if yes establish some structures needed
* an attribute value template, and if yes, establish some structures needed
* to process it at transformation time.
*/
void

View file

@ -279,10 +279,11 @@ xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI) {
int res;
res = xsltCheckRead(ctxt->sec, ctxt, URI);
if (res == 0) {
xsltTransformError(ctxt, NULL, NULL,
"xsltLoadDocument: read rights for %s denied\n",
URI);
if (res <= 0) {
if (res == 0)
xsltTransformError(ctxt, NULL, NULL,
"xsltLoadDocument: read rights for %s denied\n",
URI);
return(NULL);
}
}
@ -355,10 +356,11 @@ xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) {
int res;
res = xsltCheckRead(sec, NULL, URI);
if (res == 0) {
xsltTransformError(NULL, NULL, NULL,
"xsltLoadStyleDocument: read rights for %s denied\n",
URI);
if (res <= 0) {
if (res == 0)
xsltTransformError(NULL, NULL, NULL,
"xsltLoadStyleDocument: read rights for %s denied\n",
URI);
return(NULL);
}
}

View file

@ -27,7 +27,7 @@
/**
* xsltXPathFunctionLookup:
* @ctxt: a void * but the XSLT transformation context actually
* @vctxt: a void * but the XSLT transformation context actually
* @name: the function name
* @ns_uri: the function namespace URI
*

View file

@ -93,10 +93,11 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
int secres;
secres = xsltCheckRead(sec, NULL, URI);
if (secres == 0) {
xsltTransformError(NULL, NULL, NULL,
"xsl:import: read rights for %s denied\n",
URI);
if (secres <= 0) {
if (secres == 0)
xsltTransformError(NULL, NULL, NULL,
"xsl:import: read rights for %s denied\n",
URI);
goto error;
}
}

View file

@ -223,6 +223,8 @@ skipString(const xmlChar *cur, int end) {
*/
static int
skipPredicate(const xmlChar *cur, int end) {
int level = 0;
if ((cur == NULL) || (end < 0)) return(-1);
if (cur[end] != '[') return(end);
end++;
@ -233,12 +235,12 @@ skipPredicate(const xmlChar *cur, int end) {
return(-1);
continue;
} else if (cur[end] == '[') {
end = skipPredicate(cur, end);
if (end <= 0)
return(-1);
continue;
} else if (cur[end] == ']')
return(end + 1);
level += 1;
} else if (cur[end] == ']') {
if (level == 0)
return(end + 1);
level -= 1;
}
end++;
}
return(-1);
@ -611,6 +613,7 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr idoc,
xmlNodePtr oldContextNode;
xsltDocumentPtr oldDocInfo;
int oldXPPos, oldXPSize;
xmlNodePtr oldXPNode;
xmlDocPtr oldXPDoc;
int oldXPNsNr;
xmlNsPtr *oldXPNamespaces;
@ -649,6 +652,7 @@ fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel);
oldDocInfo = ctxt->document;
oldContextNode = ctxt->node;
oldXPNode = xpctxt->node;
oldXPDoc = xpctxt->doc;
oldXPPos = xpctxt->proximityPosition;
oldXPSize = xpctxt->contextSize;
@ -847,6 +851,7 @@ error:
/*
* Restore context state.
*/
xpctxt->node = oldXPNode;
xpctxt->doc = oldXPDoc;
xpctxt->nsNr = oldXPNsNr;
xpctxt->namespaces = oldXPNamespaces;

View file

@ -19,7 +19,7 @@
#define SYMBOL_QUOTE ((xmlChar)'\'')
#define DEFAULT_TOKEN (xmlChar)'0'
#define DEFAULT_TOKEN '0'
#define DEFAULT_SEPARATOR "."
#define MAX_TOKENS 1024
@ -28,7 +28,7 @@ typedef struct _xsltFormatToken xsltFormatToken;
typedef xsltFormatToken *xsltFormatTokenPtr;
struct _xsltFormatToken {
xmlChar *separator;
xmlChar token;
int token;
int width;
};
@ -90,20 +90,22 @@ xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2) {
(xsltUTF8Charcmp((letter), (self)->patternSeparator) == 0))
#define IS_DIGIT_ZERO(x) xsltIsDigitZero(x)
#define IS_DIGIT_ONE(x) xsltIsDigitZero((xmlChar)(x)-1)
#define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1)
static int
xsltIsDigitZero(unsigned int ch)
{
/*
* Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
*
* There a many more digit ranges in newer Unicode versions. These
* are only the zeros that match Digit in XML 1.0 (IS_DIGIT macro).
*/
switch (ch) {
case 0x0030: case 0x0660: case 0x06F0: case 0x0966:
case 0x09E6: case 0x0A66: case 0x0AE6: case 0x0B66:
case 0x0C66: case 0x0CE6: case 0x0D66: case 0x0E50:
case 0x0E60: case 0x0F20: case 0x1040: case 0x17E0:
case 0x1810: case 0xFF10:
case 0x0ED0: case 0x0F20:
return TRUE;
default:
return FALSE;
@ -365,11 +367,14 @@ xsltNumberFormatTokenize(const xmlChar *format,
tokens->tokens[tokens->nTokens].token = val - 1;
ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len);
}
} else if ( (val == (xmlChar)'A') ||
(val == (xmlChar)'a') ||
(val == (xmlChar)'I') ||
(val == (xmlChar)'i') ) {
} else {
tokens->tokens[tokens->nTokens].token = '0';
tokens->tokens[tokens->nTokens].width = 1;
}
} else if ( (val == 'A') ||
(val == 'a') ||
(val == 'I') ||
(val == 'i') ) {
tokens->tokens[tokens->nTokens].token = val;
ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len);
@ -380,7 +385,7 @@ xsltNumberFormatTokenize(const xmlChar *format,
* not support a numbering sequence that starts with that
* token, it must use a format token of 1."
*/
tokens->tokens[tokens->nTokens].token = (xmlChar)'0';
tokens->tokens[tokens->nTokens].token = '0';
tokens->tokens[tokens->nTokens].width = 1;
}
/*
@ -629,42 +634,51 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
{
int amount = 0;
int cnt;
xmlNodePtr oldCtxtNode;
xmlNodePtr ancestor;
xmlNodePtr preceding;
xmlXPathParserContextPtr parser;
context->xpathCtxt->node = node;
oldCtxtNode = context->xpathCtxt->node;
parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
if (parser) {
/* ancestor-or-self::*[count] */
for (ancestor = node;
(ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE);
ancestor = xmlXPathNextAncestor(parser, ancestor)) {
ancestor = node;
while ((ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE)) {
if ((fromPat != NULL) &&
xsltTestCompMatchList(context, ancestor, fromPat))
break; /* for */
/*
* The xmlXPathNext* iterators require that the context node is
* set to the start node. Calls to xsltTestCompMatch* may also
* leave the context node in an undefined state, so make sure
* that the context node is reset before each iterator invocation.
*/
if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
/* count(preceding-sibling::*) */
cnt = 1;
for (preceding =
xmlXPathNextPrecedingSibling(parser, ancestor);
preceding != NULL;
preceding =
xmlXPathNextPrecedingSibling(parser, preceding)) {
context->xpathCtxt->node = ancestor;
preceding = xmlXPathNextPrecedingSibling(parser, ancestor);
while (preceding != NULL) {
if (xsltTestCompMatchCount(context, preceding, countPat,
node))
cnt++;
context->xpathCtxt->node = ancestor;
preceding =
xmlXPathNextPrecedingSibling(parser, preceding);
}
array[amount++] = (double)cnt;
if (amount >= max)
break; /* for */
}
context->xpathCtxt->node = node;
ancestor = xmlXPathNextAncestor(parser, ancestor);
}
xmlXPathFreeParserContext(parser);
}
context->xpathCtxt->node = oldCtxtNode;
return amount;
}
@ -798,6 +812,16 @@ xsltNumberFormat(xsltTransformContextPtr ctxt,
output);
}
}
/*
* Unlike `match` patterns, `count` and `from` patterns can contain
* variable references, so we have to clear the pattern match
* cache if the "direct" matching algorithm was used.
*/
if (data->countPat != NULL)
xsltCompMatchClearCache(ctxt, data->countPat);
if (data->fromPat != NULL)
xsltCompMatchClearCache(ctxt, data->fromPat);
}
/* Insert number as text node */
xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0);
@ -818,7 +842,8 @@ XSLT_NUMBER_FORMAT_END:
static int
xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltFormatNumberInfoPtr info)
{
int count=0; /* will hold total length of prefix/suffix */
/* will hold total length of prefix/suffix without quote characters */
int count=0;
int len;
while (1) {
@ -916,7 +941,6 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
xmlBufferPtr buffer;
xmlChar *the_format, *prefix = NULL, *suffix = NULL;
xmlChar *nprefix, *nsuffix = NULL;
xmlChar pchar;
int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
double scale;
int j, len;
@ -944,7 +968,7 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
*result = xmlStrdup(BAD_CAST "-");
else
*result = xmlStrdup(self->minusSign);
/* no-break on purpose */
/* Intentional fall-through */
case 1:
if ((self == NULL) || (self->infinity == NULL))
*result = xmlStrcat(*result, BAD_CAST "Infinity");
@ -1241,14 +1265,13 @@ OUTPUT_NUMBER:
xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1));
/* Put the prefix into the buffer */
for (j = 0; j < prefix_length; j++) {
if ((pchar = *prefix++) == SYMBOL_QUOTE) {
len = xmlUTF8Strsize(prefix, 1);
xmlBufferAdd(buffer, prefix, len);
prefix += len;
j += len - 1; /* length of symbol less length of quote */
} else
xmlBufferAdd(buffer, &pchar, 1);
for (j = 0; j < prefix_length; ) {
if (*prefix == SYMBOL_QUOTE)
prefix++;
len = xmlUTF8Strsize(prefix, 1);
xmlBufferAdd(buffer, prefix, len);
prefix += len;
j += len;
}
/* Next do the integer part of the number */
@ -1257,13 +1280,14 @@ OUTPUT_NUMBER:
number = floor((scale * number + 0.5)) / scale;
if ((self->grouping != NULL) &&
(self->grouping[0] != 0)) {
int gchar;
len = xmlStrlen(self->grouping);
pchar = xsltGetUTF8Char(self->grouping, &len);
gchar = xsltGetUTF8Char(self->grouping, &len);
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.integer_digits,
format_info.group,
pchar, len);
gchar, len);
} else
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.integer_digits,
@ -1306,14 +1330,13 @@ OUTPUT_NUMBER:
}
}
/* Put the suffix into the buffer */
for (j = 0; j < suffix_length; j++) {
if ((pchar = *suffix++) == SYMBOL_QUOTE) {
len = xmlUTF8Strsize(suffix, 1);
xmlBufferAdd(buffer, suffix, len);
suffix += len;
j += len - 1; /* length of symbol less length of escape */
} else
xmlBufferAdd(buffer, &pchar, 1);
for (j = 0; j < suffix_length; ) {
if (*suffix == SYMBOL_QUOTE)
suffix++;
len = xmlUTF8Strsize(suffix, 1);
xmlBufferAdd(buffer, suffix, len);
suffix += len;
j += len;
}
*result = xmlStrdup(xmlBufferContent(buffer));

View file

@ -94,7 +94,6 @@ struct _xsltCompMatch {
xmlNsPtr *nsList; /* the namespaces in scope */
int nsNr; /* the number of namespaces in scope */
xsltStepOpPtr steps; /* ops for computation */
int novar; /* doesn't contain variables */
};
typedef struct _xsltParserContext xsltParserContext;
@ -323,20 +322,14 @@ xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp,
xsltAllocateExtra(ctxt->style);
}
if (op == XSLT_OP_PREDICATE) {
xmlXPathContextPtr xctxt;
int flags = 0;
if (ctxt->style != NULL)
xctxt = xmlXPathNewContext(ctxt->style->doc);
else
xctxt = xmlXPathNewContext(NULL);
#ifdef XML_XPATH_NOVAR
if (novar != 0)
xctxt->flags = XML_XPATH_NOVAR;
flags = XML_XPATH_NOVAR;
#endif
if (ctxt->style != NULL)
xctxt->dict = ctxt->style->dict;
comp->steps[comp->nbStep].comp = xmlXPathCtxtCompile(xctxt, value);
xmlXPathFreeContext(xctxt);
comp->steps[comp->nbStep].comp = xsltXPathCompileFlags(ctxt->style,
value, flags);
if (comp->steps[comp->nbStep].comp == NULL) {
xsltTransformError(NULL, ctxt->style, ctxt->elem,
"Failed to compile predicate\n");
@ -576,8 +569,7 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
}
ix = 0;
if ((parent == NULL) || (node->doc == NULL) || isRVT ||
(comp->novar == 0))
if ((parent == NULL) || (node->doc == NULL) || isRVT)
nocache = 1;
if (nocache == 0) {
@ -1232,6 +1224,34 @@ xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node,
return(0);
}
/**
* xsltCompMatchClearCache:
* @ctxt: a XSLT process context
* @comp: the precompiled pattern list
*
* Clear pattern match cache.
*/
void
xsltCompMatchClearCache(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp) {
xsltStepOpPtr sel;
xmlXPathObjectPtr list;
if ((ctxt == NULL) || (comp == NULL))
return;
sel = &comp->steps[0];
list = (xmlXPathObjectPtr) XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra);
if (list != NULL) {
xmlXPathFreeObject(list);
XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra) = NULL;
XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = NULL;
XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = 0;
XSLT_RUNTIME_EXTRA_FREE(ctxt, sel->lenExtra) = NULL;
}
}
/************************************************************************
* *
* Dedicated parser for templates *
@ -1776,9 +1796,7 @@ xsltCompileRelativePathPattern(xsltParserContextPtr ctxt, xmlChar *token, int no
PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
NEXT;
SKIP_BLANKS;
if ((CUR != 0) && (CUR != '|')) {
xsltCompileRelativePathPattern(ctxt, NULL, novar);
}
xsltCompileStepPattern(ctxt, NULL, novar);
} else {
ctxt->error = 1;
}
@ -1843,6 +1861,8 @@ xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar) {
xsltCompileIdKeyPattern(ctxt, name, 1, novar, 0);
xmlFree(name);
name = NULL;
if (ctxt->error)
return;
if ((CUR == '/') && (NXT(1) == '/')) {
PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
NEXT;
@ -1953,7 +1973,6 @@ xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc,
j++;
}
element->nsNr = j;
element->novar = novar;
#ifdef WITH_XSLT_DEBUG_PATTERN
@ -2118,8 +2137,15 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
xmlHashAddEntry2(style->namedTemplates, cur->name, cur->nameURI, cur);
}
if (cur->match == NULL)
if (cur->match == NULL) {
if (cur->name == NULL) {
xsltTransformError(NULL, style, cur->elem,
"xsl:template: need to specify match or name attribute\n");
style->errors++;
return(-1);
}
return(0);
}
priority = cur->priority;
pat = xsltCompilePatternInternal(cur->match, style->doc, cur->elem,
@ -2345,6 +2371,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
case XML_ELEMENT_NODE:
if (node->name[0] == ' ')
break;
/* Intentional fall-through */
case XML_ATTRIBUTE_NODE:
case XML_PI_NODE:
name = node->name;
@ -2382,7 +2409,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
list = NULL;
while (list != NULL) {
if (xsltTestCompMatch(ctxt, list, node,
ctxt->mode, ctxt->modeURI)) {
ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@ -2451,7 +2478,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
ctxt->mode, ctxt->modeURI)) {
ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@ -2468,7 +2495,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
ctxt->mode, ctxt->modeURI)) {
ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@ -2481,7 +2508,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
ctxt->mode, ctxt->modeURI)) {
ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@ -2496,7 +2523,7 @@ keyed_match:
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
ctxt->mode, ctxt->modeURI)) {
ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;

View file

@ -352,16 +352,18 @@ xsltCheckWrite(xsltSecurityPrefsPtr sec,
(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
#if defined(_WIN32) && !defined(__CYGWIN__)
if ((uri->path)&&(uri->path[0]=='/')&&
(uri->path[1]!='\0')&&(uri->path[2]==':'))
ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
else
if ((uri->path)&&(uri->path[0]=='/')&&
(uri->path[1]!='\0')&&(uri->path[2]==':'))
ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
else
#endif
{
/*
* Check if we are allowed to write this file
*/
ret = xsltCheckWritePath(sec, ctxt, uri->path);
}
/*
* Check if we are allowed to write this file
*/
ret = xsltCheckWritePath(sec, ctxt, uri->path);
if (ret <= 0) {
xmlFreeURI(uri);
return(ret);

View file

@ -314,7 +314,7 @@ xsltAttrTemplateValueProcessNode(xsltTransformContextPtr ctxt,
nsNr = i;
}
}
comp = xmlXPathCompile(expr);
comp = xmlXPathCtxtCompile(ctxt->xpathCtxt, expr);
val = xsltEvalXPathStringNs(ctxt, comp, nsNr, nsList);
xmlXPathFreeCompExpr(comp);
xmlFree(expr);
@ -627,11 +627,12 @@ xmlAttrPtr
xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt,
xmlNodePtr target, xmlAttrPtr attrs)
{
xmlAttrPtr attr, copy, last;
xmlAttrPtr attr, copy, last = NULL;
xmlNodePtr oldInsert, text;
xmlNsPtr origNs = NULL, copyNs = NULL;
const xmlChar *value;
xmlChar *valueAVT;
int hasAttr = 0;
if ((ctxt == NULL) || (target == NULL) || (attrs == NULL) ||
(target->type != XML_ELEMENT_NODE))
@ -640,16 +641,35 @@ xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt,
oldInsert = ctxt->insert;
ctxt->insert = target;
/*
* Apply attribute-sets.
*/
attr = attrs;
do {
#ifdef XSLT_REFACTORED
if ((attr->psvi == xsltXSLTAttrMarker) &&
xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets"))
{
xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL);
}
#else
if ((attr->ns != NULL) &&
xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets") &&
xmlStrEqual(attr->ns->href, XSLT_NAMESPACE))
{
xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL);
}
#endif
attr = attr->next;
} while (attr != NULL);
if (target->properties != NULL) {
hasAttr = 1;
}
/*
* Instantiate LRE-attributes.
*/
if (target->properties) {
last = target->properties;
while (last->next != NULL)
last = last->next;
} else {
last = NULL;
}
attr = attrs;
do {
/*
@ -685,35 +705,7 @@ xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt,
value = xmlDictLookup(ctxt->dict, BAD_CAST "", 0);
/*
* Create a new attribute.
*/
copy = xmlNewDocProp(target->doc, attr->name, NULL);
if (copy == NULL) {
if (attr->ns) {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '{%s}%s'.\n",
attr->ns->href, attr->name);
} else {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '%s'.\n",
attr->name);
}
goto error;
}
/*
* Attach it to the target element.
*/
copy->parent = target;
if (last == NULL) {
target->properties = copy;
last = copy;
} else {
last->next = copy;
copy->prev = last;
last = copy;
}
/*
* Set the namespace. Avoid lookups of same namespaces.
* Get the namespace. Avoid lookups of same namespaces.
*/
if (attr->ns != origNs) {
origNs = attr->ns;
@ -730,7 +722,47 @@ xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt,
} else
copyNs = NULL;
}
copy->ns = copyNs;
/*
* Create a new attribute.
*/
if (hasAttr) {
copy = xmlSetNsProp(target, copyNs, attr->name, NULL);
} else {
/*
* Avoid checking for duplicate attributes if there aren't
* any attribute sets.
*/
copy = xmlNewDocProp(target->doc, attr->name, NULL);
if (copy != NULL) {
copy->ns = copyNs;
/*
* Attach it to the target element.
*/
copy->parent = target;
if (last == NULL) {
target->properties = copy;
last = copy;
} else {
last->next = copy;
copy->prev = last;
last = copy;
}
}
}
if (copy == NULL) {
if (attr->ns) {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '{%s}%s'.\n",
attr->ns->href, attr->name);
} else {
xsltTransformError(ctxt, NULL, attr->parent,
"Internal error: Failed to create attribute '%s'.\n",
attr->name);
}
goto error;
}
/*
* Set the value.
@ -785,30 +817,6 @@ next_attribute:
attr = attr->next;
} while (attr != NULL);
/*
* Apply attribute-sets.
* The creation of such attributes will not overwrite any existing
* attribute.
*/
attr = attrs;
do {
#ifdef XSLT_REFACTORED
if ((attr->psvi == xsltXSLTAttrMarker) &&
xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets"))
{
xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL);
}
#else
if ((attr->ns != NULL) &&
xmlStrEqual(attr->name, (const xmlChar *)"use-attribute-sets") &&
xmlStrEqual(attr->ns->href, XSLT_NAMESPACE))
{
xsltApplyAttributeSet(ctxt, ctxt->node, (xmlNodePtr) attr, NULL);
}
#endif
attr = attr->next;
} while (attr != NULL);
ctxt->insert = oldInsert;
return(target->properties);

View file

@ -197,6 +197,8 @@ xsltTemplateParamsCleanup(xsltTransformContextPtr ctxt)
ctxt->vars = NULL;
}
#ifdef WITH_PROFILER
/**
* profPush:
* @ctxt: the transformation context
@ -305,6 +307,8 @@ profCallgraphAdd(xsltTemplatePtr templ, xsltTemplatePtr parent)
}
}
#endif /* WITH_PROFILER */
/**
* xsltPreCompEval:
* @ctxt: transform context
@ -1055,6 +1059,8 @@ xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target,
if ((copy->content = xmlStrdup(cur->content)) == NULL)
return NULL;
}
ctxt->lasttext = NULL;
} else {
/*
* normal processing. keep counters to extend the text node
@ -2170,6 +2176,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
}
}
#ifdef WITH_DEBUGGER
static xmlNodePtr
xsltDebuggerStartSequenceConstructor(xsltTransformContextPtr ctxt,
xmlNodePtr contextNode,
@ -2205,6 +2212,7 @@ xsltDebuggerStartSequenceConstructor(xsltTransformContextPtr ctxt,
}
return(debugedNode);
}
#endif /* WITH_DEBUGGER */
/**
* xsltLocalVariablePush:
@ -2376,6 +2384,17 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
*/
cur = list;
while (cur != NULL) {
if (ctxt->opLimit != 0) {
if (ctxt->opCount >= ctxt->opLimit) {
xsltTransformError(ctxt, NULL, cur,
"xsltApplySequenceConstructor: "
"Operation limit exceeded\n");
ctxt->state = XSLT_STATE_STOPPED;
goto error;
}
ctxt->opCount += 1;
}
ctxt->inst = cur;
#ifdef WITH_DEBUGGER
@ -2832,6 +2851,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
/*
* Search if there are fallbacks
*/
ctxt->insert = insert;
child = cur->children;
while (child != NULL) {
if ((IS_XSLT_ELEM(child)) &&
@ -2843,6 +2863,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
}
child = child->next;
}
ctxt->insert = oldInsert;
if (!found) {
xsltTransformError(ctxt, NULL, cur,
@ -3051,10 +3072,12 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
xsltStackElemPtr withParams)
{
int oldVarsBase = 0;
long start = 0;
xmlNodePtr cur;
xsltStackElemPtr tmpParam = NULL;
xmlDocPtr oldUserFragmentTop;
#ifdef WITH_PROFILER
long start = 0;
#endif
#ifdef XSLT_REFACTORED
xsltStyleItemParamPtr iparam;
@ -3109,12 +3132,16 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
ctxt->varsBase = ctxt->varsNr;
ctxt->node = contextNode;
#ifdef WITH_PROFILER
if (ctxt->profile) {
templ->nbCalls++;
start = xsltTimestamp();
profPush(ctxt, 0);
profCallgraphAdd(templ, ctxt->templ);
}
#endif
/*
* Push the xsl:template declaration onto the stack.
*/
@ -3222,6 +3249,8 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
* Pop the xsl:template declaration from the stack.
*/
templPop(ctxt);
#ifdef WITH_PROFILER
if (ctxt->profile) {
long spent, child, total, end;
@ -3242,6 +3271,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
if (ctxt->profNr > 0)
ctxt->profTab[ctxt->profNr - 1] += total;
}
#endif
#ifdef WITH_DEBUGGER
if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (addCallResult)) {
@ -3399,7 +3429,7 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
* XPath expression.
* (see http://xml.apache.org/xalan-j/extensionslib.html#redirect)
*/
cmp = xmlXPathCompile(URL);
cmp = xmlXPathCtxtCompile(ctxt->xpathCtxt, URL);
val = xsltEvalXPathString(ctxt, cmp);
xmlXPathFreeCompExpr(cmp);
xmlFree(URL);
@ -3458,10 +3488,11 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
*/
if (ctxt->sec != NULL) {
ret = xsltCheckWrite(ctxt->sec, ctxt, filename);
if (ret == 0) {
xsltTransformError(ctxt, NULL, inst,
"xsltDocumentElem: write rights for %s denied\n",
filename);
if (ret <= 0) {
if (ret == 0)
xsltTransformError(ctxt, NULL, inst,
"xsltDocumentElem: write rights for %s denied\n",
filename);
xmlFree(URL);
xmlFree(filename);
return;
@ -4962,7 +4993,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
break;
}
}
/* no break on purpose */
/* Intentional fall-through */
case XML_ELEMENT_NODE:
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
@ -5862,8 +5893,16 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
ctxt->initialContextDoc = doc;
ctxt->initialContextNode = (xmlNodePtr) doc;
if (profile != NULL)
if (profile != NULL) {
#ifdef WITH_PROFILER
ctxt->profile = 1;
#else
xsltTransformError(ctxt, NULL, (xmlNodePtr) doc,
"xsltApplyStylesheetInternal: "
"libxslt compiled without profiler\n");
goto error;
#endif
}
if (output != NULL)
ctxt->outputFile = output;
@ -5976,6 +6015,13 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
res->encoding = xmlStrdup(encoding);
variables = style->variables;
ctxt->node = (xmlNodePtr) doc;
ctxt->output = res;
ctxt->xpathCtxt->contextSize = 1;
ctxt->xpathCtxt->proximityPosition = 1;
ctxt->xpathCtxt->node = NULL; /* TODO: Set the context node here? */
/*
* Start the evaluation, evaluate the params, the stylesheets globals
* and start by processing the top node.
@ -5985,7 +6031,6 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
/*
* Evaluate global params and user-provided params.
*/
ctxt->node = (xmlNodePtr) doc;
if (ctxt->globalVars == NULL)
ctxt->globalVars = xmlHashCreate(20);
if (params != NULL) {
@ -6000,14 +6045,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
/* Clean up any unused RVTs. */
xsltReleaseLocalRVTs(ctxt, NULL);
ctxt->node = (xmlNodePtr) doc;
ctxt->output = res;
ctxt->insert = (xmlNodePtr) res;
ctxt->varsBase = ctxt->varsNr - 1;
ctxt->xpathCtxt->contextSize = 1;
ctxt->xpathCtxt->proximityPosition = 1;
ctxt->xpathCtxt->node = NULL; /* TODO: Set the context node here? */
/*
* Start processing the source tree -----------------------------------
*/
@ -6137,9 +6177,12 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
}
}
xmlXPathFreeNodeSet(ctxt->nodeList);
#ifdef WITH_PROFILER
if (profile != NULL) {
xsltSaveProfiling(ctxt, profile);
}
#endif
/*
* Be pedantic.

View file

@ -184,7 +184,8 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
* This function is unsupported in newer releases of libxslt.
*/
int
xsltExtensionInstructionResultFinalize(xsltTransformContextPtr ctxt)
xsltExtensionInstructionResultFinalize(
xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED)
{
xmlGenericError(xmlGenericErrorContext,
"xsltExtensionInstructionResultFinalize is unsupported "
@ -209,8 +210,9 @@ xsltExtensionInstructionResultFinalize(xsltTransformContextPtr ctxt)
* libxslt.
*/
int
xsltExtensionInstructionResultRegister(xsltTransformContextPtr ctxt,
xmlXPathObjectPtr obj)
xsltExtensionInstructionResultRegister(
xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
xmlXPathObjectPtr obj ATTRIBUTE_UNUSED)
{
return(0);
}
@ -837,7 +839,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
if ((comp != NULL) && (comp->comp != NULL)) {
xpExpr = comp->comp;
} else {
xpExpr = xmlXPathCompile(variable->select);
xpExpr = xmlXPathCtxtCompile(ctxt->xpathCtxt, variable->select);
}
if (xpExpr == NULL)
return(NULL);
@ -1078,7 +1080,7 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
if ((comp != NULL) && (comp->comp != NULL)) {
xpExpr = comp->comp;
} else {
xpExpr = xmlXPathCompile(elem->select);
xpExpr = xmlXPathCtxtCompile(ctxt->xpathCtxt, elem->select);
}
if (xpExpr == NULL)
goto error;
@ -1529,7 +1531,7 @@ xsltProcessUserParamInternal(xsltTransformContextPtr ctxt,
result = NULL;
if (eval != 0) {
xpExpr = xmlXPathCompile(value);
xpExpr = xmlXPathCtxtCompile(ctxt->xpathCtxt, value);
if (xpExpr != NULL) {
xmlDocPtr oldXPDoc;
xmlNodePtr oldXPContextNode;
@ -1946,7 +1948,7 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
* @inst: the xsl:with-param instruction element
*
* Processes an xsl:with-param instruction at transformation time.
* The value is compute, but not recorded.
* The value is computed, but not recorded.
* NOTE that this is also called with an *xsl:param* element
* from exsltFuncFunctionFunction().
*

View file

@ -563,10 +563,6 @@ xsltCompilationCtxtFree(xsltCompilerCtxtPtr cctxt)
}
if (cctxt->tmpList != NULL)
xsltPointerListFree(cctxt->tmpList);
#ifdef XSLT_REFACTORED_XPATHCOMP
if (cctxt->xpathCtxt != NULL)
xmlXPathFreeContext(cctxt->xpathCtxt);
#endif
if (cctxt->nsAliases != NULL)
xsltFreeNsAliasList(cctxt->nsAliases);
@ -602,15 +598,6 @@ xsltCompilationCtxtCreate(xsltStylesheetPtr style) {
if (ret->tmpList == NULL) {
goto internal_err;
}
#ifdef XSLT_REFACTORED_XPATHCOMP
/*
* Create the XPath compilation context in order
* to speed up precompilation of XPath expressions.
*/
ret->xpathCtxt = xmlXPathNewContext(NULL);
if (ret->xpathCtxt == NULL)
goto internal_err;
#endif
return(ret);
@ -732,14 +719,15 @@ internal_err:
#endif
/**
* xsltNewStylesheet:
* xsltNewStylesheetInternal:
* @parent: the parent stylesheet or NULL
*
* Create a new XSLT Stylesheet
*
* Returns the newly allocated xsltStylesheetPtr or NULL in case of error
*/
xsltStylesheetPtr
xsltNewStylesheet(void) {
static xsltStylesheetPtr
xsltNewStylesheetInternal(xsltStylesheetPtr parent) {
xsltStylesheetPtr ret = NULL;
ret = (xsltStylesheetPtr) xmlMalloc(sizeof(xsltStylesheet));
@ -750,6 +738,7 @@ xsltNewStylesheet(void) {
}
memset(ret, 0, sizeof(xsltStylesheet));
ret->parent = parent;
ret->omitXmlDeclaration = -1;
ret->standalone = -1;
ret->decimalFormat = xsltNewDecimalFormat(NULL, NULL);
@ -770,6 +759,21 @@ xsltNewStylesheet(void) {
"creating dictionary for stylesheet\n");
#endif
if (parent == NULL) {
ret->principal = ret;
ret->xpathCtxt = xmlXPathNewContext(NULL);
if (ret->xpathCtxt == NULL) {
xsltTransformError(NULL, NULL, NULL,
"xsltNewStylesheet: xmlXPathNewContext failed\n");
goto internal_err;
}
if (xmlXPathContextSetCache(ret->xpathCtxt, 1, -1, 0) == -1)
goto internal_err;
} else {
ret->principal = parent->principal;
}
xsltInit();
return(ret);
@ -780,6 +784,18 @@ internal_err:
return(NULL);
}
/**
* xsltNewStylesheet:
*
* Create a new XSLT Stylesheet
*
* Returns the newly allocated xsltStylesheetPtr or NULL in case of error
*/
xsltStylesheetPtr
xsltNewStylesheet(void) {
return xsltNewStylesheetInternal(NULL);
}
/**
* xsltAllocateExtra:
* @style: an XSLT stylesheet
@ -1036,6 +1052,9 @@ xsltFreeStylesheet(xsltStylesheetPtr style)
#endif
xmlDictFree(style->dict);
if (style->xpathCtxt != NULL)
xmlXPathFreeContext(style->xpathCtxt);
memset(style, -1, sizeof(xsltStylesheet));
xmlFree(style);
}
@ -1320,8 +1339,8 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
* via the stylesheet's error handling.
*/
xsltTransformError(NULL, style, cur,
"Attribute 'cdata-section-elements': The value "
"'%s' is not a valid QName.\n", element);
"Attribute 'cdata-section-elements': "
"Not a valid QName.\n");
style->errors++;
} else {
xmlNsPtr ns;
@ -5450,7 +5469,7 @@ error:
/**
* xsltIncludeComp:
* @cctxt: the compilation contenxt
* @cctxt: the compilation context
* @node: the xsl:include node
*
* Process the xslt include node on the source node
@ -6503,54 +6522,67 @@ xsltParseStylesheetImportedDoc(xmlDocPtr doc,
if (doc == NULL)
return(NULL);
retStyle = xsltNewStylesheet();
retStyle = xsltNewStylesheetInternal(parentStyle);
if (retStyle == NULL)
return(NULL);
/*
* Set the importing stylesheet module; also used to detect recursion.
*/
retStyle->parent = parentStyle;
if (xsltParseStylesheetUser(retStyle, doc) != 0) {
xsltFreeStylesheet(retStyle);
return(NULL);
}
return(retStyle);
}
/**
* xsltParseStylesheetUser:
* @style: pointer to the stylesheet
* @doc: an xmlDoc parsed XML
*
* Parse an XSLT stylesheet with a user-provided stylesheet struct.
*
* Returns 0 if successful, -1 in case of error.
*/
int
xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) {
if ((style == NULL) || (doc == NULL))
return(-1);
/*
* Adjust the string dict.
*/
if (doc->dict != NULL) {
xmlDictFree(retStyle->dict);
retStyle->dict = doc->dict;
xmlDictFree(style->dict);
style->dict = doc->dict;
#ifdef WITH_XSLT_DEBUG
xsltGenericDebug(xsltGenericDebugContext,
"reusing dictionary from %s for stylesheet\n",
doc->URL);
#endif
xmlDictReference(retStyle->dict);
xmlDictReference(style->dict);
}
/*
* TODO: Eliminate xsltGatherNamespaces(); we must not restrict
* the stylesheet to containt distinct namespace prefixes.
*/
xsltGatherNamespaces(retStyle);
xsltGatherNamespaces(style);
#ifdef XSLT_REFACTORED
{
xsltCompilerCtxtPtr cctxt;
xsltStylesheetPtr oldCurSheet;
if (parentStyle == NULL) {
if (style->parent == NULL) {
xsltPrincipalStylesheetDataPtr principalData;
/*
* Principal stylesheet
* --------------------
*/
retStyle->principal = retStyle;
/*
* Create extra data for the principal stylesheet.
*/
principalData = xsltNewPrincipalStylesheetData();
if (principalData == NULL) {
xsltFreeStylesheet(retStyle);
return(NULL);
return(-1);
}
retStyle->principalData = principalData;
style->principalData = principalData;
/*
* Create the compilation context
* ------------------------------
@ -6558,14 +6590,13 @@ xsltParseStylesheetImportedDoc(xmlDocPtr doc,
* This is currently the only function where the
* compilation context is created.
*/
cctxt = xsltCompilationCtxtCreate(retStyle);
cctxt = xsltCompilationCtxtCreate(style);
if (cctxt == NULL) {
xsltFreeStylesheet(retStyle);
return(NULL);
return(-1);
}
retStyle->compCtxt = (void *) cctxt;
cctxt->style = retStyle;
cctxt->dict = retStyle->dict;
style->compCtxt = (void *) cctxt;
cctxt->style = style;
cctxt->dict = style->dict;
cctxt->psData = principalData;
/*
* Push initial dummy node info.
@ -6576,22 +6607,21 @@ xsltParseStylesheetImportedDoc(xmlDocPtr doc,
/*
* Imported stylesheet.
*/
retStyle->principal = parentStyle->principal;
cctxt = parentStyle->compCtxt;
retStyle->compCtxt = cctxt;
cctxt = style->parent->compCtxt;
style->compCtxt = cctxt;
}
/*
* Save the old and set the current stylesheet structure in the
* compilation context.
*/
oldCurSheet = cctxt->style;
cctxt->style = retStyle;
cctxt->style = style;
retStyle->doc = doc;
xsltParseStylesheetProcess(retStyle, doc);
style->doc = doc;
xsltParseStylesheetProcess(style, doc);
cctxt->style = oldCurSheet;
if (parentStyle == NULL) {
if (style->parent == NULL) {
/*
* Pop the initial dummy node info.
*/
@ -6602,65 +6632,54 @@ xsltParseStylesheetImportedDoc(xmlDocPtr doc,
* stylesheets.
* TODO: really?
*/
/* retStyle->compCtxt = NULL; */
/* style->compCtxt = NULL; */
}
/*
* Free the stylesheet if there were errors.
*/
if (retStyle != NULL) {
if (retStyle->errors != 0) {
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
/*
* Restore all changes made to namespace URIs of ns-decls.
*/
if (cctxt->psData->nsMap)
xsltRestoreDocumentNamespaces(cctxt->psData->nsMap, doc);
#endif
/*
* Detach the doc from the stylesheet; otherwise the doc
* will be freed in xsltFreeStylesheet().
*/
retStyle->doc = NULL;
/*
* Cleanup the doc if its the main stylesheet.
*/
if (parentStyle == NULL) {
xsltCleanupStylesheetTree(doc, xmlDocGetRootElement(doc));
if (retStyle->compCtxt != NULL) {
xsltCompilationCtxtFree(retStyle->compCtxt);
retStyle->compCtxt = NULL;
}
}
xsltFreeStylesheet(retStyle);
retStyle = NULL;
}
}
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
if (style->errors != 0) {
/*
* Restore all changes made to namespace URIs of ns-decls.
*/
if (cctxt->psData->nsMap)
xsltRestoreDocumentNamespaces(cctxt->psData->nsMap, doc);
}
#endif
if (style->parent == NULL) {
xsltCompilationCtxtFree(style->compCtxt);
style->compCtxt = NULL;
}
}
#else /* XSLT_REFACTORED */
/*
* Old behaviour.
*/
retStyle->doc = doc;
if (xsltParseStylesheetProcess(retStyle, doc) == NULL) {
retStyle->doc = NULL;
xsltFreeStylesheet(retStyle);
retStyle = NULL;
}
if (retStyle != NULL) {
if (retStyle->errors != 0) {
retStyle->doc = NULL;
if (parentStyle == NULL)
xsltCleanupStylesheetTree(doc,
xmlDocGetRootElement(doc));
xsltFreeStylesheet(retStyle);
retStyle = NULL;
}
style->doc = doc;
if (xsltParseStylesheetProcess(style, doc) == NULL) {
style->doc = NULL;
return(-1);
}
#endif /* else of XSLT_REFACTORED */
return(retStyle);
if (style->errors != 0) {
/*
* Detach the doc from the stylesheet; otherwise the doc
* will be freed in xsltFreeStylesheet().
*/
style->doc = NULL;
/*
* Cleanup the doc if its the main stylesheet.
*/
if (style->parent == NULL)
xsltCleanupStylesheetTree(doc, xmlDocGetRootElement(doc));
return(-1);
}
if (style->parent == NULL)
xsltResolveStylesheetAttributeSet(style);
return(0);
}
/**
@ -6678,27 +6697,9 @@ xsltParseStylesheetImportedDoc(xmlDocPtr doc,
xsltStylesheetPtr
xsltParseStylesheetDoc(xmlDocPtr doc) {
xsltStylesheetPtr ret;
xsltInitGlobals();
ret = xsltParseStylesheetImportedDoc(doc, NULL);
if (ret == NULL)
return(NULL);
xsltResolveStylesheetAttributeSet(ret);
#ifdef XSLT_REFACTORED
/*
* Free the compilation context.
* TODO: Check if it's better to move this cleanup to
* xsltParseStylesheetImportedDoc().
*/
if (ret->compCtxt != NULL) {
xsltCompilationCtxtFree(XSLT_CCTXT(ret));
ret->compCtxt = NULL;
}
#endif
return(ret);
return(xsltParseStylesheetImportedDoc(doc, NULL));
}
/**
@ -6734,10 +6735,11 @@ xsltParseStylesheetFile(const xmlChar* filename) {
int res;
res = xsltCheckRead(sec, NULL, filename);
if (res == 0) {
xsltTransformError(NULL, NULL, NULL,
"xsltParseStylesheetFile: read rights for %s denied\n",
filename);
if (res <= 0) {
if (res == 0)
xsltTransformError(NULL, NULL, NULL,
"xsltParseStylesheetFile: read rights for %s denied\n",
filename);
return(NULL);
}
}

View file

@ -110,6 +110,19 @@ extern "C" {
#endif
#endif
/**
* WITH_PROFILER:
*
* Activate the compilation of the profiler. Speed penalty
* is insignifiant.
* On by default unless --without-profiler is passed to configure
*/
#if @WITH_PROFILER@
#ifndef WITH_PROFILER
#define WITH_PROFILER
#endif
#endif
/**
* WITH_MODULES:
*
@ -129,9 +142,6 @@ extern "C" {
* This macro is used to flag unused function parameters to GCC
*/
#ifdef __GNUC__
#ifdef HAVE_ANSIDECL_H
#include <ansidecl.h>
#endif
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__((unused))
#endif

View file

@ -1554,7 +1554,15 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
xmlOutputBufferWriteString(buf, "?>\n");
}
if (result->children != NULL) {
xmlNodePtr child = result->children;
xmlNodePtr children = result->children;
xmlNodePtr child = children;
/*
* Hack to avoid quadratic behavior when scanning
* result->children in xmlGetIntSubset called by
* xmlNodeDumpOutput.
*/
result->children = NULL;
while (child != NULL) {
xmlNodeDumpOutput(buf, result, child, 0, (indent == 1),
@ -1567,6 +1575,8 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
}
if (indent)
xmlOutputBufferWriteString(buf, "\n");
result->children = children;
}
xmlOutputBufferFlush(buf);
}
@ -1764,6 +1774,8 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
return 0;
}
#ifdef WITH_PROFILER
/************************************************************************
* *
* Generating profiling information *
@ -2241,6 +2253,8 @@ xsltGetProfileInformation(xsltTransformContextPtr ctxt)
return ret;
}
#endif /* WITH_PROFILER */
/************************************************************************
* *
* Hooks for libxml2 XPath *
@ -2264,25 +2278,7 @@ xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags) {
xmlXPathCompExprPtr ret;
if (style != NULL) {
#ifdef XSLT_REFACTORED_XPATHCOMP
if (XSLT_CCTXT(style)) {
/*
* Proposed by Jerome Pesenti
* --------------------------
* For better efficiency we'll reuse the compilation
* context's XPath context. For the common stylesheet using
* XPath expressions this will reduce compilation time to
* about 50%.
*
* See http://mail.gnome.org/archives/xslt/2006-April/msg00037.html
*/
xpathCtxt = XSLT_CCTXT(style)->xpathCtxt;
xpathCtxt->doc = style->doc;
} else
xpathCtxt = xmlXPathNewContext(style->doc);
#else
xpathCtxt = xmlXPathNewContext(style->doc);
#endif
xpathCtxt = style->principal->xpathCtxt;
if (xpathCtxt == NULL)
return NULL;
xpathCtxt->dict = style->dict;
@ -2298,13 +2294,9 @@ xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags) {
*/
ret = xmlXPathCtxtCompile(xpathCtxt, str);
#ifdef XSLT_REFACTORED_XPATHCOMP
if ((style == NULL) || (! XSLT_CCTXT(style))) {
if (style == NULL) {
xmlXPathFreeContext(xpathCtxt);
}
#else
xmlXPathFreeContext(xpathCtxt);
#endif
/*
* TODO: there is a lot of optimizations which should be possible
* like variable slot precomputations, function precomputations, etc.
@ -2334,6 +2326,23 @@ xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str) {
* *
************************************************************************/
int xslDebugStatus;
/**
* xsltGetDebuggerStatus:
*
* Get xslDebugStatus.
*
* Returns the value of xslDebugStatus.
*/
int
xsltGetDebuggerStatus(void)
{
return(xslDebugStatus);
}
#ifdef WITH_DEBUGGER
/*
* There is currently only 3 debugging callback defined
* Debugger callbacks are disabled by default
@ -2354,8 +2363,6 @@ static xsltDebuggerCallbacks xsltDebuggerCurrentCallbacks = {
NULL /* drop */
};
int xslDebugStatus;
/**
* xsltSetDebuggerStatus:
* @value : the value to be set
@ -2368,19 +2375,6 @@ xsltSetDebuggerStatus(int value)
xslDebugStatus = value;
}
/**
* xsltGetDebuggerStatus:
*
* Get xslDebugStatus.
*
* Returns the value of xslDebugStatus.
*/
int
xsltGetDebuggerStatus(void)
{
return(xslDebugStatus);
}
/**
* xsltSetDebuggerCallbacks:
* @no : number of callbacks
@ -2455,3 +2449,5 @@ xslDropCall(void)
xsltDebuggerCurrentCallbacks.drop();
}
#endif /* WITH_DEBUGGER */

View file

@ -23,21 +23,21 @@ extern "C" {
*
* the version string like "1.2.3"
*/
#define LIBXSLT_DOTTED_VERSION "1.1.33"
#define LIBXSLT_DOTTED_VERSION "1.1.34"
/**
* LIBXSLT_VERSION:
*
* the version number: 1.2.3 value is 1002003
*/
#define LIBXSLT_VERSION 10133
#define LIBXSLT_VERSION 10134
/**
* LIBXSLT_VERSION_STRING:
*
* the version number string, 1.2.3 value is "1002003"
*/
#define LIBXSLT_VERSION_STRING "10133"
#define LIBXSLT_VERSION_STRING "10134"
/**
* LIBXSLT_VERSION_EXTRA:

View file

@ -44,7 +44,7 @@ Used Version: 2.9.10
Website: http://xmlsoft.org | ftp://xmlsoft.org/libxml2/
Title: Libxslt
Used Version: 1.1.33
Used Version: 1.1.34
Website: http://xmlsoft.org
Title: ZLib

View file

@ -44,6 +44,9 @@ XSLTPUBFUN int XSLTCALL
xsltTestCompMatchList (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xsltCompMatchPtr comp);
XSLTPUBFUN void XSLTCALL
xsltCompMatchClearCache (xsltTransformContextPtr ctxt,
xsltCompMatchPtr comp);
XSLTPUBFUN void XSLTCALL
xsltNormalizeCompSteps (void *payload,
void *data,

View file

@ -105,14 +105,6 @@ extern const xmlChar *xsltXSLTAttrMarker;
*/
/* #define XSLT_REFACTORED_XSLT_NSCOMP */
/**
* XSLT_REFACTORED_XPATHCOMP:
*
* Internal define to enable the optimization of the
* compilation of XPath expressions.
*/
#define XSLT_REFACTORED_XPATHCOMP
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
extern const xmlChar *xsltConstNamespaceNameXSLT;
@ -478,7 +470,7 @@ typedef void (*xsltElemPreCompDeallocator) (xsltElemPreCompPtr comp);
*/
struct _xsltElemPreComp {
xsltElemPreCompPtr next; /* next item in the global chained
list hold by xsltStylesheet. */
list held by xsltStylesheet. */
xsltStyleType type; /* type of the element */
xsltTransformFunction func; /* handling function */
xmlNodePtr inst; /* the node in the stylesheet's tree
@ -590,7 +582,7 @@ struct _xsltNsListContainer {
*/
struct _xsltStylePreComp {
xsltElemPreCompPtr next; /* next item in the global chained
list hold by xsltStylesheet */
list held by xsltStylesheet */
xsltStyleType type; /* type of the item */
xsltTransformFunction func; /* handling function */
xmlNodePtr inst; /* the node in the stylesheet's tree
@ -1346,9 +1338,6 @@ struct _xsltCompilerCtxt {
*/
int strict;
xsltPrincipalStylesheetDataPtr psData;
#ifdef XSLT_REFACTORED_XPATHCOMP
xmlXPathContextPtr xpathCtxt;
#endif
xsltStyleItemUknownPtr unknownItem;
int hasNsAliases; /* Indicator if there was an xsl:namespace-alias. */
xsltNsAliasPtr nsAliases;
@ -1642,6 +1631,8 @@ struct _xsltStylesheet {
int forwards_compatible;
xmlHashTablePtr namedTemplates; /* hash table of named templates */
xmlXPathContextPtr xpathCtxt;
};
typedef struct _xsltTransformCache xsltTransformCache;
@ -1789,6 +1780,8 @@ struct _xsltTransformContext {
int depth; /* Needed to catch recursions */
int maxTemplateDepth;
int maxTemplateVars;
unsigned long opLimit;
unsigned long opCount;
};
/**
@ -1871,6 +1864,9 @@ XSLTPUBFUN xsltStylesheetPtr XSLTCALL
XSLTPUBFUN xsltStylesheetPtr XSLTCALL
xsltParseStylesheetImportedDoc(xmlDocPtr doc,
xsltStylesheetPtr style);
XSLTPUBFUN int XSLTCALL
xsltParseStylesheetUser(xsltStylesheetPtr style,
xmlDocPtr doc);
XSLTPUBFUN xsltStylesheetPtr XSLTCALL
xsltLoadStylesheetPI (xmlDocPtr doc);
XSLTPUBFUN void XSLTCALL

View file

@ -20,21 +20,21 @@ extern "C" {
*
* the version string like "1.2.3"
*/
#define LIBXSLT_DOTTED_VERSION "1.1.33"
#define LIBXSLT_DOTTED_VERSION "1.1.34"
/**
* LIBXSLT_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
#define LIBXSLT_VERSION 10133
#define LIBXSLT_VERSION 10134
/**
* LIBXSLT_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
#define LIBXSLT_VERSION_STRING "10133"
#define LIBXSLT_VERSION_STRING "10134"
/**
* LIBXSLT_VERSION_EXTRA:
@ -110,6 +110,19 @@ extern "C" {
#endif
#endif
/**
* WITH_PROFILER:
*
* Activate the compilation of the profiler. Speed penalty
* is insignifiant.
* On by default unless --without-profiler is passed to configure
*/
#if 0
#ifndef WITH_PROFILER
#define WITH_PROFILER
#endif
#endif
/**
* WITH_MODULES:
*
@ -129,9 +142,6 @@ extern "C" {
* This macro is used to flag unused function parameters to GCC
*/
#ifdef __GNUC__
#ifdef HAVE_ANSIDECL_H
#include <ansidecl.h>
#endif
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__((unused))
#endif

View file

@ -80,7 +80,7 @@ extern "C" {
((n)->type == XML_PI_NODE)))
/*
* Our own version of namespaced atributes lookup.
* Our own version of namespaced attributes lookup.
*/
XSLTPUBFUN xmlChar * XSLTCALL
xsltGetNsProp (xmlNodePtr node,