Skip to content
Snippets Groups Projects
Commit 7dfaa5b372de authored by Nick Wellnhofer's avatar Nick Wellnhofer
Browse files

Fix saxon:line-number with namespace nodes

exsltSaxonLineNumberFunction must make sure not to pass namespace
"nodes" to xmlGetLineNo. Otherwise, an OOB heap read results which
typically leads to a segfault.

Found with afl-fuzz and ASan.
parent f298d3195bce
No related branches found
No related tags found
No related merge requests found
......@@ -229,7 +229,9 @@
static void
exsltSaxonLineNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlNodePtr cur = NULL;
xmlXPathObjectPtr obj = NULL;
long lineNo = -1;
if (nargs == 0) {
cur = ctxt->context->node;
} else if (nargs == 1) {
......@@ -232,8 +234,7 @@
if (nargs == 0) {
cur = ctxt->context->node;
} else if (nargs == 1) {
xmlXPathObjectPtr obj;
xmlNodeSetPtr nodelist;
int i;
......@@ -246,14 +247,10 @@
obj = valuePop(ctxt);
nodelist = obj->nodesetval;
if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
xmlXPathFreeObject(obj);
valuePush(ctxt, xmlXPathNewFloat(-1));
return;
}
if ((nodelist != NULL) && (nodelist->nodeNr > 0)) {
cur = nodelist->nodeTab[0];
for (i = 1;i < nodelist->nodeNr;i++) {
int ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
if (ret == -1)
cur = nodelist->nodeTab[i];
}
......@@ -254,10 +251,10 @@
cur = nodelist->nodeTab[0];
for (i = 1;i < nodelist->nodeNr;i++) {
int ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
if (ret == -1)
cur = nodelist->nodeTab[i];
}
xmlXPathFreeObject(obj);
}
} else {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
"saxon:line-number() : invalid number of args %d\n",
......@@ -266,8 +263,26 @@
return;
}
valuePush(ctxt, xmlXPathNewFloat(xmlGetLineNo(cur)));
return;
if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL)) {
/*
* The XPath module sets the owner element of a ns-node on
* the ns->next field.
*/
cur = (xmlNodePtr) ((xmlNsPtr) cur)->next;
if (cur == NULL || cur->type != XML_ELEMENT_NODE) {
xsltGenericError(xsltGenericErrorContext,
"Internal error in exsltSaxonLineNumberFunction: "
"Cannot retrieve the doc of a namespace node.\n");
cur = NULL;
}
}
if (cur != NULL)
lineNo = xmlGetLineNo(cur);
valuePush(ctxt, xmlXPathNewFloat(lineNo));
xmlXPathFreeObject(obj);
}
/**
......
......@@ -6,7 +6,8 @@
EXTRA_DIST = \
eval.1.out eval.1.xml eval.1.xsl \
eval.2.out eval.2.xml eval.2.xsl \
eval.3.out eval.3.xml eval.3.xsl
eval.3.out eval.3.xml eval.3.xsl \
lineno.1.out lineno.1.xml lineno.1.xsl
CLEANFILES = .memdump
......
<?xml version="1.0"?>
<results>
<lineno>1</lineno>
<lineno>8</lineno>
<lineno>8</lineno>
</results>
<doc>
<!--
a
couple
of
lines
-->
<elem/>
</doc>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://icl.com/saxon"
exclude-result-prefixes="saxon">
<xsl:output indent="yes"/>
<xsl:template match="/">
<results>
<lineno>
<xsl:value-of select="saxon:line-number(/doc)"/>
</lineno>
<lineno>
<xsl:value-of select="saxon:line-number(/doc/elem)"/>
</lineno>
<lineno>
<xsl:value-of select="saxon:line-number(/doc/elem/namespace::*)"/>
</lineno>
</results>
</xsl:template>
</xsl:stylesheet>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment