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.
diff --git a/xpath.c b/xpath.c
index d620543..0fa53b8 100644
--- a/xpath.c
+++ b/xpath.c
@@ -175,7 +175,9 @@
  *									*
  ************************************************************************/
 
-
+/*
+ * The array xmlXPathErrorMessages corresponds to the enum xmlXPathError
+ */
 static const char *xmlXPathErrorMessages[] = {
     "Ok\n",
     "Number encoding\n",
@@ -400,9 +402,9 @@
 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 _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 @@
  * @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 @@
 #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, (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 @@
 	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 @@
 	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 @@
 	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 @@
  * 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 @@
  * 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 @@
  * 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 @@
 	(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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
     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 @@
     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 @@
 /**
  * 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 @@
     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 @@
 
 /************************************************************************
  *									*
- *			Routines to handle Variable			*
+ *			Routines to handle Variables			*
  *									*
  ************************************************************************/
 
@@ -3065,7 +3074,7 @@
  *									*
  ************************************************************************/
 
-/* Allocations are terrible, one need to optimize all this !!! */
+/* Allocations are terrible, one needs to optimize all this !!! */
 
 /**
  * xmlXPathNewFloat:
@@ -4031,8 +4040,6 @@
 		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 @@
 		    /* 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 @@
 		    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 @@
 		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 @@
 	    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 @@
  *
  * 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 @@
  *
  * 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 @@
 	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 @@
  ************************************************************************/
 
 /*
- * 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 @@
     }
 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 @@
  * 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 @@
 	 *   - 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 @@
 	    }
 	    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 @@
  *		   | '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 @@
  *
  * 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 @@
  *
  * 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 @@
  * 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 @@
  * @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 @@
                         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 @@
                 xmlXPathObjectPtr range;
                 xmlXPathObjectPtr res, obj;
                 xmlXPathObjectPtr tmp;
-                xmlLocationSetPtr newset = NULL;
+                xmlLocationSetPtr newlocset = NULL;
+		    xmlLocationSetPtr oldlocset;
                 xmlNodeSetPtr oldset;
                 int i;
 
@@ -10594,22 +10602,40 @@
                 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 @@
                          * 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 @@
 
                         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 @@
                 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 @@
         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
     }