mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
edited a couple of comments in accordance with posting on the mailing list
* xmlschemas.c: edited a couple of comments in accordance with posting on the mailing list (no logic change) * xpointer.c: working on Bug 129967, added check for NULL nodeset to prevent crash. Further work required. * xpath.c: working on Bug 129967, added code to handle XPATH_LOCATIONSET in RANGETO code, also added code to handle it in xmlXPathEvaluatePredicateResult. Further work required.
This commit is contained in:
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Mon Dec 28 10:47:32 HKT 2003 William Brack <wbrack@mmm.com.hk>
|
||||||
|
|
||||||
|
* xmlschemas.c: edited a couple of comments in accordance with
|
||||||
|
posting on the mailing list (no logic change)
|
||||||
|
* xpointer.c: working on Bug 129967, added check for NULL
|
||||||
|
nodeset to prevent crash. Further work required.
|
||||||
|
* xpath.c: working on Bug 129967, added code to handle
|
||||||
|
XPATH_LOCATIONSET in RANGETO code, also added code to
|
||||||
|
handle it in xmlXPathEvaluatePredicateResult. Further
|
||||||
|
work required.
|
||||||
|
|
||||||
Sat Dec 27 12:32:58 HKT 2003 William Brack <wbrack@mmm.com.hk>
|
Sat Dec 27 12:32:58 HKT 2003 William Brack <wbrack@mmm.com.hk>
|
||||||
|
|
||||||
* xmlschemas.c: added tests for xs:all to assure minOccurs
|
* xmlschemas.c: added tests for xs:all to assure minOccurs
|
||||||
|
@ -356,7 +356,7 @@ xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlSchemaNewSchema:
|
* xmlSchemaNewSchema:
|
||||||
* @ctxt: a schema validation context (optional)
|
* @ctxt: a schema validation context
|
||||||
*
|
*
|
||||||
* Allocate a new Schema structure.
|
* Allocate a new Schema structure.
|
||||||
*
|
*
|
||||||
@ -402,7 +402,7 @@ xmlSchemaNewFacet(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlSchemaNewAnnot:
|
* xmlSchemaNewAnnot:
|
||||||
* @ctxt: a schema validation context (optional)
|
* @ctxt: a schema validation context
|
||||||
* @node: a node
|
* @node: a node
|
||||||
*
|
*
|
||||||
* Allocate a new annotation structure.
|
* Allocate a new annotation structure.
|
||||||
|
240
xpath.c
240
xpath.c
@ -175,7 +175,9 @@ static int xmlXPathDisableOptimizer = 0;
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
|
||||||
|
*/
|
||||||
static const char *xmlXPathErrorMessages[] = {
|
static const char *xmlXPathErrorMessages[] = {
|
||||||
"Ok\n",
|
"Ok\n",
|
||||||
"Number encoding\n",
|
"Number encoding\n",
|
||||||
@ -400,9 +402,9 @@ typedef enum {
|
|||||||
typedef struct _xmlXPathStepOp xmlXPathStepOp;
|
typedef struct _xmlXPathStepOp xmlXPathStepOp;
|
||||||
typedef xmlXPathStepOp *xmlXPathStepOpPtr;
|
typedef xmlXPathStepOp *xmlXPathStepOpPtr;
|
||||||
struct _xmlXPathStepOp {
|
struct _xmlXPathStepOp {
|
||||||
xmlXPathOp op;
|
xmlXPathOp op; /* The identifier of the operation */
|
||||||
int ch1;
|
int ch1; /* First child */
|
||||||
int ch2;
|
int ch2; /* Second child */
|
||||||
int value;
|
int value;
|
||||||
int value2;
|
int value2;
|
||||||
int value3;
|
int value3;
|
||||||
@ -413,11 +415,11 @@ struct _xmlXPathStepOp {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct _xmlXPathCompExpr {
|
struct _xmlXPathCompExpr {
|
||||||
int nbStep;
|
int nbStep; /* Number of steps in this expression */
|
||||||
int maxStep;
|
int maxStep; /* Maximum number of steps allocated */
|
||||||
xmlXPathStepOp *steps; /* ops for computation */
|
xmlXPathStepOp *steps; /* ops for computation of this expression */
|
||||||
int last;
|
int last; /* index of last step in expression */
|
||||||
xmlChar *expr;
|
xmlChar *expr; /* the expression being computed */
|
||||||
#ifdef DEBUG_EVAL_COUNTS
|
#ifdef DEBUG_EVAL_COUNTS
|
||||||
int nb;
|
int nb;
|
||||||
xmlChar *string;
|
xmlChar *string;
|
||||||
@ -516,7 +518,7 @@ xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
|
|||||||
* @value4: the first string value
|
* @value4: the first string value
|
||||||
* @value5: the second string value
|
* @value5: the second string value
|
||||||
*
|
*
|
||||||
* Add an step to an XPath Compiled Expression
|
* Add a step to an XPath Compiled Expression
|
||||||
*
|
*
|
||||||
* Returns -1 in case of failure, the index otherwise
|
* Returns -1 in case of failure, the index otherwise
|
||||||
*/
|
*/
|
||||||
@ -564,7 +566,7 @@ xmlXPathCompSwap(xmlXPathStepOpPtr op) {
|
|||||||
#ifndef LIBXML_THREAD_ENABLED
|
#ifndef LIBXML_THREAD_ENABLED
|
||||||
/*
|
/*
|
||||||
* Since this manipulates possibly shared variables, this is
|
* Since this manipulates possibly shared variables, this is
|
||||||
* disable if one detects that the library is used in a multithreaded
|
* disabled if one detects that the library is used in a multithreaded
|
||||||
* application
|
* application
|
||||||
*/
|
*/
|
||||||
if (xmlXPathDisableOptimizer)
|
if (xmlXPathDisableOptimizer)
|
||||||
@ -590,7 +592,8 @@ xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
|
|||||||
xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
|
xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
|
||||||
|
|
||||||
#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \
|
#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \
|
||||||
xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL)
|
xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \
|
||||||
|
(val), (val2), 0 ,NULL ,NULL)
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
@ -1117,7 +1120,10 @@ xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
|
|||||||
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
|
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
ret = xmlXPathCastToBoolean(obj);
|
if (obj->type != XPATH_BOOLEAN)
|
||||||
|
ret = xmlXPathCastToBoolean(obj);
|
||||||
|
else
|
||||||
|
ret = obj->boolval;
|
||||||
xmlXPathFreeObject(obj);
|
xmlXPathFreeObject(obj);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
@ -1141,7 +1147,10 @@ xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
|
|||||||
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
|
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
ret = xmlXPathCastToNumber(obj);
|
if (obj->type != XPATH_NUMBER)
|
||||||
|
ret = xmlXPathCastToNumber(obj);
|
||||||
|
else
|
||||||
|
ret = obj->floatval;
|
||||||
xmlXPathFreeObject(obj);
|
xmlXPathFreeObject(obj);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
@ -1165,7 +1174,7 @@ xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
|
|||||||
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
|
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
ret = xmlXPathCastToString(obj);
|
ret = xmlXPathCastToString(obj); /* this does required strdup */
|
||||||
/* TODO: needs refactoring somewhere else */
|
/* TODO: needs refactoring somewhere else */
|
||||||
if (obj->stringval == ret)
|
if (obj->stringval == ret)
|
||||||
obj->stringval = NULL;
|
obj->stringval = NULL;
|
||||||
@ -1418,10 +1427,10 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize)
|
|||||||
* Call this routine to speed up XPath computation on static documents.
|
* Call this routine to speed up XPath computation on static documents.
|
||||||
* This stamps all the element nodes with the document order
|
* This stamps all the element nodes with the document order
|
||||||
* Like for line information, the order is kept in the element->content
|
* Like for line information, the order is kept in the element->content
|
||||||
* field, the value stored is actually - the node number (startting at -1)
|
* field, the value stored is actually - the node number (starting at -1)
|
||||||
* to be able to differenciate from line numbers.
|
* to be able to differentiate from line numbers.
|
||||||
*
|
*
|
||||||
* Returns the number of element found in the document or -1 in case
|
* Returns the number of elements found in the document or -1 in case
|
||||||
* of error.
|
* of error.
|
||||||
*/
|
*/
|
||||||
long
|
long
|
||||||
@ -1469,7 +1478,7 @@ xmlXPathOrderDocElems(xmlDocPtr doc) {
|
|||||||
* Compare two nodes w.r.t document order
|
* Compare two nodes w.r.t document order
|
||||||
*
|
*
|
||||||
* Returns -2 in case of error 1 if first point < second point, 0 if
|
* Returns -2 in case of error 1 if first point < second point, 0 if
|
||||||
* that's the same node, -1 otherwise
|
* it's the same node, -1 otherwise
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
|
xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
|
||||||
@ -1662,9 +1671,9 @@ xmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
|
|||||||
* xmlXPathNodeSetFreeNs:
|
* xmlXPathNodeSetFreeNs:
|
||||||
* @ns: the XPath namespace node found in a nodeset.
|
* @ns: the XPath namespace node found in a nodeset.
|
||||||
*
|
*
|
||||||
* Namespace node in libxml don't match the XPath semantic. In a node set
|
* Namespace nodes in libxml don't match the XPath semantic. In a node set
|
||||||
* the namespace nodes are duplicated and the next pointer is set to the
|
* the namespace nodes are duplicated and the next pointer is set to the
|
||||||
* parent node in the XPath semantic. Check if such a node need to be freed
|
* parent node in the XPath semantic. Check if such a node needs to be freed
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlXPathNodeSetFreeNs(xmlNsPtr ns) {
|
xmlXPathNodeSetFreeNs(xmlNsPtr ns) {
|
||||||
@ -1772,9 +1781,9 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
|
|||||||
(node->type != XML_ELEMENT_NODE))
|
(node->type != XML_ELEMENT_NODE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
/*
|
/*
|
||||||
* check against doublons
|
* prevent duplicates
|
||||||
*/
|
*/
|
||||||
for (i = 0;i < cur->nodeNr;i++) {
|
for (i = 0;i < cur->nodeNr;i++) {
|
||||||
if ((cur->nodeTab[i] != NULL) &&
|
if ((cur->nodeTab[i] != NULL) &&
|
||||||
@ -1830,9 +1839,9 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
|
|||||||
return; /* an XSLT fake node */
|
return; /* an XSLT fake node */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
/*
|
/*
|
||||||
* check against doublons
|
* prevent duplcates
|
||||||
*/
|
*/
|
||||||
for (i = 0;i < cur->nodeNr;i++)
|
for (i = 0;i < cur->nodeNr;i++)
|
||||||
if (cur->nodeTab[i] == val) return;
|
if (cur->nodeTab[i] == val) return;
|
||||||
@ -1888,7 +1897,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
|
|||||||
return; /* an XSLT fake node */
|
return; /* an XSLT fake node */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
/*
|
/*
|
||||||
* grow the nodeTab if needed
|
* grow the nodeTab if needed
|
||||||
*/
|
*/
|
||||||
@ -1942,12 +1951,12 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
|||||||
val1 = xmlXPathNodeSetCreate(NULL);
|
val1 = xmlXPathNodeSetCreate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
initNr = val1->nodeNr;
|
initNr = val1->nodeNr;
|
||||||
|
|
||||||
for (i = 0;i < val2->nodeNr;i++) {
|
for (i = 0;i < val2->nodeNr;i++) {
|
||||||
/*
|
/*
|
||||||
* check against doublons
|
* check against duplicates
|
||||||
*/
|
*/
|
||||||
skip = 0;
|
skip = 0;
|
||||||
for (j = 0; j < initNr; j++) {
|
for (j = 0; j < initNr; j++) {
|
||||||
@ -2025,7 +2034,7 @@ xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
|||||||
val1 = xmlXPathNodeSetCreate(NULL);
|
val1 = xmlXPathNodeSetCreate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
|
|
||||||
for (i = 0;i < val2->nodeNr;i++) {
|
for (i = 0;i < val2->nodeNr;i++) {
|
||||||
/*
|
/*
|
||||||
@ -2080,12 +2089,12 @@ xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
|
|||||||
if (val == NULL) return;
|
if (val == NULL) return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check against doublons
|
* find node in nodeTab
|
||||||
*/
|
*/
|
||||||
for (i = 0;i < cur->nodeNr;i++)
|
for (i = 0;i < cur->nodeNr;i++)
|
||||||
if (cur->nodeTab[i] == val) break;
|
if (cur->nodeTab[i] == val) break;
|
||||||
|
|
||||||
if (i >= cur->nodeNr) {
|
if (i >= cur->nodeNr) { /* not found */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
|
"xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
|
||||||
@ -2134,7 +2143,7 @@ xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
|
|||||||
if (obj->nodeTab != NULL) {
|
if (obj->nodeTab != NULL) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
for (i = 0;i < obj->nodeNr;i++)
|
for (i = 0;i < obj->nodeNr;i++)
|
||||||
if ((obj->nodeTab[i] != NULL) &&
|
if ((obj->nodeTab[i] != NULL) &&
|
||||||
(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
|
(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
|
||||||
@ -2176,7 +2185,7 @@ xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
|
|||||||
/**
|
/**
|
||||||
* xmlGenericErrorContextNodeSet:
|
* xmlGenericErrorContextNodeSet:
|
||||||
* @output: a FILE * for the output
|
* @output: a FILE * for the output
|
||||||
* @obj: the xmlNodeSetPtr to free
|
* @obj: the xmlNodeSetPtr to display
|
||||||
*
|
*
|
||||||
* Quick display of a NodeSet
|
* Quick display of a NodeSet
|
||||||
*/
|
*/
|
||||||
@ -2235,7 +2244,7 @@ xmlXPathNewNodeSet(xmlNodePtr val) {
|
|||||||
ret->type = XPATH_NODESET;
|
ret->type = XPATH_NODESET;
|
||||||
ret->boolval = 0;
|
ret->boolval = 0;
|
||||||
ret->nodesetval = xmlXPathNodeSetCreate(val);
|
ret->nodesetval = xmlXPathNodeSetCreate(val);
|
||||||
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
|
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2834,7 +2843,7 @@ xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
|
|||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Routines to handle Variable *
|
* Routines to handle Variables *
|
||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
@ -3065,7 +3074,7 @@ xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
/* Allocations are terrible, one need to optimize all this !!! */
|
/* Allocations are terrible, one needs to optimize all this !!! */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathNewFloat:
|
* xmlXPathNewFloat:
|
||||||
@ -4031,8 +4040,6 @@ xmlXPathNodeValHash(xmlNodePtr node) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((string != NULL) && (string[0] != 0)) {
|
if ((string != NULL) && (string[0] != 0)) {
|
||||||
if (string[0] == 0)
|
|
||||||
return(0);
|
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
return(ret + (((unsigned int) string[0]) << 8));
|
return(ret + (((unsigned int) string[0]) << 8));
|
||||||
}
|
}
|
||||||
@ -4659,7 +4666,8 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
|
|||||||
/* no break on purpose */
|
/* no break on purpose */
|
||||||
case XPATH_NUMBER:
|
case XPATH_NUMBER:
|
||||||
/* Hand check NaN and Infinity equalities */
|
/* Hand check NaN and Infinity equalities */
|
||||||
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
|
if (xmlXPathIsNaN(arg1->floatval) ||
|
||||||
|
xmlXPathIsNaN(arg2->floatval)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
|
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
|
||||||
if (xmlXPathIsInf(arg2->floatval) == 1)
|
if (xmlXPathIsInf(arg2->floatval) == 1)
|
||||||
@ -4719,7 +4727,8 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
|
|||||||
xmlXPathNumberFunction(ctxt, 1);
|
xmlXPathNumberFunction(ctxt, 1);
|
||||||
arg1 = valuePop(ctxt);
|
arg1 = valuePop(ctxt);
|
||||||
/* Hand check NaN and Infinity equalities */
|
/* Hand check NaN and Infinity equalities */
|
||||||
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
|
if (xmlXPathIsNaN(arg1->floatval) ||
|
||||||
|
xmlXPathIsNaN(arg2->floatval)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
|
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
|
||||||
if (xmlXPathIsInf(arg2->floatval) == 1)
|
if (xmlXPathIsInf(arg2->floatval) == 1)
|
||||||
@ -5539,7 +5548,7 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
if ((ns->next != NULL) &&
|
if ((ns->next != NULL) &&
|
||||||
(ns->next->type != XML_NAMESPACE_DECL))
|
(ns->next->type != XML_NAMESPACE_DECL))
|
||||||
return((xmlNodePtr) ns->next);
|
return((xmlNodePtr) ns->next);
|
||||||
/* Bad, how did that namespace ended-up there ? */
|
/* Bad, how did that namespace end up here ? */
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5583,7 +5592,7 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
if ((ns->next != NULL) &&
|
if ((ns->next != NULL) &&
|
||||||
(ns->next->type != XML_NAMESPACE_DECL))
|
(ns->next->type != XML_NAMESPACE_DECL))
|
||||||
return((xmlNodePtr) ns->next);
|
return((xmlNodePtr) ns->next);
|
||||||
/* Bad, how did that namespace ended-up there ? */
|
/* Bad, how did that namespace end up here ? */
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
case XML_DOCUMENT_NODE:
|
case XML_DOCUMENT_NODE:
|
||||||
@ -6295,7 +6304,7 @@ xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
|||||||
*
|
*
|
||||||
* Implement the string() XPath function
|
* Implement the string() XPath function
|
||||||
* string string(object?)
|
* string string(object?)
|
||||||
* he string function converts an object to a string as follows:
|
* The string function converts an object to a string as follows:
|
||||||
* - A node-set is converted to a string by returning the value of
|
* - A node-set is converted to a string by returning the value of
|
||||||
* the node in the node-set that is first in document order.
|
* the node in the node-set that is first in document order.
|
||||||
* If the node-set is empty, an empty string is returned.
|
* If the node-set is empty, an empty string is returned.
|
||||||
@ -6855,7 +6864,7 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
*
|
*
|
||||||
* Implement the boolean() XPath function
|
* Implement the boolean() XPath function
|
||||||
* boolean boolean(object)
|
* boolean boolean(object)
|
||||||
* he boolean function converts its argument to a boolean as follows:
|
* The boolean function converts its argument to a boolean as follows:
|
||||||
* - a number is true if and only if it is neither positive or
|
* - a number is true if and only if it is neither positive or
|
||||||
* negative zero nor NaN
|
* negative zero nor NaN
|
||||||
* - a node-set is true if and only if it is non-empty
|
* - a node-set is true if and only if it is non-empty
|
||||||
@ -7019,14 +7028,12 @@ xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
XP_ERROR(XPATH_INVALID_TYPE);
|
XP_ERROR(XPATH_INVALID_TYPE);
|
||||||
cur = valuePop(ctxt);
|
cur = valuePop(ctxt);
|
||||||
|
|
||||||
if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
|
if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
|
||||||
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < cur->nodesetval->nodeNr; i++) {
|
for (i = 0; i < cur->nodesetval->nodeNr; i++) {
|
||||||
res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
|
res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
|
||||||
}
|
}
|
||||||
valuePush(ctxt, xmlXPathNewFloat(res));
|
|
||||||
}
|
}
|
||||||
|
valuePush(ctxt, xmlXPathNewFloat(res));
|
||||||
xmlXPathFreeObject(cur);
|
xmlXPathFreeObject(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7141,7 +7148,7 @@ xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* a couple of forward declarations since we use a recursive call based
|
* a few forward declarations since we use a recursive call based
|
||||||
* implementation.
|
* implementation.
|
||||||
*/
|
*/
|
||||||
static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
|
static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
|
||||||
@ -7226,8 +7233,8 @@ xmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
|
|||||||
}
|
}
|
||||||
encoding_error:
|
encoding_error:
|
||||||
/*
|
/*
|
||||||
* If we detect an UTF8 error that probably mean that the
|
* If we detect an UTF8 error that probably means that the
|
||||||
* input encoding didn't get properly advertized in the
|
* input encoding didn't get properly advertised in the
|
||||||
* declaration header. Report the error and switch the encoding
|
* declaration header. Report the error and switch the encoding
|
||||||
* to ISO-Latin-1 (if you don't like this policy, just declare the
|
* to ISO-Latin-1 (if you don't like this policy, just declare the
|
||||||
* encoding !)
|
* encoding !)
|
||||||
@ -7713,7 +7720,7 @@ xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
|
|||||||
* Parse a VariableReference, evaluate it and push it on the stack.
|
* Parse a VariableReference, evaluate it and push it on the stack.
|
||||||
*
|
*
|
||||||
* The variable bindings consist of a mapping from variable names
|
* The variable bindings consist of a mapping from variable names
|
||||||
* to variable values. The value of a variable is an object, which
|
* to variable values. The value of a variable is an object, which can be
|
||||||
* of any of the types that are possible for the value of an expression,
|
* of any of the types that are possible for the value of an expression,
|
||||||
* and may also be of additional types not specified here.
|
* and may also be of additional types not specified here.
|
||||||
*
|
*
|
||||||
@ -7994,7 +8001,7 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
* - a element name
|
* - a element name
|
||||||
* We do an a priori analysis here rather than having to
|
* We do an a priori analysis here rather than having to
|
||||||
* maintain parsed token content through the recursive function
|
* maintain parsed token content through the recursive function
|
||||||
* calls. This looks uglier but makes the code quite easier to
|
* calls. This looks uglier but makes the code easier to
|
||||||
* read/write/debug.
|
* read/write/debug.
|
||||||
*/
|
*/
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -8073,7 +8080,7 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
}
|
}
|
||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
} else {
|
} else {
|
||||||
/* make sure all cases are covered explicitely */
|
/* make sure all cases are covered explicitly */
|
||||||
XP_ERROR(XPATH_EXPR_ERROR);
|
XP_ERROR(XPATH_EXPR_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8435,7 +8442,7 @@ xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
|
|||||||
* | 'processing-instruction'
|
* | 'processing-instruction'
|
||||||
* | 'node'
|
* | 'node'
|
||||||
*
|
*
|
||||||
* Returns the name found and update @test, @type and @prefix appropriately
|
* Returns the name found and updates @test, @type and @prefix appropriately
|
||||||
*/
|
*/
|
||||||
static xmlChar *
|
static xmlChar *
|
||||||
xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
|
xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
|
||||||
@ -8891,11 +8898,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
|
|||||||
*
|
*
|
||||||
* This is the function implementing a step: based on the current list
|
* This is the function implementing a step: based on the current list
|
||||||
* of nodes, it builds up a new list, looking at all nodes under that
|
* of nodes, it builds up a new list, looking at all nodes under that
|
||||||
* axis and selecting them it also do the predicate filtering
|
* axis and selecting them. It also does the predicate filtering
|
||||||
*
|
*
|
||||||
* Pushes the new NodeSet resulting from the search.
|
* Pushes the new NodeSet resulting from the search.
|
||||||
*
|
*
|
||||||
* Returns the number of node traversed
|
* Returns the number of nodes traversed
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
|
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
|
||||||
@ -9313,7 +9320,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
|
|||||||
*
|
*
|
||||||
* This is the function implementing a step: based on the current list
|
* This is the function implementing a step: based on the current list
|
||||||
* of nodes, it builds up a new list, looking at all nodes under that
|
* of nodes, it builds up a new list, looking at all nodes under that
|
||||||
* axis and selecting them it also do the predicate filtering
|
* axis and selecting them. It also does the predicate filtering
|
||||||
*
|
*
|
||||||
* Pushes the new NodeSet resulting from the search.
|
* Pushes the new NodeSet resulting from the search.
|
||||||
* Returns the number of node traversed
|
* Returns the number of node traversed
|
||||||
@ -9830,7 +9837,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
|
|||||||
* Evaluate the Precompiled XPath operation searching only the last
|
* Evaluate the Precompiled XPath operation searching only the last
|
||||||
* element in document order
|
* element in document order
|
||||||
*
|
*
|
||||||
* Returns the number of node traversed
|
* Returns the number of nodes traversed
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||||
@ -9965,7 +9972,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
|||||||
* @op: an XPath compiled operation
|
* @op: an XPath compiled operation
|
||||||
*
|
*
|
||||||
* Evaluate the Precompiled XPath operation
|
* Evaluate the Precompiled XPath operation
|
||||||
* Returns the number of node traversed
|
* Returns the number of nodes traversed
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||||
@ -10537,8 +10544,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|||||||
CHECK_ERROR0;
|
CHECK_ERROR0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The result of the evaluation need to be tested to
|
* The result of the evaluation needs to be tested to
|
||||||
* decided whether the filter succeeded or not
|
* decide whether the filter succeeded or not
|
||||||
*/
|
*/
|
||||||
res = valuePop(ctxt);
|
res = valuePop(ctxt);
|
||||||
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
|
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
|
||||||
@ -10584,7 +10591,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|||||||
xmlXPathObjectPtr range;
|
xmlXPathObjectPtr range;
|
||||||
xmlXPathObjectPtr res, obj;
|
xmlXPathObjectPtr res, obj;
|
||||||
xmlXPathObjectPtr tmp;
|
xmlXPathObjectPtr tmp;
|
||||||
xmlLocationSetPtr newset = NULL;
|
xmlLocationSetPtr newlocset = NULL;
|
||||||
|
xmlLocationSetPtr oldlocset;
|
||||||
xmlNodeSetPtr oldset;
|
xmlNodeSetPtr oldset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -10594,22 +10602,40 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|||||||
if (op->ch2 == -1)
|
if (op->ch2 == -1)
|
||||||
return (total);
|
return (total);
|
||||||
|
|
||||||
CHECK_TYPE0(XPATH_NODESET);
|
if (ctxt->value->type == XPATH_LOCATIONSET) {
|
||||||
obj = valuePop(ctxt);
|
/*
|
||||||
oldset = obj->nodesetval;
|
* Extract the old locset, and then evaluate the result of the
|
||||||
ctxt->context->node = NULL;
|
* expression for all the element in the locset. use it to grow
|
||||||
|
* up a new locset.
|
||||||
|
*/
|
||||||
|
CHECK_TYPE0(XPATH_LOCATIONSET);
|
||||||
|
obj = valuePop(ctxt);
|
||||||
|
oldlocset = obj->user;
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
|
||||||
newset = xmlXPtrLocationSetCreate(NULL);
|
if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
|
||||||
|
ctxt->context->contextSize = 0;
|
||||||
|
ctxt->context->proximityPosition = 0;
|
||||||
|
total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
if (res != NULL)
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
valuePush(ctxt, obj);
|
||||||
|
CHECK_ERROR0;
|
||||||
|
return (total);
|
||||||
|
}
|
||||||
|
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||||
|
|
||||||
if (oldset != NULL) {
|
for (i = 0; i < oldlocset->locNr; i++) {
|
||||||
for (i = 0; i < oldset->nodeNr; i++) {
|
|
||||||
/*
|
/*
|
||||||
* Run the evaluation with a node list made of a single item
|
* Run the evaluation with a node list made of a
|
||||||
* in the nodeset.
|
* single item in the nodelocset.
|
||||||
*/
|
*/
|
||||||
ctxt->context->node = oldset->nodeTab[i];
|
ctxt->context->node = oldlocset->locTab[i]->user;
|
||||||
tmp = xmlXPathNewNodeSet(ctxt->context->node);
|
tmp = xmlXPathNewNodeSet(ctxt->context->node);
|
||||||
valuePush(ctxt, tmp);
|
valuePush(ctxt, tmp);
|
||||||
|
ctxt->context->contextSize = oldlocset->locNr;
|
||||||
|
ctxt->context->proximityPosition = i + 1;
|
||||||
|
|
||||||
if (op->ch2 != -1)
|
if (op->ch2 != -1)
|
||||||
total +=
|
total +=
|
||||||
@ -10622,11 +10648,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|||||||
* decided whether the filter succeeded or not
|
* decided whether the filter succeeded or not
|
||||||
*/
|
*/
|
||||||
res = valuePop(ctxt);
|
res = valuePop(ctxt);
|
||||||
range =
|
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
|
||||||
xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
|
xmlXPtrLocationSetAdd(newlocset,
|
||||||
res);
|
xmlXPathObjectCopy
|
||||||
if (range != NULL) {
|
(oldlocset->locTab[i]));
|
||||||
xmlXPtrLocationSetAdd(newset, range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -10641,6 +10666,55 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|||||||
|
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
}
|
}
|
||||||
|
} else { /* Not a location set */
|
||||||
|
CHECK_TYPE0(XPATH_NODESET);
|
||||||
|
obj = valuePop(ctxt);
|
||||||
|
oldset = obj->nodesetval;
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
|
||||||
|
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||||
|
|
||||||
|
if (oldset != NULL) {
|
||||||
|
for (i = 0; i < oldset->nodeNr; i++) {
|
||||||
|
/*
|
||||||
|
* Run the evaluation with a node list made of a single item
|
||||||
|
* in the nodeset.
|
||||||
|
*/
|
||||||
|
ctxt->context->node = oldset->nodeTab[i];
|
||||||
|
tmp = xmlXPathNewNodeSet(ctxt->context->node);
|
||||||
|
valuePush(ctxt, tmp);
|
||||||
|
|
||||||
|
if (op->ch2 != -1)
|
||||||
|
total +=
|
||||||
|
xmlXPathCompOpEval(ctxt,
|
||||||
|
&comp->steps[op->ch2]);
|
||||||
|
CHECK_ERROR0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The result of the evaluation need to be tested to
|
||||||
|
* decided whether the filter succeeded or not
|
||||||
|
*/
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
range =
|
||||||
|
xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
|
||||||
|
res);
|
||||||
|
if (range != NULL) {
|
||||||
|
xmlXPtrLocationSetAdd(newlocset, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
|
if (res != NULL)
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
if (ctxt->value == tmp) {
|
||||||
|
res = valuePop(ctxt);
|
||||||
|
xmlXPathFreeObject(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt->context->node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -10650,7 +10724,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
|||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
ctxt->context->contextSize = -1;
|
ctxt->context->contextSize = -1;
|
||||||
ctxt->context->proximityPosition = -1;
|
ctxt->context->proximityPosition = -1;
|
||||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
|
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||||
return (total);
|
return (total);
|
||||||
}
|
}
|
||||||
#endif /* LIBXML_XPTR_ENABLED */
|
#endif /* LIBXML_XPTR_ENABLED */
|
||||||
@ -10771,6 +10845,14 @@ xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
|
|||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
return((res->stringval != NULL) &&
|
return((res->stringval != NULL) &&
|
||||||
(xmlStrlen(res->stringval) != 0));
|
(xmlStrlen(res->stringval) != 0));
|
||||||
|
#ifdef LIBXML_XPTR_ENABLED
|
||||||
|
case XPATH_LOCATIONSET:{
|
||||||
|
xmlLocationSetPtr ptr = res->user;
|
||||||
|
if (ptr == NULL)
|
||||||
|
return(0);
|
||||||
|
return (ptr->locNr != 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
STRANGE
|
STRANGE
|
||||||
}
|
}
|
||||||
|
@ -2771,6 +2771,10 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
XP_ERROR(XPATH_INVALID_TYPE)
|
XP_ERROR(XPATH_INVALID_TYPE)
|
||||||
|
|
||||||
set = valuePop(ctxt);
|
set = valuePop(ctxt);
|
||||||
|
newset = xmlXPtrLocationSetCreate(NULL);
|
||||||
|
if (set->nodesetval == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (set->type == XPATH_NODESET) {
|
if (set->type == XPATH_NODESET) {
|
||||||
xmlXPathObjectPtr tmp;
|
xmlXPathObjectPtr tmp;
|
||||||
|
|
||||||
@ -2787,7 +2791,6 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
* The loop is to search for each element in the location set
|
* The loop is to search for each element in the location set
|
||||||
* the list of location set corresponding to that search
|
* the list of location set corresponding to that search
|
||||||
*/
|
*/
|
||||||
newset = xmlXPtrLocationSetCreate(NULL);
|
|
||||||
for (i = 0;i < oldset->locNr;i++) {
|
for (i = 0;i < oldset->locNr;i++) {
|
||||||
#ifdef DEBUG_RANGES
|
#ifdef DEBUG_RANGES
|
||||||
xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
|
xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
|
||||||
@ -2851,6 +2854,7 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
/*
|
/*
|
||||||
* Save the new value and cleanup
|
* Save the new value and cleanup
|
||||||
*/
|
*/
|
||||||
|
error:
|
||||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
|
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
|
||||||
xmlXPathFreeObject(set);
|
xmlXPathFreeObject(set);
|
||||||
xmlXPathFreeObject(string);
|
xmlXPathFreeObject(string);
|
||||||
|
Reference in New Issue
Block a user