1
0
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:
William M. Brack
2003-12-29 02:52:11 +00:00
parent b15351e54d
commit 081719182d
4 changed files with 179 additions and 82 deletions

View File

@ -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>
* xmlschemas.c: added tests for xs:all to assure minOccurs

View File

@ -356,7 +356,7 @@ xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
/**
* xmlSchemaNewSchema:
* @ctxt: a schema validation context (optional)
* @ctxt: a schema validation context
*
* Allocate a new Schema structure.
*
@ -402,7 +402,7 @@ xmlSchemaNewFacet(void)
/**
* xmlSchemaNewAnnot:
* @ctxt: a schema validation context (optional)
* @ctxt: a schema validation context
* @node: a node
*
* Allocate a new annotation structure.

240
xpath.c
View File

@ -175,7 +175,9 @@ static int xmlXPathDisableOptimizer = 0;
* *
************************************************************************/
/*
* The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
*/
static const char *xmlXPathErrorMessages[] = {
"Ok\n",
"Number encoding\n",
@ -400,9 +402,9 @@ typedef enum {
typedef struct _xmlXPathStepOp xmlXPathStepOp;
typedef xmlXPathStepOp *xmlXPathStepOpPtr;
struct _xmlXPathStepOp {
xmlXPathOp op;
int ch1;
int ch2;
xmlXPathOp op; /* The identifier of the operation */
int ch1; /* First child */
int ch2; /* Second child */
int value;
int value2;
int value3;
@ -413,11 +415,11 @@ struct _xmlXPathStepOp {
};
struct _xmlXPathCompExpr {
int nbStep;
int maxStep;
xmlXPathStepOp *steps; /* ops for computation */
int last;
xmlChar *expr;
int nbStep; /* Number of steps in this expression */
int maxStep; /* Maximum number of steps allocated */
xmlXPathStepOp *steps; /* ops for computation of this expression */
int last; /* index of last step in expression */
xmlChar *expr; /* the expression being computed */
#ifdef DEBUG_EVAL_COUNTS
int nb;
xmlChar *string;
@ -516,7 +518,7 @@ xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
* @value4: the first 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
*/
@ -564,7 +566,7 @@ xmlXPathCompSwap(xmlXPathStepOpPtr op) {
#ifndef LIBXML_THREAD_ENABLED
/*
* 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
*/
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)
#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);
return(0);
}
ret = xmlXPathCastToBoolean(obj);
if (obj->type != XPATH_BOOLEAN)
ret = xmlXPathCastToBoolean(obj);
else
ret = obj->boolval;
xmlXPathFreeObject(obj);
return(ret);
}
@ -1141,7 +1147,10 @@ xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
return(0);
}
ret = xmlXPathCastToNumber(obj);
if (obj->type != XPATH_NUMBER)
ret = xmlXPathCastToNumber(obj);
else
ret = obj->floatval;
xmlXPathFreeObject(obj);
return(ret);
}
@ -1165,7 +1174,7 @@ xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
return(NULL);
}
ret = xmlXPathCastToString(obj);
ret = xmlXPathCastToString(obj); /* this does required strdup */
/* TODO: needs refactoring somewhere else */
if (obj->stringval == ret)
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.
* This stamps all the element nodes with the document order
* Like for line information, the order is kept in the element->content
* field, the value stored is actually - the node number (startting at -1)
* to be able to differenciate from line numbers.
* field, the value stored is actually - the node number (starting at -1)
* 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.
*/
long
@ -1469,7 +1478,7 @@ xmlXPathOrderDocElems(xmlDocPtr doc) {
* Compare two nodes w.r.t document order
*
* 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
xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
@ -1662,9 +1671,9 @@ xmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
* xmlXPathNodeSetFreeNs:
* @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
* 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
xmlXPathNodeSetFreeNs(xmlNsPtr ns) {
@ -1772,9 +1781,9 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
(node->type != XML_ELEMENT_NODE))
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++) {
if ((cur->nodeTab[i] != NULL) &&
@ -1830,9 +1839,9 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
return; /* an XSLT fake node */
#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++)
if (cur->nodeTab[i] == val) return;
@ -1888,7 +1897,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
return; /* an XSLT fake node */
#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
*/
@ -1942,12 +1951,12 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
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;
for (i = 0;i < val2->nodeNr;i++) {
/*
* check against doublons
* check against duplicates
*/
skip = 0;
for (j = 0; j < initNr; j++) {
@ -2025,7 +2034,7 @@ xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
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++) {
/*
@ -2080,12 +2089,12 @@ xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
if (val == NULL) return;
/*
* check against doublons
* find node in nodeTab
*/
for (i = 0;i < cur->nodeNr;i++)
if (cur->nodeTab[i] == val) break;
if (i >= cur->nodeNr) {
if (i >= cur->nodeNr) { /* not found */
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
@ -2134,7 +2143,7 @@ xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
if (obj->nodeTab != NULL) {
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++)
if ((obj->nodeTab[i] != NULL) &&
(obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
@ -2176,7 +2185,7 @@ xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
/**
* xmlGenericErrorContextNodeSet:
* @output: a FILE * for the output
* @obj: the xmlNodeSetPtr to free
* @obj: the xmlNodeSetPtr to display
*
* Quick display of a NodeSet
*/
@ -2235,7 +2244,7 @@ xmlXPathNewNodeSet(xmlNodePtr val) {
ret->type = XPATH_NODESET;
ret->boolval = 0;
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);
}
@ -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:
@ -4031,8 +4040,6 @@ xmlXPathNodeValHash(xmlNodePtr node) {
break;
}
if ((string != NULL) && (string[0] != 0)) {
if (string[0] == 0)
return(0);
if (len == 1) {
return(ret + (((unsigned int) string[0]) << 8));
}
@ -4659,7 +4666,8 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
/* no break on purpose */
case XPATH_NUMBER:
/* Hand check NaN and Infinity equalities */
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
if (xmlXPathIsNaN(arg1->floatval) ||
xmlXPathIsNaN(arg2->floatval)) {
ret = 0;
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
if (xmlXPathIsInf(arg2->floatval) == 1)
@ -4719,7 +4727,8 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
xmlXPathNumberFunction(ctxt, 1);
arg1 = valuePop(ctxt);
/* Hand check NaN and Infinity equalities */
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
if (xmlXPathIsNaN(arg1->floatval) ||
xmlXPathIsNaN(arg2->floatval)) {
ret = 0;
} else if (xmlXPathIsInf(arg1->floatval) == 1) {
if (xmlXPathIsInf(arg2->floatval) == 1)
@ -5539,7 +5548,7 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
if ((ns->next != NULL) &&
(ns->next->type != XML_NAMESPACE_DECL))
return((xmlNodePtr) ns->next);
/* Bad, how did that namespace ended-up there ? */
/* Bad, how did that namespace end up here ? */
return(NULL);
}
}
@ -5583,7 +5592,7 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
if ((ns->next != NULL) &&
(ns->next->type != XML_NAMESPACE_DECL))
return((xmlNodePtr) ns->next);
/* Bad, how did that namespace ended-up there ? */
/* Bad, how did that namespace end up here ? */
return(NULL);
}
case XML_DOCUMENT_NODE:
@ -6295,7 +6304,7 @@ xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
*
* Implement the string() XPath function
* 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
* the node in the node-set that is first in document order.
* 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
* 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
* negative zero nor NaN
* - 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);
cur = valuePop(ctxt);
if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
valuePush(ctxt, xmlXPathNewFloat(0.0));
} else {
if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
for (i = 0; i < cur->nodesetval->nodeNr; i++) {
res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
}
valuePush(ctxt, xmlXPathNewFloat(res));
}
valuePush(ctxt, xmlXPathNewFloat(res));
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.
*/
static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
@ -7226,8 +7233,8 @@ xmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
}
encoding_error:
/*
* If we detect an UTF8 error that probably mean that the
* input encoding didn't get properly advertized in the
* If we detect an UTF8 error that probably means that the
* input encoding didn't get properly advertised in the
* declaration header. Report the error and switch the encoding
* to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !)
@ -7713,7 +7720,7 @@ xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
* Parse a VariableReference, evaluate it and push it on the stack.
*
* 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,
* and may also be of additional types not specified here.
*
@ -7994,7 +8001,7 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
* - a element name
* We do an a priori analysis here rather than having to
* 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.
*/
SKIP_BLANKS;
@ -8073,7 +8080,7 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
}
xmlFree(name);
} else {
/* make sure all cases are covered explicitely */
/* make sure all cases are covered explicitly */
XP_ERROR(XPATH_EXPR_ERROR);
}
}
@ -8435,7 +8442,7 @@ xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
* | 'processing-instruction'
* | '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 *
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
* 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.
*
* Returns the number of node traversed
* Returns the number of nodes traversed
*/
static int
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
@ -9313,7 +9320,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
*
* 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
* 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.
* Returns the number of node traversed
@ -9830,7 +9837,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
* Evaluate the Precompiled XPath operation searching only the last
* element in document order
*
* Returns the number of node traversed
* Returns the number of nodes traversed
*/
static int
xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
@ -9965,7 +9972,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
* @op: an XPath compiled operation
*
* Evaluate the Precompiled XPath operation
* Returns the number of node traversed
* Returns the number of nodes traversed
*/
static int
xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
@ -10537,8 +10544,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
CHECK_ERROR0;
/*
* The result of the evaluation need to be tested to
* decided whether the filter succeeded or not
* The result of the evaluation needs to be tested to
* decide whether the filter succeeded or not
*/
res = valuePop(ctxt);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
@ -10584,7 +10591,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
xmlXPathObjectPtr range;
xmlXPathObjectPtr res, obj;
xmlXPathObjectPtr tmp;
xmlLocationSetPtr newset = NULL;
xmlLocationSetPtr newlocset = NULL;
xmlLocationSetPtr oldlocset;
xmlNodeSetPtr oldset;
int i;
@ -10594,22 +10602,40 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
if (op->ch2 == -1)
return (total);
CHECK_TYPE0(XPATH_NODESET);
obj = valuePop(ctxt);
oldset = obj->nodesetval;
ctxt->context->node = NULL;
if (ctxt->value->type == XPATH_LOCATIONSET) {
/*
* Extract the old locset, and then evaluate the result of the
* 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 < oldset->nodeNr; i++) {
for (i = 0; i < oldlocset->locNr; i++) {
/*
* Run the evaluation with a node list made of a single item
* in the nodeset.
* Run the evaluation with a node list made of a
* single item in the nodelocset.
*/
ctxt->context->node = oldset->nodeTab[i];
ctxt->context->node = oldlocset->locTab[i]->user;
tmp = xmlXPathNewNodeSet(ctxt->context->node);
valuePush(ctxt, tmp);
ctxt->context->contextSize = oldlocset->locNr;
ctxt->context->proximityPosition = i + 1;
if (op->ch2 != -1)
total +=
@ -10622,11 +10648,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
* decided whether the filter succeeded or not
*/
res = valuePop(ctxt);
range =
xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
res);
if (range != NULL) {
xmlXPtrLocationSetAdd(newset, range);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
xmlXPtrLocationSetAdd(newlocset,
xmlXPathObjectCopy
(oldlocset->locTab[i]));
}
/*
@ -10641,6 +10666,55 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
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->contextSize = -1;
ctxt->context->proximityPosition = -1;
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
return (total);
}
#endif /* LIBXML_XPTR_ENABLED */
@ -10771,6 +10845,14 @@ xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
case XPATH_STRING:
return((res->stringval != NULL) &&
(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:
STRANGE
}

View File

@ -2771,6 +2771,10 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
XP_ERROR(XPATH_INVALID_TYPE)
set = valuePop(ctxt);
newset = xmlXPtrLocationSetCreate(NULL);
if (set->nodesetval == NULL) {
goto error;
}
if (set->type == XPATH_NODESET) {
xmlXPathObjectPtr tmp;
@ -2787,7 +2791,6 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
* The loop is to search for each element in the location set
* the list of location set corresponding to that search
*/
newset = xmlXPtrLocationSetCreate(NULL);
for (i = 0;i < oldset->locNr;i++) {
#ifdef DEBUG_RANGES
xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
@ -2851,6 +2854,7 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
/*
* Save the new value and cleanup
*/
error:
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
xmlXPathFreeObject(set);
xmlXPathFreeObject(string);