mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-07-29 15:41:13 +03:00
added DTD like checking when compiling stylesheets, closes bug #160402 and
* libxslt/preproc.c libxslt/xslt.c libxslt/xsltInternals.h: added DTD like checking when compiling stylesheets, closes bug #160402 and a long term TODO * tests/general/bug-89.xsl: thos spotted a misconstruct of one of the test cases where <xsl:when> was not within <xsl:choose> Daniel
This commit is contained in:
10
ChangeLog
10
ChangeLog
@ -1,6 +1,14 @@
|
||||
Tue Mar 29 15:13:59 CEST 2005 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* libxslt/preproc.c libxslt/xslt.c libxslt/xsltInternals.h:
|
||||
added DTD like checking when compiling stylesheets, closes
|
||||
bug #160402 and a long term TODO
|
||||
* tests/general/bug-89.xsl: thos spotted a misconstruct of one
|
||||
of the test cases where <xsl:when> was not within <xsl:choose>
|
||||
|
||||
Mon Mar 21 20:56:43 MST 2005 John Fleck (jfleck@inkstain.net)
|
||||
|
||||
* doc/xsltproc.xml, xsltproc.html, xsltproc.1
|
||||
* doc/xsltproc.xml, xsltproc.html, xsltproc.1:
|
||||
update documentation to reflect addition of --nodtdattr
|
||||
command line flag. Bug #171098
|
||||
|
||||
|
@ -54,7 +54,7 @@ Output each step taken by xsltproc in processing the stylesheet and the document
|
||||
|
||||
.TP
|
||||
\fB\-o\fR or \fB\-\-output\fR \fIfile\fR
|
||||
Direct output to the file named \fIfile\fR\&. For multiple outputs, also known as "chunking", \fB\-o\fR \fBdirectory/\fR directs the output files to a specified directory\&. The directory must already exist\&.
|
||||
Direct output to the file named \fIfile\fR\&. For multiple outputs, also known as "chunking", \fB\-o\fR \fBdirectory/\fR directs the output files to a specified directory\&. The directory must already exist\&.
|
||||
|
||||
.TP
|
||||
\fB\-\-timing\fR
|
||||
@ -110,7 +110,7 @@ Use the SGML catalog specified in \fBSGML_CATALOG_FILES\fR to resolve the locati
|
||||
|
||||
.TP
|
||||
\fB\-\-xinclude\fR
|
||||
Process the input document using the Xinclude specification\&. More details on this can be found in the Xinclude specification: http://www\&.w3\&.org/TR/xinclude/: \fIhttp://www.w3.org/TR/xinclude/\fR
|
||||
Process the input document using the Xinclude specification\&. More details on this can be found in the Xinclude specification: http://www\&.w3\&.org/TR/xinclude/: \fIhttp://www.w3.org/TR/xinclude/\fR
|
||||
|
||||
.TP
|
||||
\fB\-\-profile\fR or \fB\-\-norman\fR
|
||||
|
@ -46,6 +46,158 @@
|
||||
|
||||
const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Grammar checks *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* xsltCheckTopLevelElement:
|
||||
* @style: the XSLT stylesheet
|
||||
* @inst: the XSLT instruction
|
||||
* @err: raise an error or not
|
||||
*
|
||||
* Check that the instruction is instanciated as a top level element.
|
||||
*
|
||||
* Returns -1 in case of error, 0 if failed and 1 in case of success
|
||||
*/
|
||||
static int
|
||||
xsltCheckTopLevelElement(xsltStylesheetPtr style, xmlNodePtr inst, int err) {
|
||||
xmlNodePtr parent;
|
||||
if ((style == NULL) || (inst == NULL) || (inst->ns == NULL))
|
||||
return(-1);
|
||||
|
||||
parent = inst->parent;
|
||||
if (parent == NULL) {
|
||||
if (err) {
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"internal problem: element has no parent\n");
|
||||
style->errors++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
if ((parent->ns == NULL) ||
|
||||
((parent->ns != inst->ns) &&
|
||||
(!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
|
||||
((!xmlStrEqual(parent->name, BAD_CAST "stylesheet")) &&
|
||||
(!xmlStrEqual(parent->name, BAD_CAST "transform")))) {
|
||||
if (err) {
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"element %s only allowed as child of stylesheet\n",
|
||||
inst->name);
|
||||
style->errors++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* xsltCheckInstructionElement:
|
||||
* @style: the XSLT stylesheet
|
||||
* @inst: the XSLT instruction
|
||||
*
|
||||
* Check that the instruction is instanciated as an instruction element.
|
||||
*/
|
||||
static void
|
||||
xsltCheckInstructionElement(xsltStylesheetPtr style, xmlNodePtr inst) {
|
||||
xmlNodePtr parent;
|
||||
int has_ext;
|
||||
|
||||
if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
|
||||
(style->literal_result))
|
||||
return;
|
||||
|
||||
has_ext = (style->extInfos != NULL);
|
||||
|
||||
parent = inst->parent;
|
||||
if (parent == NULL) {
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"internal problem: element has no parent\n");
|
||||
style->errors++;
|
||||
return;
|
||||
}
|
||||
while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
|
||||
if (((parent->ns == inst->ns) ||
|
||||
((parent->ns != NULL) &&
|
||||
(xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
|
||||
((xmlStrEqual(parent->name, BAD_CAST "template")) ||
|
||||
(xmlStrEqual(parent->name, BAD_CAST "param")) ||
|
||||
(xmlStrEqual(parent->name, BAD_CAST "attribute")) ||
|
||||
(xmlStrEqual(parent->name, BAD_CAST "variable")))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we are within an extension element all bets are off
|
||||
* about the semantic there e.g. xsl:param within func:function
|
||||
*/
|
||||
if ((has_ext) && (parent->ns != NULL) &&
|
||||
(xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
|
||||
return;
|
||||
|
||||
parent = parent->parent;
|
||||
}
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"element %s only allowed within a template, variable or param\n",
|
||||
inst->name);
|
||||
style->errors++;
|
||||
}
|
||||
|
||||
/**
|
||||
* xsltCheckParentElement:
|
||||
* @style: the XSLT stylesheet
|
||||
* @inst: the XSLT instruction
|
||||
* @allow1: allowed parent1
|
||||
* @allow2: allowed parent2
|
||||
*
|
||||
* Check that the instruction is instanciated as the childre of one of the
|
||||
* possible parents.
|
||||
*/
|
||||
static void
|
||||
xsltCheckParentElement(xsltStylesheetPtr style, xmlNodePtr inst,
|
||||
const xmlChar *allow1, const xmlChar *allow2) {
|
||||
xmlNodePtr parent;
|
||||
|
||||
if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
|
||||
(style->literal_result))
|
||||
return;
|
||||
|
||||
parent = inst->parent;
|
||||
if (parent == NULL) {
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"internal problem: element has no parent\n");
|
||||
style->errors++;
|
||||
return;
|
||||
}
|
||||
if (((parent->ns == inst->ns) ||
|
||||
((parent->ns != NULL) &&
|
||||
(xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
|
||||
((xmlStrEqual(parent->name, allow1)) ||
|
||||
(xmlStrEqual(parent->name, allow2)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (style->extInfos != NULL) {
|
||||
while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
|
||||
/*
|
||||
* if we are within an extension element all bets are off
|
||||
* about the semantic there e.g. xsl:param within func:function
|
||||
*/
|
||||
if ((parent->ns != NULL) &&
|
||||
(xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
|
||||
return;
|
||||
|
||||
parent = parent->parent;
|
||||
}
|
||||
}
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"element %s is not allowed within that context\n",
|
||||
inst->name);
|
||||
style->errors++;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* handling of precomputed data *
|
||||
@ -1192,91 +1344,129 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
|
||||
xsltStylePreCompPtr cur;
|
||||
|
||||
if (IS_XSLT_NAME(inst, "apply-templates")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltApplyTemplatesComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "with-param")) {
|
||||
xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
|
||||
BAD_CAST "call-template");
|
||||
xsltWithParamComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "value-of")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltValueOfComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "copy")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltCopyComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "copy-of")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltCopyOfComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "if")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltIfComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "when")) {
|
||||
xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
|
||||
xsltWhenComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "choose")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltChooseComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "for-each")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltForEachComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "apply-imports")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltApplyImportsComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "attribute")) {
|
||||
xmlNodePtr parent = inst->parent;
|
||||
|
||||
if ((parent == NULL) || (parent->ns == NULL) ||
|
||||
((parent->ns != inst->ns) &&
|
||||
(!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
|
||||
(!xmlStrEqual(parent->name, BAD_CAST "attribute-set"))) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
}
|
||||
xsltAttributeComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "element")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltElementComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "text")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltTextComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "sort")) {
|
||||
xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
|
||||
BAD_CAST "for-each");
|
||||
xsltSortComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "comment")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltCommentComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "number")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltNumberComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "processing-instruction")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltProcessingInstructionComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "call-template")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltCallTemplateComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "param")) {
|
||||
if (xsltCheckTopLevelElement(style, inst, 0) == 0)
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltParamComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "variable")) {
|
||||
if (xsltCheckTopLevelElement(style, inst, 0) == 0)
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
xsltVariableComp(style, inst);
|
||||
} else if (IS_XSLT_NAME(inst, "otherwise")) {
|
||||
/* no computation needed */
|
||||
xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "template")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "output")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "preserve-space")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "strip-space")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "stylesheet")) {
|
||||
/* no computation needed */
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "transform")) {
|
||||
/* no computation needed */
|
||||
} else if ((IS_XSLT_NAME(inst, "stylesheet")) ||
|
||||
(IS_XSLT_NAME(inst, "transform"))) {
|
||||
xmlNodePtr parent = inst->parent;
|
||||
|
||||
if ((parent == NULL) || (parent->type != XML_DOCUMENT_NODE)) {
|
||||
xsltTransformError(NULL, style, inst,
|
||||
"element %s only allowed only as root element\n",
|
||||
inst->name);
|
||||
style->errors++;
|
||||
}
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "key")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "message")) {
|
||||
/* no computation needed */
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "attribute-set")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "namespace-alias")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "include")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "import")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "decimal-format")) {
|
||||
/* no computation needed */
|
||||
xsltCheckTopLevelElement(style, inst, 1);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "fallback")) {
|
||||
/* no computation needed */
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
return;
|
||||
} else if (IS_XSLT_NAME(inst, "document")) {
|
||||
xsltCheckInstructionElement(style, inst);
|
||||
inst->psvi = (void *) xsltDocumentComp(style, inst,
|
||||
(xsltTransformFunction) xsltDocumentElem);
|
||||
} else {
|
||||
|
@ -375,6 +375,7 @@ xsltNewStylesheet(void) {
|
||||
cur->extInfos = NULL;
|
||||
cur->extrasNr = 0;
|
||||
cur->internalized = 1;
|
||||
cur->literal_result = 0;
|
||||
cur->dict = xmlDictCreate();
|
||||
#ifdef WITH_XSLT_DEBUG
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
@ -1901,8 +1902,6 @@ xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
|
||||
xmlFree(prop);
|
||||
}
|
||||
|
||||
xsltParseStylesheetExtPrefix(style, top);
|
||||
|
||||
cur = top->children;
|
||||
|
||||
/*
|
||||
@ -2048,9 +2047,6 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
|
||||
return(NULL);
|
||||
}
|
||||
xsltParseStylesheetExcludePrefix(ret, cur);
|
||||
if (!ret->nopreproc)
|
||||
xsltPrecomputeStylesheet(ret, cur);
|
||||
|
||||
if ((IS_XSLT_ELEM(cur)) &&
|
||||
((IS_XSLT_NAME(cur, "stylesheet")) ||
|
||||
(IS_XSLT_NAME(cur, "transform")))) {
|
||||
@ -2058,6 +2054,16 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
|
||||
xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltParseStylesheetProcess : found stylesheet\n");
|
||||
#endif
|
||||
ret->literal_result = 0;
|
||||
|
||||
xsltParseStylesheetExtPrefix(ret, cur);
|
||||
} else {
|
||||
ret->literal_result = 1;
|
||||
}
|
||||
if (!ret->nopreproc)
|
||||
xsltPrecomputeStylesheet(ret, cur);
|
||||
|
||||
if (ret->literal_result == 0) {
|
||||
|
||||
xsltParseStylesheetTop(ret, cur);
|
||||
} else {
|
||||
@ -2105,6 +2111,7 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
|
||||
template->elem = (xmlNodePtr) doc;
|
||||
template->content = doc->children;
|
||||
xsltAddTemplate(ret, template, NULL, NULL);
|
||||
ret->literal_result = 1;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
|
@ -447,6 +447,10 @@ struct _xsltStylesheet {
|
||||
* all document text strings were internalized
|
||||
*/
|
||||
int internalized;
|
||||
/*
|
||||
* Literal Result Element as Stylesheet c.f. section 2.3
|
||||
*/
|
||||
int literal_result;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -44,7 +44,7 @@ extern "C" {
|
||||
*
|
||||
* extra version information, used to show a CVS compilation
|
||||
*/
|
||||
#define LIBXSLT_VERSION_EXTRA "-CVS998"
|
||||
#define LIBXSLT_VERSION_EXTRA "-CVS999"
|
||||
|
||||
/**
|
||||
* WITH_XSLT_DEBUG:
|
||||
|
@ -44,9 +44,12 @@ la valeur nulle -->
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:when test="$action='repl'">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$action='del'">
|
||||
<xsl:call-template name="del"/>
|
||||
</xsl:when> <xsl:call-template name="add">
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<xsl:call-template name="add">
|
||||
<xsl:with-param name="type">toto</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:when> </xsl:choose>
|
||||
|
Reference in New Issue
Block a user