From 2e2bc3addecef3f5ee2668302a3aad6a60216f75 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Sun, 10 Feb 2002 19:21:39 +0000 Subject: [PATCH] adding extra run-time informations to make the stylesheet really read-only * libxslt/imports.c libxslt/numbers.c libxslt/pattern.c libxslt/pattern.h libxslt/transform.c libxslt/xslt.c libxslt/xsltInternals.h: adding extra run-time informations to make the stylesheet really read-only at run-time. Daniel --- ChangeLog | 7 +++ libxslt/imports.c | 1 + libxslt/numbers.c | 8 +-- libxslt/pattern.c | 151 +++++++++++++++++++++++++++++------------------- libxslt/pattern.h | 6 +- libxslt/transform.c | 41 +++++++++++++ libxslt/xslt.c | 68 ++++++++++++++++++++++ libxslt/xsltInternals.h | 22 ++++++- 8 files changed, 239 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2cf494a..5036d26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sun Feb 10 20:16:15 CET 2002 Daniel Veillard + + * libxslt/imports.c libxslt/numbers.c libxslt/pattern.c + libxslt/pattern.h libxslt/transform.c libxslt/xslt.c + libxslt/xsltInternals.h: adding extra run-time informations + to make the stylesheet really read-only at run-time. + Sun Feb 10 16:21:09 CET 2002 Daniel Veillard * libxslt/transform.c: fixing bug #70281 diff --git a/libxslt/imports.c b/libxslt/imports.c index 2a4c11c..40827b2 100644 --- a/libxslt/imports.c +++ b/libxslt/imports.c @@ -100,6 +100,7 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) { res->parent = style; res->next = style->imports; style->imports = res; + style->extrasNr += res->extrasNr; } error: diff --git a/libxslt/numbers.c b/libxslt/numbers.c index f4144fa..6a17eb0 100644 --- a/libxslt/numbers.c +++ b/libxslt/numbers.c @@ -432,9 +432,9 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context, xsltCompMatchPtr fromPat = NULL; if (count != NULL) - countPat = xsltCompilePattern(count, doc, elem); + countPat = xsltCompilePattern(count, doc, elem, NULL, context); if (from != NULL) - fromPat = xsltCompilePattern(from, doc, elem); + fromPat = xsltCompilePattern(from, doc, elem, NULL, context); /* select the starting node */ switch (node->type) { @@ -516,11 +516,11 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, xsltCompMatchPtr fromPat; if (count != NULL) - countPat = xsltCompilePattern(count, doc, elem); + countPat = xsltCompilePattern(count, doc, elem, NULL, context); else countPat = NULL; if (from != NULL) - fromPat = xsltCompilePattern(from, doc, elem); + fromPat = xsltCompilePattern(from, doc, elem, NULL, context); else fromPat = NULL; context->xpathCtxt->node = node; diff --git a/libxslt/pattern.c b/libxslt/pattern.c index 8396b57..36b1ada 100644 --- a/libxslt/pattern.c +++ b/libxslt/pattern.c @@ -71,9 +71,9 @@ struct _xsltStepOp { /* * Optimisations for count */ - xmlNodePtr previous; - int index; - int len; + int previousExtra; + int indexExtra; + int lenExtra; }; struct _xsltCompMatch { @@ -95,6 +95,8 @@ struct _xsltCompMatch { typedef struct _xsltParserContext xsltParserContext; typedef xsltParserContext *xsltParserContextPtr; struct _xsltParserContext { + xsltStylesheetPtr style; /* the stylesheet */ + xsltTransformContextPtr ctxt; /* the transformation or NULL */ const xmlChar *cur; /* the current char being parsed */ const xmlChar *base; /* the full expression */ xmlDocPtr doc; /* the source document */ @@ -189,13 +191,15 @@ xsltFreeCompMatchList(xsltCompMatchPtr comp) { /** * xsltNewParserContext: + * @style: the stylesheet + * @ctxt: the transformation context, if done at run-time * * Create a new XSLT ParserContext * * Returns the newly allocated xsltParserContextPtr or NULL in case of error */ static xsltParserContextPtr -xsltNewParserContext(void) { +xsltNewParserContext(xsltStylesheetPtr style, xsltTransformContextPtr ctxt) { xsltParserContextPtr cur; cur = (xsltParserContextPtr) xmlMalloc(sizeof(xsltParserContext)); @@ -206,6 +210,8 @@ xsltNewParserContext(void) { return(NULL); } memset(cur, 0, sizeof(xsltParserContext)); + cur->style = style; + cur->ctxt = ctxt; return(cur); } @@ -235,19 +241,35 @@ xsltFreeParserContext(xsltParserContextPtr ctxt) { * Returns -1 in case of failure, 0 otherwise. */ static int -xsltCompMatchAdd(xsltCompMatchPtr comp, xsltOp op, xmlChar *value, - xmlChar *value2) { +xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp, + xsltOp op, xmlChar * value, xmlChar * value2) +{ if (comp->nbStep >= 40) { - xsltPrintErrorContext(NULL, NULL, NULL); /* TODO */ + xsltPrintErrorContext(NULL, NULL, NULL); /* TODO */ xsltGenericError(xsltGenericErrorContext, - "xsltCompMatchAdd: overflow\n"); - return(-1); + "xsltCompMatchAdd: overflow\n"); + return (-1); } comp->steps[comp->nbStep].op = op; comp->steps[comp->nbStep].value = value; comp->steps[comp->nbStep].value2 = value2; + if (ctxt->ctxt != NULL) { + comp->steps[comp->nbStep].previousExtra = + xsltAllocateExtraCtxt(ctxt->ctxt); + comp->steps[comp->nbStep].indexExtra = + xsltAllocateExtraCtxt(ctxt->ctxt); + comp->steps[comp->nbStep].lenExtra = + xsltAllocateExtraCtxt(ctxt->ctxt); + } else { + comp->steps[comp->nbStep].previousExtra = + xsltAllocateExtra(ctxt->style); + comp->steps[comp->nbStep].indexExtra = + xsltAllocateExtra(ctxt->style); + comp->steps[comp->nbStep].lenExtra = + xsltAllocateExtra(ctxt->style); + } comp->nbStep++; - return(0); + return (0); } /** @@ -306,21 +328,6 @@ xsltReverseCompMatch(xsltCompMatchPtr comp) { comp->steps[comp->nbStep++].op = XSLT_OP_END; } -/** - * xsltCleanupCompMatch: - * @comp: the compiled match expression - * - * remove all computation state from the pattern - */ -static void -xsltCleanupCompMatch(xsltCompMatchPtr comp) { - int i; - - for (i = 0;i < comp->nbStep;i++) { - comp->steps[i].previous = NULL; - } -} - /************************************************************************ * * * The interpreter for the precompiled patterns * @@ -566,9 +573,15 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, (select->value != NULL) && (node->type == XML_ELEMENT_NODE) && (node->parent != NULL)) { - - if ((select->previous != NULL) && - (select->previous->parent == node->parent)) { + xmlNodePtr previous; + int index; + + previous = (xmlNodePtr) + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra); + index = (int) + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra); + if ((previous != NULL) && + (previous->parent == node->parent)) { /* * just walk back to adjust the index */ @@ -576,7 +589,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr sibling = node; while (sibling != NULL) { - if (sibling == select->previous) + if (sibling == previous) break; if (xmlStrEqual(node->name, sibling->name)) { if ((select->value2 == NULL) || @@ -592,7 +605,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, indx = 0; sibling = node; while (sibling != NULL) { - if (sibling == select->previous) + if (sibling == previous) break; if ((select->value2 == NULL) || ((sibling->ns != NULL) && @@ -603,10 +616,14 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, } } if (sibling != NULL) { - pos = select->index + indx; - len = select->len; - select->previous = node; - select->index = pos; + pos = index + indx; + len = (int) + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra); + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = + node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + index = pos; } else pos = 0; } else { @@ -635,14 +652,24 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, if (pos != 0) { ctxt->xpathCtxt->contextSize = len; ctxt->xpathCtxt->proximityPosition = pos; - select->previous = node; - select->index = pos; - select->len = len; + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = + node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) = + (void *) len; } } else if ((select != NULL) && (select->op == XSLT_OP_ALL) && (node->type == XML_ELEMENT_NODE)) { - if ((select->previous != NULL) && - (select->previous->parent == node->parent)) { + xmlNodePtr previous; + int index; + + previous = (xmlNodePtr) + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra); + index = (int) + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra); + if ((previous != NULL) && + (previous->parent == node->parent)) { /* * just walk back to adjust the index */ @@ -650,7 +677,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr sibling = node; while (sibling != NULL) { - if (sibling == select->previous) + if (sibling == previous) break; if (sibling->type == XML_ELEMENT_NODE) indx++; @@ -661,7 +688,7 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, indx = 0; sibling = node; while (sibling != NULL) { - if (sibling == select->previous) + if (sibling == previous) break; if (sibling->type == XML_ELEMENT_NODE) indx--; @@ -669,10 +696,13 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, } } if (sibling != NULL) { - pos = select->index + indx; - len = select->len; - select->previous = node; - select->index = pos; + pos = index + indx; + len = (int) + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra); + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = + node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; } else pos = 0; } else { @@ -694,9 +724,12 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, if (pos != 0) { ctxt->xpathCtxt->contextSize = len; ctxt->xpathCtxt->proximityPosition = pos; - select->previous = node; - select->index = pos; - select->len = len; + XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra) = + node; + XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra) = + (void *) pos; + XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) = + (void *) len; } } oldNode = ctxt->node; @@ -823,7 +856,7 @@ xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, #define PUSH(op, val, val2) \ - if (xsltCompMatchAdd(ctxt->comp, (op), (val), (val2))) goto error; + if (xsltCompMatchAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error; #define SWAP() \ xsltSwapTopCompMatch(ctxt->comp); @@ -1498,6 +1531,8 @@ error: * @pattern: an XSLT pattern * @doc: the containing document * @node: the containing element + * @style: the stylesheet + * @runtime: the transformation context, if done at run-time * * Compile the XSLT pattern and generates a list of precompiled form suitable * for fast matching. @@ -1508,7 +1543,9 @@ error: */ xsltCompMatchPtr -xsltCompilePattern(const xmlChar *pattern, xmlDocPtr doc, xmlNodePtr node) { +xsltCompilePattern(const xmlChar *pattern, xmlDocPtr doc, + xmlNodePtr node, xsltStylesheetPtr style, + xsltTransformContextPtr runtime) { xsltParserContextPtr ctxt = NULL; xsltCompMatchPtr element, first = NULL, previous = NULL; int current, start, end; @@ -1520,7 +1557,7 @@ xsltCompilePattern(const xmlChar *pattern, xmlDocPtr doc, xmlNodePtr node) { return(NULL); } - ctxt = xsltNewParserContext(); + ctxt = xsltNewParserContext(style, runtime); if (ctxt == NULL) return(NULL); ctxt->doc = doc; @@ -1665,7 +1702,7 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, return(-1); priority = cur->priority; - pat = xsltCompilePattern(cur->match, style->doc, cur->elem); + pat = xsltCompilePattern(cur->match, style->doc, cur->elem, style, NULL); while (pat) { next = pat->next; pat->next = NULL; @@ -1998,13 +2035,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, * the ones it imports. */ void -xsltCleanupTemplates(xsltStylesheetPtr style) { - while (style != NULL) { - xmlHashScan((xmlHashTablePtr) style->templatesHash, - (xmlHashScanner) xsltCleanupCompMatch, NULL); - - style = xsltNextImport(style); - } +xsltCleanupTemplates(xsltStylesheetPtr style ATTRIBUTE_UNUSED) { } /** @@ -2036,6 +2067,7 @@ xsltFreeTemplateHashes(xsltStylesheetPtr style) { xsltFreeCompMatchList(style->commentMatch); } +#if 0 /** * xsltMatchPattern * @node: a node in the source tree @@ -2067,3 +2099,4 @@ xsltMatchPattern(xsltTransformContextPtr context, } return match; } +#endif diff --git a/libxslt/pattern.h b/libxslt/pattern.h index f49c9f9..57b7482 100644 --- a/libxslt/pattern.h +++ b/libxslt/pattern.h @@ -30,7 +30,9 @@ typedef xsltCompMatch *xsltCompMatchPtr; xsltCompMatchPtr xsltCompilePattern (const xmlChar *pattern, xmlDocPtr doc, - xmlNodePtr node); + xmlNodePtr node, + xsltStylesheetPtr style, + xsltTransformContextPtr runtime); void xsltFreeCompMatchList (xsltCompMatchPtr comp); int xsltTestCompMatchList (xsltTransformContextPtr ctxt, xmlNodePtr node, @@ -49,11 +51,13 @@ xsltTemplatePtr xsltGetTemplate (xsltTransformContextPtr ctxt, void xsltFreeTemplateHashes (xsltStylesheetPtr style); void xsltCleanupTemplates (xsltStylesheetPtr style); +#if 0 int xsltMatchPattern (xsltTransformContextPtr ctxt, xmlNodePtr node, const xmlChar *pattern, xmlDocPtr ctxtdoc, xmlNodePtr ctxtnode); +#endif #ifdef __cplusplus } #endif diff --git a/libxslt/transform.c b/libxslt/transform.c index f5ce131..39ec1bb 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -175,6 +175,7 @@ xsltTransformContextPtr xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { xsltTransformContextPtr cur; xsltDocumentPtr docu; + int i; cur = (xsltTransformContextPtr) xmlMalloc(sizeof(xsltTransformContext)); if (cur == NULL) { @@ -217,6 +218,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { cur->varsMax = 5; cur->vars = NULL; cur->varsBase = 0; + /* * the profiling stcka is not initialized by default */ @@ -239,6 +241,35 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { } cur->xpathCtxt->proximityPosition = 0; cur->xpathCtxt->contextSize = 0; + + /* + * Initialize the extras array + */ + if (style->extrasNr != 0) { + cur->extrasMax = style->extrasNr + 20; + cur->extras = (xsltRuntimeExtraPtr) + xmlMalloc(cur->extrasMax * sizeof(xsltRuntimeExtra)); + if (cur->extras == NULL) { + xmlGenericError(xmlGenericErrorContext, + "xsltNewTransformContext: out of memory\n"); + xmlFree(cur->xpathCtxt); + xmlFree(cur->varsTab); + xmlFree(cur->templTab); + xmlFree(cur); + return(NULL); + } + cur->extrasNr = style->extrasNr; + for (i = 0;i < cur->extrasMax;i++) { + cur->extras[i].info = NULL; + cur->extras[i].deallocate = NULL; + } + } else { + cur->extras = NULL; + cur->extrasNr = 0; + cur->extrasMax = 0; + } + + XSLT_REGISTER_VARIABLE_LOOKUP(cur); XSLT_REGISTER_FUNCTION_LOOKUP(cur); cur->xpathCtxt->nsHash = style->nsHash; @@ -280,6 +311,16 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) { xmlFree(ctxt->varsTab); if (ctxt->profTab != NULL) xmlFree(ctxt->profTab); + if ((ctxt->extrasNr > 0) && (ctxt->extras != NULL)) { + int i; + + for (i = 0;i < ctxt->extrasNr;i++) { + if ((ctxt->extras[i].deallocate != NULL) && + (ctxt->extras[i].info != NULL)) + ctxt->extras[i].deallocate(ctxt->extras[i].info); + } + xmlFree(ctxt->extras); + } xsltFreeDocuments(ctxt); xsltFreeCtxtExts(ctxt); xsltFreeGlobalVariables(ctxt); diff --git a/libxslt/xslt.c b/libxslt/xslt.c index 4ae7833..059b46a 100644 --- a/libxslt/xslt.c +++ b/libxslt/xslt.c @@ -346,6 +346,7 @@ xsltNewStylesheet(void) { cur->exclPrefixMax = 0; cur->exclPrefixTab = NULL; cur->extInfos = NULL; + cur->extrasNr = 0; xsltInit(); @@ -353,6 +354,73 @@ xsltNewStylesheet(void) { } /** + * xsltAllocateExtra: + * @style: an XSLT stylesheet + * + * Allocate an extra runtime information slot statically while compiling + * the stylesheet and return its number + * + * Returns the number of the slot + */ +int +xsltAllocateExtra(xsltStylesheetPtr style) +{ + return(style->extrasNr++); +} + +/** + * xsltAllocateExtraCtxt: + * @ctxt: an XSLT transformation context + * + * Allocate an extra runtime information slot at run-time + * and return its number + * This make sure there is a slot ready in the transformation context + * + * Returns the number of the slot + */ +int +xsltAllocateExtraCtxt(xsltTransformContextPtr ctxt) +{ + if (ctxt->extrasNr >= ctxt->extrasMax) { + int i; + if (ctxt->extrasNr == 0) { + ctxt->extrasMax = 20; + ctxt->extras = (xsltRuntimeExtraPtr) + xmlMalloc(ctxt->extrasMax * sizeof(xsltRuntimeExtra)); + if (ctxt->extras == NULL) { + xmlGenericError(xmlGenericErrorContext, + "xsltAllocateExtraCtxt: out of memory\n"); + ctxt->state = XSLT_STATE_ERROR; + return(0); + } + for (i = 0;i < ctxt->extrasMax;i++) { + ctxt->extras[i].info = NULL; + ctxt->extras[i].deallocate = NULL; + } + + } else { + xsltRuntimeExtraPtr tmp; + + ctxt->extrasMax += 100; + tmp = (xsltRuntimeExtraPtr) xmlRealloc(ctxt->extras, + ctxt->extrasMax * sizeof(xsltRuntimeExtra)); + if (tmp == NULL) { + xmlGenericError(xmlGenericErrorContext, + "xsltAllocateExtraCtxt: out of memory\n"); + ctxt->state = XSLT_STATE_ERROR; + return(0); + } + ctxt->extras = tmp; + for (i = ctxt->extrasNr;i < ctxt->extrasMax;i++) { + ctxt->extras[i].info = NULL; + ctxt->extras[i].deallocate = NULL; + } + } + } + return(ctxt->extrasNr++); +} + +/** * xsltFreeStylesheetList: * @sheet: an XSLT stylesheet list * diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index 08e5805..bbb8554 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -37,6 +37,20 @@ extern "C" { #define XSLT_PAT_NO_PRIORITY -12345789 /** + * xsltRuntimeExtra: + * + * Extra information added to the transformation context + */ +typedef struct _xsltRuntimeExtra xsltRuntimeExtra; +typedef xsltRuntimeExtra *xsltRuntimeExtraPtr; +struct _xsltRuntimeExtra { + void *info; /* pointer to the extra data */ + xmlFreeFunc deallocate; /* pointer to the deallocation routine */ +}; + +#define XSLT_RUNTIME_EXTRA(ctxt, nr) (ctxt)->extras[(nr)].info + +/** * xsltTemplate: * * The in-memory structure corresponding to an XSLT Template @@ -354,6 +368,7 @@ struct _xsltStylesheet { * Extensions */ xmlHashTablePtr extInfos; /* the extension data */ + int extrasNr; /* the number of extras required */ }; /* @@ -427,6 +442,10 @@ struct _xsltTransformContext { long *profTab; /* the profile template stack */ void *_private; /* user defined data */ + + int extrasNr; /* the number of extras used */ + int extrasMax; /* the number of extras allocated */ + xsltRuntimeExtraPtr extras; /* extra per runtime informations */ }; /** @@ -482,7 +501,8 @@ xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr self, void xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ); - +int xsltAllocateExtra (xsltStylesheetPtr style); +int xsltAllocateExtraCtxt (xsltTransformContextPtr ctxt); #ifdef __cplusplus } #endif -- 2.7.4