Imported Upstream version 2.9.5
[platform/upstream/libxml2.git] / xpointer.c
index 0b463dd..c8ebff3 100644 (file)
@@ -7,13 +7,18 @@
  *
  * Added support for the element() scheme described in:
  * W3C Proposed Recommendation 13 November 2002
- * http://www.w3.org/TR/2002/PR-xptr-element-20021113/  
+ * http://www.w3.org/TR/2002/PR-xptr-element-20021113/
  *
  * See Copyright for the status of this software.
  *
  * daniel@veillard.com
  */
 
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
 #endif
 #endif
 
-#define TODO                                                           \
+#define TODO                                                           \
     xmlGenericError(xmlGenericErrorContext,                            \
            "Unimplemented block at %s:%d\n",                           \
             __FILE__, __LINE__);
 
-#define STRANGE                                                        \
+#define STRANGE                                                        \
     xmlGenericError(xmlGenericErrorContext,                            \
            "Internal error at %s:%d\n",                                \
             __FILE__, __LINE__);
 
 /************************************************************************
  *                                                                     *
- *             Some factorized error routines                          *
+ *             Some factorized error routines                          *
  *                                                                     *
  ************************************************************************/
 
@@ -85,7 +90,7 @@ xmlXPtrErrMemory(const char *extra)
  *
  * Handle a redefinition of attribute error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
            const char * msg, const xmlChar *extra)
 {
@@ -99,6 +104,10 @@ xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
                        msg, extra);
        return;
     }
+
+    /* cleanup current last error */
+    xmlResetError(&ctxt->context->lastError);
+
     ctxt->context->lastError.domain = XML_FROM_XPOINTER;
     ctxt->context->lastError.code = error;
     ctxt->context->lastError.level = XML_ERR_ERROR;
@@ -134,7 +143,7 @@ xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level);
 static int
 xmlXPtrGetArity(xmlNodePtr cur) {
     int i;
-    if (cur == NULL) 
+    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(-1);
     cur = cur->children;
     for (i = 0;cur != NULL;cur = cur->next) {
@@ -157,7 +166,7 @@ xmlXPtrGetArity(xmlNodePtr cur) {
 static int
 xmlXPtrGetIndex(xmlNodePtr cur) {
     int i;
-    if (cur == NULL) 
+    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(-1);
     for (i = 1;cur != NULL;cur = cur->prev) {
        if ((cur->type == XML_ELEMENT_NODE) ||
@@ -179,11 +188,11 @@ xmlXPtrGetIndex(xmlNodePtr cur) {
 static xmlNodePtr
 xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
     int i;
-    if (cur == NULL) 
+    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(cur);
     cur = cur->children;
     for (i = 0;i <= no;cur = cur->next) {
-       if (cur == NULL) 
+       if (cur == NULL)
            return(cur);
        if ((cur->type == XML_ELEMENT_NODE) ||
            (cur->type == XML_DOCUMENT_NODE) ||
@@ -320,6 +329,45 @@ xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
 }
 
 /**
+ * xmlXPtrNewRangeInternal:
+ * @start:  the starting node
+ * @startindex:  the start index
+ * @end:  the ending point
+ * @endindex:  the ending index
+ *
+ * Internal function to create a new xmlXPathObjectPtr of type range
+ *
+ * Returns the newly created object.
+ */
+static xmlXPathObjectPtr
+xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex,
+                        xmlNodePtr end, int endindex) {
+    xmlXPathObjectPtr ret;
+
+    /*
+     * Namespace nodes must be copied (see xmlXPathNodeSetDupNs).
+     * Disallow them for now.
+     */
+    if ((start != NULL) && (start->type == XML_NAMESPACE_DECL))
+       return(NULL);
+    if ((end != NULL) && (end->type == XML_NAMESPACE_DECL))
+       return(NULL);
+
+    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+    if (ret == NULL) {
+        xmlXPtrErrMemory("allocating range");
+       return(NULL);
+    }
+    memset(ret, 0, sizeof(xmlXPathObject));
+    ret->type = XPATH_RANGE;
+    ret->user = start;
+    ret->index = startindex;
+    ret->user2 = end;
+    ret->index2 = endindex;
+    return(ret);
+}
+
+/**
  * xmlXPtrNewRange:
  * @start:  the starting node
  * @startindex:  the start index
@@ -344,17 +392,7 @@ xmlXPtrNewRange(xmlNodePtr start, int startindex,
     if (endindex < 0)
        return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = startindex;
-    ret->user2 = end;
-    ret->index2 = endindex;
+    ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -381,17 +419,8 @@ xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
     if (end->type != XPATH_POINT)
        return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start->user;
-    ret->index = start->index;
-    ret->user2 = end->user;
-    ret->index2 = end->index;
+    ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user,
+                                  end->index);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -416,17 +445,7 @@ xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
     if (start->type != XPATH_POINT)
        return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start->user;
-    ret->index = start->index;
-    ret->user2 = end;
-    ret->index2 = -1;
+    ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -453,17 +472,7 @@ xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
     if (end->type != XPATH_POINT)
        return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    ret->user2 = end->user;
-    ret->index2 = end->index;
+    ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -486,17 +495,7 @@ xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
     if (end == NULL)
        return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    ret->user2 = end;
-    ret->index2 = -1;
+    ret = xmlXPtrNewRangeInternal(start, -1, end, -1);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -516,17 +515,7 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
     if (start == NULL)
        return(NULL);
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    ret->user2 = NULL;
-    ret->index2 = -1;
+    ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1);
     return(ret);
 }
 
@@ -541,6 +530,8 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
  */
 xmlXPathObjectPtr
 xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+    xmlNodePtr endNode;
+    int endIndex;
     xmlXPathObjectPtr ret;
 
     if (start == NULL)
@@ -549,47 +540,28 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
        return(NULL);
     switch (end->type) {
        case XPATH_POINT:
+           endNode = end->user;
+           endIndex = end->index;
+           break;
        case XPATH_RANGE:
+           endNode = end->user2;
+           endIndex = end->index2;
            break;
        case XPATH_NODESET:
            /*
-            * Empty set ... 
+            * Empty set ...
             */
-           if (end->nodesetval->nodeNr <= 0)
+           if ((end->nodesetval == NULL) || (end->nodesetval->nodeNr <= 0))
                return(NULL);
+           endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
+           endIndex = -1;
            break;
        default:
            /* TODO */
            return(NULL);
     }
 
-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
-    if (ret == NULL) {
-        xmlXPtrErrMemory("allocating range");
-       return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
-    ret->type = XPATH_RANGE;
-    ret->user = start;
-    ret->index = -1;
-    switch (end->type) {
-       case XPATH_POINT:
-           ret->user2 = end->user;
-           ret->index2 = end->index;
-           break;
-       case XPATH_RANGE:
-           ret->user2 = end->user2;
-           ret->index2 = end->index2;
-           break;
-       case XPATH_NODESET: {
-           ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
-           ret->index2 = -1;
-           break;
-       }
-       default:
-           STRANGE
-           return(NULL);
-    }
+    ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex);
     xmlXPtrRangeCheckOrder(ret);
     return(ret);
 }
@@ -731,7 +703,7 @@ xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
 
     if (i >= cur->locNr) {
 #ifdef DEBUG
-        xmlGenericError(xmlGenericErrorContext, 
+        xmlGenericError(xmlGenericErrorContext,
                "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n");
 #endif
         return;
@@ -903,7 +875,7 @@ static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);
 #define NXT(val) ctxt->cur[(val)]
 #define CUR_PTR ctxt->cur
 
-#define SKIP_BLANKS                                                    \
+#define SKIP_BLANKS                                                    \
     while (IS_BLANK_CH(*(ctxt->cur))) NEXT
 
 #define CURRENT (*ctxt->cur)
@@ -945,7 +917,7 @@ xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) {
  * xmlXPtrEvalXPtrPart:
  * @ctxt:  the XPointer Parser context
  * @name:  the preparsed Scheme for the XPtrPart
- * 
+ *
  * XPtrPart ::= 'xpointer' '(' XPtrExpr ')'
  *            | Scheme '(' SchemeSpecificExpr ')'
  *
@@ -953,7 +925,7 @@ xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) {
  *
  * SchemeSpecificExpr ::= StringWithBalancedParens
  *
- * StringWithBalancedParens ::=  
+ * StringWithBalancedParens ::=
  *              [^()]* ('(' StringWithBalancedParens ')' [^()]*)*
  *              [VC: Parenthesis escaping]
  *
@@ -971,7 +943,7 @@ xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) {
  *
  * Parse and evaluate an XPtrPart. Basically it generates the unescaped
  * string and if the scheme is 'xpointer' it will call the XPath interpreter.
- * 
+ *
  * TODO: there is no new scheme registration mechanism
  */
 
@@ -986,8 +958,10 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
     if (name == NULL)
        XP_ERROR(XPATH_EXPR_ERROR);
 
-    if (CUR != '(')
+    if (CUR != '(') {
+        xmlFree(name);
        XP_ERROR(XPATH_EXPR_ERROR);
+    }
     NEXT;
     level = 1;
 
@@ -996,6 +970,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
     buffer = (xmlChar *) xmlMallocAtomic(len * sizeof (xmlChar));
     if (buffer == NULL) {
         xmlXPtrErrMemory("allocating buffer");
+        xmlFree(name);
        return;
     }
 
@@ -1020,6 +995,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
     *cur = 0;
 
     if ((level != 0) && (CUR == 0)) {
+        xmlFree(name);
        xmlFree(buffer);
        XP_ERROR(XPTR_SYNTAX_ERROR);
     }
@@ -1052,6 +1028,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
            if (name2 == NULL) {
                CUR_PTR = left;
                xmlFree(buffer);
+                xmlFree(name);
                XP_ERROR(XPATH_EXPR_ERROR);
            }
            xmlXPtrEvalChildSeq(ctxt, name2);
@@ -1097,7 +1074,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
            xmlFree(name);
            XP_ERROR(XPATH_MEMORY_ERROR);
        }
-       
+
        xmlXPathRegisterNs(ctxt->context, prefix, URI);
        CUR_PTR = left;
        xmlFree(URI);
@@ -1229,7 +1206,7 @@ xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
     while (CUR == '/') {
        int child = 0;
        NEXT;
-        
+
        while ((CUR >= '0') && (CUR <= '9')) {
            child = child * 10 + (CUR - '0');
            NEXT;
@@ -1253,7 +1230,7 @@ static void
 xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
     if (ctxt->valueTab == NULL) {
        /* Allocate the value stack */
-       ctxt->valueTab = (xmlXPathObjectPtr *) 
+       ctxt->valueTab = (xmlXPathObjectPtr *)
                         xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
        if (ctxt->valueTab == NULL) {
            xmlXPtrErrMemory("allocating evaluation context");
@@ -1332,8 +1309,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
     ret->here = here;
     ret->origin = origin;
 
-    xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
-                        xmlXPtrRangeToFunction);
     xmlXPathRegisterFunc(ret, (xmlChar *)"range",
                         xmlXPtrRangeFunction);
     xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
@@ -1375,6 +1350,8 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
        return(NULL);
 
     ctxt = xmlXPathNewParserContext(str, ctx);
+    if (ctxt == NULL)
+       return(NULL);
     ctxt->xptr = 1;
     xmlXPtrEvalXPointer(ctxt);
 
@@ -1396,13 +1373,13 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
                    /*
                     * Evaluation may push a root nodeset which is unused
                     */
-                   xmlNodeSetPtr set; 
+                   xmlNodeSetPtr set;
                    set = tmp->nodesetval;
-                   if ((set->nodeNr != 1) ||
+                   if ((set == NULL) || (set->nodeNr != 1) ||
                        (set->nodeTab[0] != (xmlNodePtr) ctx->doc))
                        stack++;
                } else
-                   stack++;    
+                   stack++;
            }
            xmlXPathFreeObject(tmp);
         }
@@ -1416,7 +1393,7 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
        xmlXPathFreeObject(res);
        res = NULL;
     }
-        
+
     xmlXPathFreeParserContext(ctxt);
     return(res);
 }
@@ -1444,11 +1421,13 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
        return(NULL);
     start = (xmlNodePtr) range->user;
 
-    if (start == NULL)
+    if ((start == NULL) || (start->type == XML_NAMESPACE_DECL))
        return(NULL);
     end = range->user2;
     if (end == NULL)
        return(xmlCopyNode(start, 1));
+    if (end->type == XML_NAMESPACE_DECL)
+        return(NULL);
 
     cur = start;
     index1 = range->index;
@@ -1478,7 +1457,7 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
                /* prune and return full set */
                if (last != NULL)
                    xmlAddNextSibling(last, tmp);
-               else 
+               else
                    xmlAddChild(parent, tmp);
                return(list);
            } else {
@@ -1732,7 +1711,7 @@ xmlXPtrNbLocChildren(xmlNodePtr node) {
  * @ctxt:  the XPointer Parser context
  * @nargs:  the number of args
  *
- * Function implementing here() operation 
+ * Function implementing here() operation
  * as described in 5.4.3
  */
 static void
@@ -1741,7 +1720,7 @@ xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
 
     if (ctxt->context->here == NULL)
        XP_ERROR(XPTR_SYNTAX_ERROR);
-    
+
     valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));
 }
 
@@ -1750,7 +1729,7 @@ xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  * @ctxt:  the XPointer Parser context
  * @nargs:  the number of args
  *
- * Function implementing origin() operation 
+ * Function implementing origin() operation
  * as described in 5.4.3
  */
 static void
@@ -1759,7 +1738,7 @@ xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
 
     if (ctxt->context->origin == NULL)
        XP_ERROR(XPTR_SYNTAX_ERROR);
-    
+
     valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));
 }
 
@@ -1768,7 +1747,7 @@ xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  * @ctxt:  the XPointer Parser context
  * @nargs:  the number of args
  *
- * Function implementing start-point() operation 
+ * Function implementing start-point() operation
  * as described in 5.4.3
  * ----------------
  * location-set start-point(location-set)
@@ -1805,6 +1784,8 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
         */
        tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
        xmlXPathFreeObject(obj);
+       if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
        obj = tmp;
     }
 
@@ -1829,8 +1810,8 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
                case XPATH_RANGE: {
                    xmlNodePtr node = tmp->user;
                    if (node != NULL) {
-                       if (node->type == XML_ATTRIBUTE_NODE) {
-                           /* TODO: Namespace Nodes ??? */
+                       if ((node->type == XML_ATTRIBUTE_NODE) ||
+                            (node->type == XML_NAMESPACE_DECL)) {
                            xmlXPathFreeObject(obj);
                            xmlXPtrFreeLocationSet(newset);
                            XP_ERROR(XPTR_SYNTAX_ERROR);
@@ -1860,7 +1841,7 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  * @ctxt:  the XPointer Parser context
  * @nargs:  the number of args
  *
- * Function implementing end-point() operation 
+ * Function implementing end-point() operation
  * as described in 5.4.3
  * ----------------------------
  * location-set end-point(location-set)
@@ -1899,10 +1880,16 @@ xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
         */
        tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
        xmlXPathFreeObject(obj);
+       if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
        obj = tmp;
     }
 
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+       xmlXPathFreeObject(obj);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     oldset = (xmlLocationSetPtr) obj->user;
     if (oldset != NULL) {
        int i;
@@ -1919,8 +1906,8 @@ xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
                case XPATH_RANGE: {
                    xmlNodePtr node = tmp->user2;
                    if (node != NULL) {
-                       if (node->type == XML_ATTRIBUTE_NODE) {
-                           /* TODO: Namespace Nodes ??? */
+                       if ((node->type == XML_ATTRIBUTE_NODE) ||
+                            (node->type == XML_NAMESPACE_DECL)) {
                            xmlXPathFreeObject(obj);
                            xmlXPtrFreeLocationSet(newset);
                            XP_ERROR(XPTR_SYNTAX_ERROR);
@@ -1996,7 +1983,7 @@ xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
                        case XML_NOTATION_NODE:
                        case XML_HTML_DOCUMENT_NODE: {
                            int indx = xmlXPtrGetIndex(node);
-                            
+
                            node = node->parent;
                            return(xmlXPtrNewRange(node, indx - 1,
                                                   node, indx + 1));
@@ -2047,6 +2034,8 @@ xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
         */
        tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
        xmlXPathFreeObject(set);
+       if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
        set = tmp;
     }
     oldset = (xmlLocationSetPtr) set->user;
@@ -2055,9 +2044,15 @@ xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
      * The loop is to compute the covering range for each item and add it
      */
     newset = xmlXPtrLocationSetCreate(NULL);
-    for (i = 0;i < oldset->locNr;i++) {
-       xmlXPtrLocationSetAdd(newset,
-               xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
+    if (newset == NULL) {
+       xmlXPathFreeObject(set);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
+    if (oldset != NULL) {
+        for (i = 0;i < oldset->locNr;i++) {
+            xmlXPtrLocationSetAdd(newset,
+                    xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
+        }
     }
 
     /*
@@ -2193,6 +2188,8 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
         */
        tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
        xmlXPathFreeObject(set);
+       if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
        set = tmp;
     }
     oldset = (xmlLocationSetPtr) set->user;
@@ -2201,6 +2198,10 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
      * The loop is to compute the covering range for each item and add it
      */
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+       xmlXPathFreeObject(set);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     for (i = 0;i < oldset->locNr;i++) {
        xmlXPtrLocationSetAdd(newset,
                xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
@@ -2219,76 +2220,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  * @nargs:  the number of args
  *
  * Implement the range-to() XPointer function
+ *
+ * Obsolete. range-to is not a real function but a special type of location
+ * step which is handled in xpath.c.
  */
 void
-xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-    xmlXPathObjectPtr range;
-    const xmlChar *cur;
-    xmlXPathObjectPtr res, obj;
-    xmlXPathObjectPtr tmp;
-    xmlLocationSetPtr newset = NULL;
-    xmlNodeSetPtr oldset;
-    int i;
-
-    if (ctxt == NULL) return;
-    CHECK_ARITY(1);
-    /*
-     * Save the expression pointer since we will have to evaluate
-     * it multiple times. Initialize the new set.
-     */
-    CHECK_TYPE(XPATH_NODESET);
-    obj = valuePop(ctxt);
-    oldset = obj->nodesetval;
-    ctxt->context->node = NULL;
-
-    cur = ctxt->cur;
-    newset = xmlXPtrLocationSetCreate(NULL);
-    
-    for (i = 0; i < oldset->nodeNr; i++) {
-       ctxt->cur = cur;
-
-       /*
-        * 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);
-
-       xmlXPathEvalExpr(ctxt);
-       CHECK_ERROR;
-
-       /*
-        * 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(newset, range);
-       }
-
-       /*
-        * Cleanup
-        */
-       if (res != NULL)
-           xmlXPathFreeObject(res);
-       if (ctxt->value == tmp) {
-           res = valuePop(ctxt);
-           xmlXPathFreeObject(res);
-       }
-       
-       ctxt->context->node = NULL;
-    }
-
-    /*
-     * The result is used as the new evaluation set.
-     */
-    xmlXPathFreeObject(obj);
-    ctxt->context->node = NULL;
-    ctxt->context->contextSize = -1;
-    ctxt->context->proximityPosition = -1;
-    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
+                       int nargs ATTRIBUTE_UNUSED) {
+    XP_ERROR(XPATH_EXPR_ERROR);
 }
 
 /**
@@ -2297,14 +2236,14 @@ xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  * @level: incremented/decremented to show level in tree
  *
  * Advance to the next element or text node in document order
- * TODO: add a stack for entering/exiting entities 
+ * TODO: add a stack for entering/exiting entities
  *
  * Returns -1 in case of failure, 0 otherwise
  */
 xmlNodePtr
 xmlXPtrAdvanceNode(xmlNodePtr cur, int *level) {
 next:
-    if (cur == NULL)
+    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(NULL);
     if (cur->children != NULL) {
         cur = cur->children ;
@@ -2362,7 +2301,7 @@ xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) {
     if ((node == NULL) || (indx == NULL))
        return(-1);
     cur = *node;
-    if (cur == NULL)
+    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(-1);
     pos = *indx;
 
@@ -2400,7 +2339,7 @@ xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) {
            return(0);
        }
        /*
-        * We should have a text (or cdata) node ... 
+        * We should have a text (or cdata) node ...
         */
        len = 0;
        if ((cur->type != XML_ELEMENT_NODE) &&
@@ -2453,13 +2392,12 @@ xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
 
     if (string == NULL)
        return(-1);
-    if (start == NULL)
+    if ((start == NULL) || (start->type == XML_NAMESPACE_DECL))
        return(-1);
-    if ((end == NULL) || (endindex == NULL))
+    if ((end == NULL) || (*end == NULL) ||
+        ((*end)->type == XML_NAMESPACE_DECL) || (endindex == NULL))
        return(-1);
     cur = start;
-    if (cur == NULL)
-       return(-1);
     pos = startindex - 1;
     stringlen = xmlStrlen(string);
 
@@ -2538,13 +2476,12 @@ xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
 
     if (string == NULL)
        return(-1);
-    if ((start == NULL) || (startindex == NULL))
+    if ((start == NULL) || (*start == NULL) ||
+        ((*start)->type == XML_NAMESPACE_DECL) || (startindex == NULL))
        return(-1);
     if ((end == NULL) || (endindex == NULL))
        return(-1);
     cur = *start;
-    if (cur == NULL)
-       return(-1);
     pos = *startindex - 1;
     first = string[0];
 
@@ -2577,7 +2514,7 @@ xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
                    /*
                     * An empty string is considered to match before each
                     * character of the string-value and after the final
-                    * character. 
+                    * character.
                     */
 #ifdef DEBUG_RANGES
                    xmlGenericError(xmlGenericErrorContext,
@@ -2618,14 +2555,12 @@ xmlXPtrGetLastChar(xmlNodePtr *node, int *indx) {
     xmlNodePtr cur;
     int pos, len = 0;
 
-    if ((node == NULL) || (indx == NULL))
+    if ((node == NULL) || (*node == NULL) ||
+        ((*node)->type == XML_NAMESPACE_DECL) || (indx == NULL))
        return(-1);
     cur = *node;
     pos = *indx;
 
-    if (cur == NULL)
-       return(-1);
-
     if ((cur->type == XML_ELEMENT_NODE) ||
        (cur->type == XML_DOCUMENT_NODE) ||
        (cur->type == XML_HTML_DOCUMENT_NODE)) {
@@ -2729,7 +2664,7 @@ xmlXPtrGetEndPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
  * @nargs:  the number of args
  *
  * Function implementing the string-range() function
- * range as described in 5.4.2 
+ * range as described in 5.4.2
  *
  * ------------------------------
  * [Definition: For each location in the location-set argument,
@@ -2798,6 +2733,10 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
 
     set = valuePop(ctxt);
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+       xmlXPathFreeObject(set);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     if (set->nodesetval == NULL) {
         goto error;
     }
@@ -2809,6 +2748,8 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
         */
        tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
        xmlXPathFreeObject(set);
+       if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
        set = tmp;
     }
     oldset = (xmlLocationSetPtr) set->user;
@@ -2893,7 +2834,7 @@ error:
  * @ctxt:  the XPointer Parser context
  *
  *  [8]   Predicate ::=   '[' PredicateExpr ']'
- *  [9]   PredicateExpr ::=   Expr 
+ *  [9]   PredicateExpr ::=   Expr
  *
  * Evaluate a predicate as in xmlXPathEvalPredicate() but for
  * a Location Set instead of a node set
@@ -2942,7 +2883,7 @@ xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
         */
         cur = ctxt->cur;
        newset = xmlXPtrLocationSetCreate(NULL);
-       
+
         for (i = 0; i < oldset->locNr; i++) {
            ctxt->cur = cur;
 
@@ -2978,7 +2919,7 @@ xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
                res = valuePop(ctxt);
                xmlXPathFreeObject(res);
            }
-           
+
            ctxt->context->node = NULL;
        }