Diff for /embedaddon/libxml2/xpath.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2013/07/22 01:22:22 version 1.1.1.3, 2014/06/15 19:53:29
Line 55 Line 55
 #include <libxml/pattern.h>  #include <libxml/pattern.h>
 #endif  #endif
   
   #include "buf.h"
   
 #ifdef LIBXML_PATTERN_ENABLED  #ifdef LIBXML_PATTERN_ENABLED
 #define XPATH_STREAMING  #define XPATH_STREAMING
 #endif  #endif
Line 64 Line 66
             "Unimplemented block at %s:%d\n",                           \              "Unimplemented block at %s:%d\n",                           \
             __FILE__, __LINE__);              __FILE__, __LINE__);
   
   /**
    * WITH_TIM_SORT:
    *
    * Use the Timsort algorithm provided in timsort.h to sort
    * nodeset as this is a great improvement over the old Shell sort
    * used in xmlXPathNodeSetSort()
    */
   #define WITH_TIM_SORT
   
 /*  /*
 * XP_OPTIMIZED_NON_ELEM_COMPARISON:  * XP_OPTIMIZED_NON_ELEM_COMPARISON:
 * If defined, this will use xmlXPathCmpNodesExt() instead of  * If defined, this will use xmlXPathCmpNodesExt() instead of
Line 90 Line 101
 /* #define XP_DEBUG_OBJ_USAGE */  /* #define XP_DEBUG_OBJ_USAGE */
   
 /*  /*
    * XPATH_MAX_STEPS:
    * when compiling an XPath expression we arbitrary limit the maximum
    * number of step operation in the compiled expression. 1000000 is
    * an insanely large value which should never be reached under normal
    * circumstances
    */
   #define XPATH_MAX_STEPS 1000000
   
   /*
    * XPATH_MAX_STACK_DEPTH:
    * when evaluating an XPath expression we arbitrary limit the maximum
    * number of object allowed to be pushed on the stack. 1000000 is
    * an insanely large value which should never be reached under normal
    * circumstances
    */
   #define XPATH_MAX_STACK_DEPTH 1000000
   
   /*
    * XPATH_MAX_NODESET_LENGTH:
    * when evaluating an XPath expression nodesets are created and we
    * arbitrary limit the maximum length of those node set. 10000000 is
    * an insanely large value which should never be reached under normal
    * circumstances, one would first need to construct an in memory tree
    * with more than 10 millions nodes.
    */
   #define XPATH_MAX_NODESET_LENGTH 10000000
   
   /*
  * TODO:   * TODO:
  * There are a few spots where some tests are done which depend upon ascii   * There are a few spots where some tests are done which depend upon ascii
  * data.  These should be enhanced for full UTF8 support (see particularly   * data.  These should be enhanced for full UTF8 support (see particularly
  * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)   * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
  */   */
   
   /*
    * Wrapper for the Timsort argorithm from timsort.h
    */
   #ifdef WITH_TIM_SORT
   #define SORT_NAME libxml_domnode
   #define SORT_TYPE xmlNodePtr
   /**
    * wrap_cmp:
    * @x: a node
    * @y: another node
    *
    * Comparison function for the Timsort implementation
    *
    * Returns -2 in case of error -1 if first point < second point, 0 if
    *         it's the same node, +1 otherwise
    */
   static
   int wrap_cmp( xmlNodePtr x, xmlNodePtr y );
   #ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
       static int xmlXPathCmpNodesExt(xmlNodePtr, xmlNodePtr);
       static int wrap_cmp( xmlNodePtr x, xmlNodePtr y )
       {
           int res = xmlXPathCmpNodesExt(x, y);
           return res == -2 ? res : -res;
       }
   #else
       static int wrap_cmp( xmlNodePtr x, xmlNodePtr y )
       {
           int res = xmlXPathCmpNodes(x, y);
           return res == -2 ? res : -res;
       }
   #endif
   #define SORT_CMP(x, y)  (wrap_cmp(x, y))
   #include "timsort.h"
   #endif /* WITH_TIM_SORT */
   
 #if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)  #if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
   
 /************************************************************************  /************************************************************************
Line 253  static const char *xmlXPathErrorMessages[] = { Line 328  static const char *xmlXPathErrorMessages[] = {
     "Char out of XML range\n",      "Char out of XML range\n",
     "Invalid or incomplete context\n",      "Invalid or incomplete context\n",
     "Stack usage errror\n",      "Stack usage errror\n",
       "Forbidden variable\n",
     "?? Unknown error ??\n"     /* Must be last in the list! */      "?? Unknown error ??\n"     /* Must be last in the list! */
 };  };
 #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \  #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \
Line 420  xmlPointerListAddSize(xmlPointerListPtr list, Line 496  xmlPointerListAddSize(xmlPointerListPtr list,
     if (list->items == NULL) {      if (list->items == NULL) {
         if (initialSize <= 0)          if (initialSize <= 0)
             initialSize = 1;              initialSize = 1;
        list->items = (void **) xmlMalloc(        list->items = (void **) xmlMalloc(initialSize * sizeof(void *));
            initialSize * sizeof(void *)); 
         if (list->items == NULL) {          if (list->items == NULL) {
             xmlXPathErrMemory(NULL,              xmlXPathErrMemory(NULL,
                 "xmlPointerListCreate: allocating item\n");                  "xmlPointerListCreate: allocating item\n");
Line 430  xmlPointerListAddSize(xmlPointerListPtr list, Line 505  xmlPointerListAddSize(xmlPointerListPtr list,
         list->number = 0;          list->number = 0;
         list->size = initialSize;          list->size = initialSize;
     } else if (list->size <= list->number) {      } else if (list->size <= list->number) {
           if (list->size > 50000000) {
               xmlXPathErrMemory(NULL,
                   "xmlPointerListAddSize: re-allocating item\n");
               return(-1);
           }
         list->size *= 2;          list->size *= 2;
         list->items = (void **) xmlRealloc(list->items,          list->items = (void **) xmlRealloc(list->items,
             list->size * sizeof(void *));              list->size * sizeof(void *));
         if (list->items == NULL) {          if (list->items == NULL) {
             xmlXPathErrMemory(NULL,              xmlXPathErrMemory(NULL,
                "xmlPointerListCreate: re-allocating item\n");                "xmlPointerListAddSize: re-allocating item\n");
             list->size = 0;              list->size = 0;
             return(-1);              return(-1);
         }          }
Line 553  typedef enum { Line 633  typedef enum {
     NODE_TYPE_PI = XML_PI_NODE      NODE_TYPE_PI = XML_PI_NODE
 } xmlXPathTypeVal;  } xmlXPathTypeVal;
   
 #define XP_REWRITE_DOS_CHILD_ELEM 1  
   
 typedef struct _xmlXPathStepOp xmlXPathStepOp;  typedef struct _xmlXPathStepOp xmlXPathStepOp;
 typedef xmlXPathStepOp *xmlXPathStepOpPtr;  typedef xmlXPathStepOp *xmlXPathStepOpPtr;
 struct _xmlXPathStepOp {  struct _xmlXPathStepOp {
Line 568  struct _xmlXPathStepOp { Line 646  struct _xmlXPathStepOp {
     void *value5;      void *value5;
     void *cache;      void *cache;
     void *cacheURI;      void *cacheURI;
     int rewriteType;  
 };  };
   
 struct _xmlXPathCompExpr {  struct _xmlXPathCompExpr {
Line 723  xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, Line 800  xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1,
     if (comp->nbStep >= comp->maxStep) {      if (comp->nbStep >= comp->maxStep) {
         xmlXPathStepOp *real;          xmlXPathStepOp *real;
   
           if (comp->maxStep >= XPATH_MAX_STEPS) {
               xmlXPathErrMemory(NULL, "adding step\n");
               return(-1);
           }
         comp->maxStep *= 2;          comp->maxStep *= 2;
         real = (xmlXPathStepOp *) xmlRealloc(comp->steps,          real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
                                       comp->maxStep * sizeof(xmlXPathStepOp));                                        comp->maxStep * sizeof(xmlXPathStepOp));
Line 734  xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, Line 815  xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1,
         comp->steps = real;          comp->steps = real;
     }      }
     comp->last = comp->nbStep;      comp->last = comp->nbStep;
     comp->steps[comp->nbStep].rewriteType = 0;  
     comp->steps[comp->nbStep].ch1 = ch1;      comp->steps[comp->nbStep].ch1 = ch1;
     comp->steps[comp->nbStep].ch2 = ch2;      comp->steps[comp->nbStep].ch2 = ch2;
     comp->steps[comp->nbStep].op = op;      comp->steps[comp->nbStep].op = op;
Line 2052  xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNo Line 2132  xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNo
             ret->type = XPATH_NODESET;              ret->type = XPATH_NODESET;
             ret->boolval = 0;              ret->boolval = 0;
             ret->nodesetval = xmlXPathNodeSetCreate(val);              ret->nodesetval = xmlXPathNodeSetCreate(val);
               if (ret->nodesetval == NULL) {
                   ctxt->lastError.domain = XML_FROM_XPATH;
                   ctxt->lastError.code = XML_ERR_NO_MEMORY;
                   return(NULL);
               }
 #ifdef XP_DEBUG_OBJ_USAGE  #ifdef XP_DEBUG_OBJ_USAGE
             xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);              xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
 #endif  #endif
Line 2480  valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjec Line 2565  valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjec
     if (ctxt->valueNr >= ctxt->valueMax) {      if (ctxt->valueNr >= ctxt->valueMax) {
         xmlXPathObjectPtr *tmp;          xmlXPathObjectPtr *tmp;
   
           if (ctxt->valueMax >= XPATH_MAX_STACK_DEPTH) {
               xmlXPathErrMemory(NULL, "XPath stack depth limit reached\n");
               ctxt->error = XPATH_MEMORY_ERROR;
               return (0);
           }
         tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,          tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
                                              2 * ctxt->valueMax *                                               2 * ctxt->valueMax *
                                              sizeof(ctxt->valueTab[0]));                                               sizeof(ctxt->valueTab[0]));
         if (tmp == NULL) {          if (tmp == NULL) {
            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");            xmlXPathErrMemory(NULL, "pushing value\n");
             ctxt->error = XPATH_MEMORY_ERROR;              ctxt->error = XPATH_MEMORY_ERROR;
             return (0);              return (0);
         }          }
Line 3320  turtle_comparison: Line 3410  turtle_comparison:
  */   */
 void  void
 xmlXPathNodeSetSort(xmlNodeSetPtr set) {  xmlXPathNodeSetSort(xmlNodeSetPtr set) {
   #ifndef WITH_TIM_SORT
     int i, j, incr, len;      int i, j, incr, len;
     xmlNodePtr tmp;      xmlNodePtr tmp;
   #endif
   
     if (set == NULL)      if (set == NULL)
         return;          return;
   
    /* Use Shell's sort to sort the node-set */#ifndef WITH_TIM_SORT
     /*
      * Use the old Shell's sort implementation to sort the node-set
      * Timsort ought to be quite faster
      */
     len = set->nodeNr;      len = set->nodeNr;
     for (incr = len / 2; incr > 0; incr /= 2) {      for (incr = len / 2; incr > 0; incr /= 2) {
         for (i = incr; i < len; i++) {          for (i = incr; i < len; i++) {
Line 3349  xmlXPathNodeSetSort(xmlNodeSetPtr set) { Line 3445  xmlXPathNodeSetSort(xmlNodeSetPtr set) {
             }              }
         }          }
     }      }
   #else /* WITH_TIM_SORT */
       libxml_domnode_tim_sort(set->nodeTab, set->nodeNr);
   #endif /* WITH_TIM_SORT */
 }  }
   
 #define XML_NODESET_DEFAULT     10  #define XML_NODESET_DEFAULT     10
Line 3527  xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr Line 3626  xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr
  * @ns:  a the namespace node   * @ns:  a the namespace node
  *   *
  * add a new namespace node to an existing NodeSet   * add a new namespace node to an existing NodeSet
    *
    * Returns 0 in case of success and -1 in case of error
  */   */
voidint
 xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
     int i;      int i;
   
Line 3536  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod Line 3637  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod
     if ((cur == NULL) || (ns == NULL) || (node == NULL) ||      if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
         (ns->type != XML_NAMESPACE_DECL) ||          (ns->type != XML_NAMESPACE_DECL) ||
         (node->type != XML_ELEMENT_NODE))          (node->type != XML_ELEMENT_NODE))
        return;        return(-1);
   
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */      /* @@ with_ns to check whether namespace nodes should be looked at @@ */
     /*      /*
Line 3547  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod Line 3648  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod
             (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&              (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
             (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&              (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
             (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))              (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
            return;            return(0);
     }      }
   
     /*      /*
Line 3558  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod Line 3659  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod
                                              sizeof(xmlNodePtr));                                               sizeof(xmlNodePtr));
         if (cur->nodeTab == NULL) {          if (cur->nodeTab == NULL) {
             xmlXPathErrMemory(NULL, "growing nodeset\n");              xmlXPathErrMemory(NULL, "growing nodeset\n");
            return;            return(-1);
         }          }
         memset(cur->nodeTab, 0 ,          memset(cur->nodeTab, 0 ,
                XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));                 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
Line 3566  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod Line 3667  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod
     } else if (cur->nodeNr == cur->nodeMax) {      } else if (cur->nodeNr == cur->nodeMax) {
         xmlNodePtr *temp;          xmlNodePtr *temp;
   
           if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
               xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
               return(-1);
           }
         temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *          temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
                                       sizeof(xmlNodePtr));                                        sizeof(xmlNodePtr));
         if (temp == NULL) {          if (temp == NULL) {
             xmlXPathErrMemory(NULL, "growing nodeset\n");              xmlXPathErrMemory(NULL, "growing nodeset\n");
            return;            return(-1);
         }          }
         cur->nodeMax *= 2;          cur->nodeMax *= 2;
         cur->nodeTab = temp;          cur->nodeTab = temp;
     }      }
     cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);      cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
       return(0);
 }  }
   
 /**  /**
Line 3584  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod Line 3690  xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr nod
  * @val:  a new xmlNodePtr   * @val:  a new xmlNodePtr
  *   *
  * add a new xmlNodePtr to an existing NodeSet   * add a new xmlNodePtr to an existing NodeSet
    *
    * Returns 0 in case of success, and -1 in case of error
  */   */
voidint
 xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
     int i;      int i;
   
    if ((cur == NULL) || (val == NULL)) return;    if ((cur == NULL) || (val == NULL)) return(-1);
   
 #if 0  
     if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))  
         return; /* an XSLT fake node */  
 #endif  
   
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */      /* @@ with_ns to check whether namespace nodes should be looked at @@ */
     /*      /*
      * prevent duplcates       * 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(0);
   
     /*      /*
      * grow the nodeTab if needed       * grow the nodeTab if needed
Line 3611  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val)  Line 3714  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) 
                                              sizeof(xmlNodePtr));                                               sizeof(xmlNodePtr));
         if (cur->nodeTab == NULL) {          if (cur->nodeTab == NULL) {
             xmlXPathErrMemory(NULL, "growing nodeset\n");              xmlXPathErrMemory(NULL, "growing nodeset\n");
            return;            return(-1);
         }          }
         memset(cur->nodeTab, 0 ,          memset(cur->nodeTab, 0 ,
                XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));                 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
Line 3619  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val)  Line 3722  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) 
     } else if (cur->nodeNr == cur->nodeMax) {      } else if (cur->nodeNr == cur->nodeMax) {
         xmlNodePtr *temp;          xmlNodePtr *temp;
   
           if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
               xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
               return(-1);
           }
         temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *          temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
                                       sizeof(xmlNodePtr));                                        sizeof(xmlNodePtr));
         if (temp == NULL) {          if (temp == NULL) {
             xmlXPathErrMemory(NULL, "growing nodeset\n");              xmlXPathErrMemory(NULL, "growing nodeset\n");
            return;            return(-1);
         }          }
         cur->nodeMax *= 2;          cur->nodeMax *= 2;
         cur->nodeTab = temp;          cur->nodeTab = temp;
Line 3635  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val)  Line 3742  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) 
             xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);              xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
     } else      } else
         cur->nodeTab[cur->nodeNr++] = val;          cur->nodeTab[cur->nodeNr++] = val;
       return(0);
 }  }
   
 /**  /**
Line 3644  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val)  Line 3752  xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) 
  *   *
  * add a new xmlNodePtr to an existing NodeSet, optimized version   * add a new xmlNodePtr to an existing NodeSet, optimized version
  * when we are sure the node is not already in the set.   * when we are sure the node is not already in the set.
    *
    * Returns 0 in case of success and -1 in case of failure
  */   */
voidint
 xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
    if ((cur == NULL) || (val == NULL)) return;    if ((cur == NULL) || (val == NULL)) return(-1);
   
 #if 0  
     if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))  
         return; /* an XSLT fake node */  
 #endif  
   
     /* @@ with_ns to check whether 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
Line 3663  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr Line 3768  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr
                                              sizeof(xmlNodePtr));                                               sizeof(xmlNodePtr));
         if (cur->nodeTab == NULL) {          if (cur->nodeTab == NULL) {
             xmlXPathErrMemory(NULL, "growing nodeset\n");              xmlXPathErrMemory(NULL, "growing nodeset\n");
            return;            return(-1);
         }          }
         memset(cur->nodeTab, 0 ,          memset(cur->nodeTab, 0 ,
                XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));                 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
Line 3671  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr Line 3776  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr
     } else if (cur->nodeNr == cur->nodeMax) {      } else if (cur->nodeNr == cur->nodeMax) {
         xmlNodePtr *temp;          xmlNodePtr *temp;
   
           if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
               xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
               return(-1);
           }
         temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *          temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
                                       sizeof(xmlNodePtr));                                        sizeof(xmlNodePtr));
         if (temp == NULL) {          if (temp == NULL) {
             xmlXPathErrMemory(NULL, "growing nodeset\n");              xmlXPathErrMemory(NULL, "growing nodeset\n");
            return;            return(-1);
         }          }
         cur->nodeTab = temp;          cur->nodeTab = temp;
         cur->nodeMax *= 2;          cur->nodeMax *= 2;
Line 3687  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr Line 3796  xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr
             xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);              xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
     } else      } else
         cur->nodeTab[cur->nodeNr++] = val;          cur->nodeTab[cur->nodeNr++] = val;
       return(0);
 }  }
   
 /**  /**
Line 3782  xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr Line 3892  xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr
         } else if (val1->nodeNr == val1->nodeMax) {          } else if (val1->nodeNr == val1->nodeMax) {
             xmlNodePtr *temp;              xmlNodePtr *temp;
   
               if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
                   xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
                   return(NULL);
               }
             temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *              temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
                                              sizeof(xmlNodePtr));                                               sizeof(xmlNodePtr));
             if (temp == NULL) {              if (temp == NULL) {
Line 3803  xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr Line 3917  xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr
     return(val1);      return(val1);
 }  }
   
 #if 0 /* xmlXPathNodeSetMergeUnique() is currently not used anymore */  
 /**  
  * xmlXPathNodeSetMergeUnique:  
  * @val1:  the first NodeSet or NULL  
  * @val2:  the second NodeSet  
  *  
  * Merges two nodesets, all nodes from @val2 are added to @val1  
  * if @val1 is NULL, a new set is created and copied from @val2  
  *  
  * Returns @val1 once extended or NULL in case of error.  
  */  
 static xmlNodeSetPtr  
 xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {  
     int i;  
   
     if (val2 == NULL) return(val1);  
     if (val1 == NULL) {  
         val1 = xmlXPathNodeSetCreate(NULL);  
     }  
     if (val1 == NULL)  
         return (NULL);  
   
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */  
   
     for (i = 0;i < val2->nodeNr;i++) {  
         /*  
          * grow the nodeTab if needed  
          */  
         if (val1->nodeMax == 0) {  
             val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *  
                                                     sizeof(xmlNodePtr));  
             if (val1->nodeTab == NULL) {  
                 xmlXPathErrMemory(NULL, "merging nodeset\n");  
                 return(NULL);  
             }  
             memset(val1->nodeTab, 0 ,  
                    XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));  
             val1->nodeMax = XML_NODESET_DEFAULT;  
         } else if (val1->nodeNr == val1->nodeMax) {  
             xmlNodePtr *temp;  
   
             val1->nodeMax *= 2;  
             temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *  
                                              sizeof(xmlNodePtr));  
             if (temp == NULL) {  
                 xmlXPathErrMemory(NULL, "merging nodeset\n");  
                 return(NULL);  
             }  
             val1->nodeTab = temp;  
         }  
         if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) {  
             xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i];  
   
             val1->nodeTab[val1->nodeNr++] =  
                 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);  
         } else  
             val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];  
     }  
   
     return(val1);  
 }  
 #endif /* xmlXPathNodeSetMergeUnique() is currently not used anymore */  
   
 /**  /**
  * xmlXPathNodeSetMergeAndClear:   * xmlXPathNodeSetMergeAndClear:
  * @set1:  the first NodeSet or NULL   * @set1:  the first NodeSet or NULL
Line 3951  xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNo Line 4003  xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNo
             } else if (set1->nodeNr >= set1->nodeMax) {              } else if (set1->nodeNr >= set1->nodeMax) {
                 xmlNodePtr *temp;                  xmlNodePtr *temp;
   
                   if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
                       xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
                       return(NULL);
                   }
                 temp = (xmlNodePtr *) xmlRealloc(                  temp = (xmlNodePtr *) xmlRealloc(
                     set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));                      set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
                 if (temp == NULL) {                  if (temp == NULL) {
Line 4035  xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1 Line 4091  xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1
             } else if (set1->nodeNr >= set1->nodeMax) {              } else if (set1->nodeNr >= set1->nodeMax) {
                 xmlNodePtr *temp;                  xmlNodePtr *temp;
   
                   if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
                       xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
                       return(NULL);
                   }
                 temp = (xmlNodePtr *) xmlRealloc(                  temp = (xmlNodePtr *) xmlRealloc(
                     set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));                      set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
                 if (temp == NULL) {                  if (temp == NULL) {
Line 4333  xmlXPathNewNodeSetList(xmlNodeSetPtr val) Line 4393  xmlXPathNewNodeSetList(xmlNodeSetPtr val)
         ret = xmlXPathNewNodeSet(NULL);          ret = xmlXPathNewNodeSet(NULL);
     else {      else {
         ret = xmlXPathNewNodeSet(val->nodeTab[0]);          ret = xmlXPathNewNodeSet(val->nodeTab[0]);
        if (ret)        if (ret) {
            for (i = 1; i < val->nodeNr; ++i)            for (i = 1; i < val->nodeNr; ++i) {
                xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);                if (xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i])
                     < 0) break;
             }
         }
     }      }
   
     return (ret);      return (ret);
Line 4411  xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPt Line 4474  xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPt
   
     for (i = 0; i < l1; i++) {      for (i = 0; i < l1; i++) {
         cur = xmlXPathNodeSetItem(nodes1, i);          cur = xmlXPathNodeSetItem(nodes1, i);
        if (!xmlXPathNodeSetContains(nodes2, cur))        if (!xmlXPathNodeSetContains(nodes2, cur)) {
            xmlXPathNodeSetAddUnique(ret, cur);            if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
                 break;
         }
     }      }
     return(ret);      return(ret);
 }  }
Line 4445  xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSet Line 4510  xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSet
   
     for (i = 0; i < l1; i++) {      for (i = 0; i < l1; i++) {
         cur = xmlXPathNodeSetItem(nodes1, i);          cur = xmlXPathNodeSetItem(nodes1, i);
        if (xmlXPathNodeSetContains(nodes2, cur))        if (xmlXPathNodeSetContains(nodes2, cur)) {
            xmlXPathNodeSetAddUnique(ret, cur);            if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
                 break;
         }
     }      }
     return(ret);      return(ret);
 }  }
Line 4482  xmlXPathDistinctSorted (xmlNodeSetPtr nodes) { Line 4549  xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
         strval = xmlXPathCastNodeToString(cur);          strval = xmlXPathCastNodeToString(cur);
         if (xmlHashLookup(hash, strval) == NULL) {          if (xmlHashLookup(hash, strval) == NULL) {
             xmlHashAddEntry(hash, strval, strval);              xmlHashAddEntry(hash, strval, strval);
            xmlXPathNodeSetAddUnique(ret, cur);            if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
                 break;
         } else {          } else {
             xmlFree(strval);              xmlFree(strval);
         }          }
Line 4574  xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNod Line 4642  xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNod
         cur = xmlXPathNodeSetItem(nodes, i);          cur = xmlXPathNodeSetItem(nodes, i);
         if (cur == node)          if (cur == node)
             break;              break;
        xmlXPathNodeSetAddUnique(ret, cur);        if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
             break;
     }      }
     return(ret);      return(ret);
 }  }
Line 4678  xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNo Line 4747  xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNo
         cur = xmlXPathNodeSetItem(nodes, i);          cur = xmlXPathNodeSetItem(nodes, i);
         if (cur == node)          if (cur == node)
             break;              break;
        xmlXPathNodeSetAddUnique(ret, cur);        if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
             break;
     }      }
     xmlXPathNodeSetSort(ret);   /* bug 413451 */      xmlXPathNodeSetSort(ret);   /* bug 413451 */
     return(ret);      return(ret);
Line 7701  xmlXPathNextChildElement(xmlXPathParserContextPtr ctxt Line 7771  xmlXPathNextChildElement(xmlXPathParserContextPtr ctxt
     return(NULL);      return(NULL);
 }  }
   
   #if 0
 /**  /**
  * xmlXPathNextDescendantOrSelfElemParent:   * xmlXPathNextDescendantOrSelfElemParent:
  * @ctxt:  the XPath Parser context   * @ctxt:  the XPath Parser context
Line 7728  xmlXPathNextDescendantOrSelfElemParent(xmlNodePtr cur, Line 7799  xmlXPathNextDescendantOrSelfElemParent(xmlNodePtr cur,
 #ifdef LIBXML_DOCB_ENABLED  #ifdef LIBXML_DOCB_ENABLED
             case XML_DOCB_DOCUMENT_NODE:              case XML_DOCB_DOCUMENT_NODE:
 #endif  #endif
            case XML_HTML_DOCUMENT_NODE:                        case XML_HTML_DOCUMENT_NODE:
                 return(contextNode);                  return(contextNode);
             default:              default:
                 return(NULL);                  return(NULL);
Line 7776  next_sibling: Line 7847  next_sibling:
     }      }
     return(NULL);      return(NULL);
 }  }
   #endif
   
 /**  /**
  * xmlXPathNextDescendant:   * xmlXPathNextDescendant:
Line 7803  xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt,  Line 7875  xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, 
         return(ctxt->context->node->children);          return(ctxt->context->node->children);
     }      }
   
       if (cur->type == XML_NAMESPACE_DECL)
           return(NULL);
     if (cur->children != NULL) {      if (cur->children != NULL) {
         /*          /*
          * Do not descend on entities declarations           * Do not descend on entities declarations
Line 8185  xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, x Line 8259  xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, x
 static int  static int
 xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {  xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
     if ((ancestor == NULL) || (node == NULL)) return(0);      if ((ancestor == NULL) || (node == NULL)) return(0);
       if (node->type == XML_NAMESPACE_DECL)
           return(0);
       if (ancestor->type == XML_NAMESPACE_DECL)
           return(0);
     /* nodes need to be in the same document */      /* nodes need to be in the same document */
     if (ancestor->doc != node->doc) return(0);      if (ancestor->doc != node->doc) return(0);
     /* avoid searching if ancestor or node is the root node */      /* avoid searching if ancestor or node is the root node */
Line 8222  xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, x Line 8300  xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, x
         if (cur->type == XML_ATTRIBUTE_NODE)          if (cur->type == XML_ATTRIBUTE_NODE)
             return(cur->parent);              return(cur->parent);
     }      }
    if (cur == NULL)    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
         return (NULL);          return (NULL);
     if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))      if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
         cur = cur->prev;          cur = cur->prev;
Line 8269  xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr Line 8347  xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr
             return (NULL);              return (NULL);
         ctxt->ancestor = cur->parent;          ctxt->ancestor = cur->parent;
     }      }
       if (cur->type == XML_NAMESPACE_DECL)
           return(NULL);
     if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))      if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
         cur = cur->prev;          cur = cur->prev;
     while (cur->prev == NULL) {      while (cur->prev == NULL) {
Line 8476  xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, i Line 8556  xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, i
             int i = 0;              int i = 0;
   
             tmp = cur->nodesetval->nodeTab[0];              tmp = cur->nodesetval->nodeTab[0];
            if (tmp != NULL) {            if ((tmp != NULL) && (tmp->type != XML_NAMESPACE_DECL)) {
                 tmp = tmp->children;                  tmp = tmp->children;
                 while (tmp != NULL) {                  while (tmp != NULL) {
                     tmp = tmp->next;                      tmp = tmp->next;
Line 9146  void Line 9226  void
 xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
   xmlXPathObjectPtr str;    xmlXPathObjectPtr str;
   xmlXPathObjectPtr find;    xmlXPathObjectPtr find;
  xmlBufferPtr target;  xmlBufPtr target;
   const xmlChar *point;    const xmlChar *point;
   int offset;    int offset;
   
Line 9156  xmlXPathSubstringBeforeFunction(xmlXPathParserContextP Line 9236  xmlXPathSubstringBeforeFunction(xmlXPathParserContextP
   CAST_TO_STRING;    CAST_TO_STRING;
   str = valuePop(ctxt);    str = valuePop(ctxt);
   
  target = xmlBufferCreate();  target = xmlBufCreate();
   if (target) {    if (target) {
     point = xmlStrstr(str->stringval, find->stringval);      point = xmlStrstr(str->stringval, find->stringval);
     if (point) {      if (point) {
       offset = (int)(point - str->stringval);        offset = (int)(point - str->stringval);
      xmlBufferAdd(target, str->stringval, offset);      xmlBufAdd(target, str->stringval, offset);
     }      }
     valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,      valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
        xmlBufferContent(target)));        xmlBufContent(target)));
    xmlBufferFree(target);    xmlBufFree(target);
   }    }
   xmlXPathReleaseObject(ctxt->context, str);    xmlXPathReleaseObject(ctxt->context, str);
   xmlXPathReleaseObject(ctxt->context, find);    xmlXPathReleaseObject(ctxt->context, find);
Line 9189  void Line 9269  void
 xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
   xmlXPathObjectPtr str;    xmlXPathObjectPtr str;
   xmlXPathObjectPtr find;    xmlXPathObjectPtr find;
  xmlBufferPtr target;  xmlBufPtr target;
   const xmlChar *point;    const xmlChar *point;
   int offset;    int offset;
   
Line 9199  xmlXPathSubstringAfterFunction(xmlXPathParserContextPt Line 9279  xmlXPathSubstringAfterFunction(xmlXPathParserContextPt
   CAST_TO_STRING;    CAST_TO_STRING;
   str = valuePop(ctxt);    str = valuePop(ctxt);
   
  target = xmlBufferCreate();  target = xmlBufCreate();
   if (target) {    if (target) {
     point = xmlStrstr(str->stringval, find->stringval);      point = xmlStrstr(str->stringval, find->stringval);
     if (point) {      if (point) {
       offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);        offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
      xmlBufferAdd(target, &str->stringval[offset],      xmlBufAdd(target, &str->stringval[offset],
                    xmlStrlen(str->stringval) - offset);                     xmlStrlen(str->stringval) - offset);
     }      }
     valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,      valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
        xmlBufferContent(target)));        xmlBufContent(target)));
    xmlBufferFree(target);    xmlBufFree(target);
   }    }
   xmlXPathReleaseObject(ctxt->context, str);    xmlXPathReleaseObject(ctxt->context, str);
   xmlXPathReleaseObject(ctxt->context, find);    xmlXPathReleaseObject(ctxt->context, find);
Line 9233  void Line 9313  void
 xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
   xmlXPathObjectPtr obj = NULL;    xmlXPathObjectPtr obj = NULL;
   xmlChar *source = NULL;    xmlChar *source = NULL;
  xmlBufferPtr target;  xmlBufPtr target;
   xmlChar blank;    xmlChar blank;
   
   if (ctxt == NULL) return;    if (ctxt == NULL) return;
Line 9251  xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctx Line 9331  xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctx
   obj = valuePop(ctxt);    obj = valuePop(ctxt);
   source = obj->stringval;    source = obj->stringval;
   
  target = xmlBufferCreate();  target = xmlBufCreate();
   if (target && source) {    if (target && source) {
   
     /* Skip leading whitespaces */      /* Skip leading whitespaces */
Line 9265  xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctx Line 9345  xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctx
         blank = 0x20;          blank = 0x20;
       } else {        } else {
         if (blank) {          if (blank) {
          xmlBufferAdd(target, &blank, 1);          xmlBufAdd(target, &blank, 1);
           blank = 0;            blank = 0;
         }          }
        xmlBufferAdd(target, source, 1);        xmlBufAdd(target, source, 1);
       }        }
       source++;        source++;
     }      }
     valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,      valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
        xmlBufferContent(target)));        xmlBufContent(target)));
    xmlBufferFree(target);    xmlBufFree(target);
   }    }
   xmlXPathReleaseObject(ctxt->context, obj);    xmlXPathReleaseObject(ctxt->context, obj);
 }  }
Line 9305  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx Line 9385  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx
     xmlXPathObjectPtr str;      xmlXPathObjectPtr str;
     xmlXPathObjectPtr from;      xmlXPathObjectPtr from;
     xmlXPathObjectPtr to;      xmlXPathObjectPtr to;
    xmlBufferPtr target;    xmlBufPtr target;
     int offset, max;      int offset, max;
     xmlChar ch;      xmlChar ch;
     const xmlChar *point;      const xmlChar *point;
Line 9320  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx Line 9400  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx
     CAST_TO_STRING;      CAST_TO_STRING;
     str = valuePop(ctxt);      str = valuePop(ctxt);
   
    target = xmlBufferCreate();    target = xmlBufCreate();
     if (target) {      if (target) {
         max = xmlUTF8Strlen(to->stringval);          max = xmlUTF8Strlen(to->stringval);
         for (cptr = str->stringval; (ch=*cptr); ) {          for (cptr = str->stringval; (ch=*cptr); ) {
Line 9329  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx Line 9409  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx
                 if (offset < max) {                  if (offset < max) {
                     point = xmlUTF8Strpos(to->stringval, offset);                      point = xmlUTF8Strpos(to->stringval, offset);
                     if (point)                      if (point)
                        xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1));                        xmlBufAdd(target, point, xmlUTF8Strsize(point, 1));
                 }                  }
             } else              } else
                xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1));                xmlBufAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
   
             /* Step to next character in input */              /* Step to next character in input */
             cptr++;              cptr++;
Line 9358  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx Line 9438  xmlXPathTranslateFunction(xmlXPathParserContextPtr ctx
         }          }
     }      }
     valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,      valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
        xmlBufferContent(target)));        xmlBufContent(target)));
    xmlBufferFree(target);    xmlBufFree(target);
     xmlXPathReleaseObject(ctxt->context, str);      xmlXPathReleaseObject(ctxt->context, str);
     xmlXPathReleaseObject(ctxt->context, from);      xmlXPathReleaseObject(ctxt->context, from);
     xmlXPathReleaseObject(ctxt->context, to);      xmlXPathReleaseObject(ctxt->context, to);
Line 9866  xmlChar * Line 9946  xmlChar *
 xmlXPathParseName(xmlXPathParserContextPtr ctxt) {  xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
     const xmlChar *in;      const xmlChar *in;
     xmlChar *ret;      xmlChar *ret;
    int count = 0;    size_t count = 0;
   
     if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);      if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
     /*      /*
Line 9885  xmlXPathParseName(xmlXPathParserContextPtr ctxt) { Line 9965  xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
             in++;              in++;
         if ((*in > 0) && (*in < 0x80)) {          if ((*in > 0) && (*in < 0x80)) {
             count = in - ctxt->cur;              count = in - ctxt->cur;
               if (count > XML_MAX_NAME_LENGTH) {
                   ctxt->cur = in;
                   XP_ERRORNULL(XPATH_EXPR_ERROR);
               }
             ret = xmlStrndup(ctxt->cur, count);              ret = xmlStrndup(ctxt->cur, count);
             ctxt->cur = in;              ctxt->cur = in;
             return(ret);              return(ret);
Line 9928  xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt Line 10012  xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt
             xmlChar *buffer;              xmlChar *buffer;
             int max = len * 2;              int max = len * 2;
   
               if (len > XML_MAX_NAME_LENGTH) {
                   XP_ERRORNULL(XPATH_EXPR_ERROR);
               }
             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));              buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
             if (buffer == NULL) {              if (buffer == NULL) {
                 XP_ERRORNULL(XPATH_MEMORY_ERROR);                  XP_ERRORNULL(XPATH_MEMORY_ERROR);
Line 9939  xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt Line 10026  xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt
                    (IS_COMBINING(c)) ||                     (IS_COMBINING(c)) ||
                    (IS_EXTENDER(c))) {                     (IS_EXTENDER(c))) {
                 if (len + 10 > max) {                  if (len + 10 > max) {
                       if (max > XML_MAX_NAME_LENGTH) {
                           XP_ERRORNULL(XPATH_EXPR_ERROR);
                       }
                     max *= 2;                      max *= 2;
                     buffer = (xmlChar *) xmlRealloc(buffer,                      buffer = (xmlChar *) xmlRealloc(buffer,
                                                     max * sizeof(xmlChar));                                                      max * sizeof(xmlChar));
Line 10291  xmlXPathCompVariableReference(xmlXPathParserContextPtr Line 10381  xmlXPathCompVariableReference(xmlXPathParserContextPtr
                    name, prefix);                     name, prefix);
     SKIP_BLANKS;      SKIP_BLANKS;
     if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {      if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {
        XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR);        XP_ERROR(XPATH_FORBID_VARIABLE_ERROR);
     }      }
 }  }
   
Line 11655  xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr c Line 11745  xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr c
             */              */
             if (contextObj == NULL)              if (contextObj == NULL)
                 contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);                  contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
            else            else {
                xmlXPathNodeSetAddUnique(contextObj->nodesetval,                if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
                    contextNode);                    contextNode) < 0) {
                     ctxt->error = XPATH_MEMORY_ERROR;
                     goto evaluation_exit;
                 }
             }
   
             valuePush(ctxt, contextObj);              valuePush(ctxt, contextObj);
   
Line 11803  xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserCo Line 11897  xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserCo
             */              */
             if (contextObj == NULL)              if (contextObj == NULL)
                 contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);                  contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
            else            else {
                xmlXPathNodeSetAddUnique(contextObj->nodesetval,                if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
                    contextNode);                    contextNode) < 0) {
                     ctxt->error = XPATH_MEMORY_ERROR;
                     goto evaluation_exit;
                 }
             }
   
             frame = xmlXPathSetFrame(ctxt);              frame = xmlXPathSetFrame(ctxt);
             valuePush(ctxt, contextObj);              valuePush(ctxt, contextObj);
Line 11977  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12075  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
 #define XP_TEST_HIT \  #define XP_TEST_HIT \
     if (hasAxisRange != 0) { \      if (hasAxisRange != 0) { \
         if (++pos == maxPos) { \          if (++pos == maxPos) { \
            addNode(seq, cur); \            if (addNode(seq, cur) < 0) \
        goto axis_range_end; } \                ctxt->error = XPATH_MEMORY_ERROR; \
             goto axis_range_end; } \
     } else { \      } else { \
        addNode(seq, cur); \        if (addNode(seq, cur) < 0) \
             ctxt->error = XPATH_MEMORY_ERROR; \
         if (breakOnFirstHit) goto first_hit; }          if (breakOnFirstHit) goto first_hit; }
   
 #define XP_TEST_HIT_NS \  #define XP_TEST_HIT_NS \
     if (hasAxisRange != 0) { \      if (hasAxisRange != 0) { \
         if (++pos == maxPos) { \          if (++pos == maxPos) { \
             hasNsNodes = 1; \              hasNsNodes = 1; \
            xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur); \            if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
                 ctxt->error = XPATH_MEMORY_ERROR; \
         goto axis_range_end; } \          goto axis_range_end; } \
     } else { \      } else { \
         hasNsNodes = 1; \          hasNsNodes = 1; \
        xmlXPathNodeSetAddNs(seq, \        if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
        xpctxt->node, (xmlNsPtr) cur); \            ctxt->error = XPATH_MEMORY_ERROR; \
         if (breakOnFirstHit) goto first_hit; }          if (breakOnFirstHit) goto first_hit; }
   
     xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;      xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;
Line 12012  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12113  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
     xmlNodeSetPtr contextSeq;      xmlNodeSetPtr contextSeq;
     int contextIdx;      int contextIdx;
     xmlNodePtr contextNode;      xmlNodePtr contextNode;
     /* The context node for a compound traversal */  
     xmlNodePtr outerContextNode;  
     /* The final resulting node set wrt to all context nodes */      /* The final resulting node set wrt to all context nodes */
     xmlNodeSetPtr outSeq;      xmlNodeSetPtr outSeq;
     /*      /*
Line 12029  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12128  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
     int breakOnFirstHit;      int breakOnFirstHit;
   
     xmlXPathTraversalFunction next = NULL;      xmlXPathTraversalFunction next = NULL;
    /* compound axis traversal */    int (*addNode) (xmlNodeSetPtr, xmlNodePtr);
    xmlXPathTraversalFunctionExt outerNext = NULL; 
    void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 
     xmlXPathNodeSetMergeFunction mergeAndClear;      xmlXPathNodeSetMergeFunction mergeAndClear;
     xmlNodePtr oldContextNode;      xmlNodePtr oldContextNode;
     xmlXPathContextPtr xpctxt = ctxt->context;      xmlXPathContextPtr xpctxt = ctxt->context;
Line 12080  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12177  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
             break;              break;
         case AXIS_CHILD:          case AXIS_CHILD:
             last = NULL;              last = NULL;
             if (op->rewriteType == XP_REWRITE_DOS_CHILD_ELEM) {  
                 /*  
                 * This iterator will give us only nodes which can  
                 * hold element nodes.  
                 */  
                 outerNext = xmlXPathNextDescendantOrSelfElemParent;  
             }  
             if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) &&              if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) &&
                 (type == NODE_TYPE_NODE))                  (type == NODE_TYPE_NODE))
             {              {
Line 12216  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12306  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
     addNode = xmlXPathNodeSetAddUnique;      addNode = xmlXPathNodeSetAddUnique;
     outSeq = NULL;      outSeq = NULL;
     seq = NULL;      seq = NULL;
     outerContextNode = NULL;  
     contextNode = NULL;      contextNode = NULL;
     contextIdx = 0;      contextIdx = 0;
   
   
    while ((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) {    while (((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) &&
        if (outerNext != NULL) {           (ctxt->error == XPATH_EXPRESSION_OK)) {
            /*        xpctxt->node = contextSeq->nodeTab[contextIdx++];
            * This is a compound traversal. 
            */ 
            if (contextNode == NULL) { 
                /* 
                * Set the context for the outer traversal. 
                */ 
                outerContextNode = contextSeq->nodeTab[contextIdx++]; 
                contextNode = outerNext(NULL, outerContextNode); 
            } else 
                contextNode = outerNext(contextNode, outerContextNode); 
            if (contextNode == NULL) 
                continue; 
            /* 
            * Set the context for the main traversal. 
            */ 
            xpctxt->node = contextNode; 
        } else 
            xpctxt->node = contextSeq->nodeTab[contextIdx++]; 
   
         if (seq == NULL) {          if (seq == NULL) {
             seq = xmlXPathNodeSetCreate(NULL);              seq = xmlXPathNodeSetCreate(NULL);
Line 12328  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12399  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
                                 break;                                  break;
                         }                          }
                     } else if (cur->type == type) {                      } else if (cur->type == type) {
                        if (type == XML_NAMESPACE_DECL)                        if (cur->type == XML_NAMESPACE_DECL)
                             XP_TEST_HIT_NS                              XP_TEST_HIT_NS
                         else                          else
                             XP_TEST_HIT                              XP_TEST_HIT
Line 12439  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct Line 12510  xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ct
                     }                      }
                     break;                      break;
             } /* switch(test) */              } /* switch(test) */
        } while (cur != NULL);        } while ((cur != NULL) && (ctxt->error == XPATH_EXPRESSION_OK));
   
         goto apply_predicates;          goto apply_predicates;
   
Line 12480  first_hit: /* ---------------------------------------- Line 12551  first_hit: /* ----------------------------------------
 #endif  #endif
   
 apply_predicates: /* --------------------------------------------------- */  apply_predicates: /* --------------------------------------------------- */
           if (ctxt->error != XPATH_EXPRESSION_OK)
               goto error;
   
         /*          /*
         * Apply predicates.          * Apply predicates.
         */          */
         if ((predOp != NULL) && (seq->nodeNr > 0)) {          if ((predOp != NULL) && (seq->nodeNr > 0)) {
             /*              /*
             * E.g. when we have a "/foo[some expression][n]".              * E.g. when we have a "/foo[some expression][n]".
            */                  */
             /*              /*
             * QUESTION TODO: The old predicate evaluation took into              * QUESTION TODO: The old predicate evaluation took into
             *  account location-sets.              *  account location-sets.
Line 12495  apply_predicates: /* --------------------------------- Line 12569  apply_predicates: /* ---------------------------------
             *  All what I learned now from the evaluation semantics              *  All what I learned now from the evaluation semantics
             *  does not indicate that a location-set will be processed              *  does not indicate that a location-set will be processed
             *  here, so this looks OK.              *  here, so this looks OK.
            */                  */
             /*              /*
             * Iterate over all predicates, starting with the outermost              * Iterate over all predicates, starting with the outermost
             * predicate.              * predicate.
Line 12988  xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr Line 13062  xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr
                 tmp = xmlXPathCacheNewNodeSet(ctxt->context,                  tmp = xmlXPathCacheNewNodeSet(ctxt->context,
                     ctxt->context->node);                      ctxt->context->node);
             } else {              } else {
                xmlXPathNodeSetAddUnique(tmp->nodesetval,                if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
                    ctxt->context->node);                                             ctxt->context->node) < 0) {
                     ctxt->error = XPATH_MEMORY_ERROR;
                 }
             }              }
             valuePush(ctxt, tmp);              valuePush(ctxt, tmp);
             if (op->ch2 != -1)              if (op->ch2 != -1)
Line 13102  xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr Line 13178  xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr
                 tmp = xmlXPathCacheNewNodeSet(ctxt->context,                  tmp = xmlXPathCacheNewNodeSet(ctxt->context,
                     ctxt->context->node);                      ctxt->context->node);
             } else {              } else {
                xmlXPathNodeSetAddUnique(tmp->nodesetval,                if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
                    ctxt->context->node);                                             ctxt->context->node) < 0) {
                     ctxt->error = XPATH_MEMORY_ERROR;
                 }
             }              }
             valuePush(ctxt, tmp);              valuePush(ctxt, tmp);
             ctxt->context->contextSize = oldset->nodeNr;              ctxt->context->contextSize = oldset->nodeNr;
Line 13121  xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr Line 13199  xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr
             */              */
             res = valuePop(ctxt);              res = valuePop(ctxt);
             if (xmlXPathEvaluatePredicateResult(ctxt, res)) {              if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
                xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);                if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) < 0)
                     ctxt->error = XPATH_MEMORY_ERROR;
             }              }
             /*              /*
             * Cleanup              * Cleanup
Line 13800  xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlX Line 13879  xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlX
                             tmp = xmlXPathCacheNewNodeSet(ctxt->context,                              tmp = xmlXPathCacheNewNodeSet(ctxt->context,
                                 ctxt->context->node);                                  ctxt->context->node);
                         } else {                          } else {
                            xmlXPathNodeSetAddUnique(tmp->nodesetval,                            if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
                                ctxt->context->node);                                               ctxt->context->node) < 0) {
                                 ctxt->error = XPATH_MEMORY_ERROR;
                             }
                         }                          }
                         valuePush(ctxt, tmp);                          valuePush(ctxt, tmp);
                         ctxt->context->contextSize = oldset->nodeNr;                          ctxt->context->contextSize = oldset->nodeNr;
Line 13831  xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlX Line 13912  xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlX
                         */                          */
                         res = valuePop(ctxt);                          res = valuePop(ctxt);
                         if (xmlXPathEvaluatePredicateResult(ctxt, res)) {                          if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
                            xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);                            if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i])
                                 < 0)
                                 ctxt->error = XPATH_MEMORY_ERROR;
                         }                          }
   
                         /*                          /*
Line 14194  xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatt Line 14277  xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatt
             if (toBool)              if (toBool)
                 return(1);                  return(1);
             xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,              xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
                (xmlNodePtr) ctxt->doc);                                     (xmlNodePtr) ctxt->doc);
         } else {          } else {
             /* Select "self::node()" */              /* Select "self::node()" */
             if (toBool)              if (toBool)
Line 14287  next_node: Line 14370  next_node:
                 } else if (ret == 1) {                  } else if (ret == 1) {
                     if (toBool)                      if (toBool)
                         goto return_1;                          goto return_1;
                    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);                    if (xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur)
                         < 0) {
                         ctxt->lastError.domain = XML_FROM_XPATH;
                         ctxt->lastError.code = XML_ERR_NO_MEMORY;
                     }
                 }                  }
                 if ((cur->children == NULL) || (depth >= max_depth)) {                  if ((cur->children == NULL) || (depth >= max_depth)) {
                     ret = xmlStreamPop(patstream);                      ret = xmlStreamPop(patstream);
Line 14303  next_node: Line 14390  next_node:
         }          }
   
 scan_children:  scan_children:
           if (cur->type == XML_NAMESPACE_DECL) break;
         if ((cur->children != NULL) && (depth < max_depth)) {          if ((cur->children != NULL) && (depth < max_depth)) {
             /*              /*
              * Do not descend on entities declarations               * Do not descend on entities declarations
Line 14623  xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, cons Line 14711  xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, cons
 }  }
 #endif /* XPATH_STREAMING */  #endif /* XPATH_STREAMING */
   
 static int  
 xmlXPathCanRewriteDosExpression(xmlChar *expr)  
 {  
     if (expr == NULL)  
         return(0);  
     do {  
         if ((*expr == '/') && (*(++expr) == '/'))  
             return(1);  
     } while (*expr++);  
     return(0);  
 }  
 static void  static void
xmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
 {  {
     /*      /*
     * Try to rewrite "descendant-or-self::node()/foo" to an optimized      * Try to rewrite "descendant-or-self::node()/foo" to an optimized
     * internal representation.      * internal representation.
     */      */
     if (op->ch1 != -1) {  
         if ((op->op == XPATH_OP_COLLECT /* 11 */) &&  
             ((xmlXPathAxisVal) op->value == AXIS_CHILD /* 4 */) &&  
             ((xmlXPathTestVal) op->value2 == NODE_TEST_NAME /* 5 */) &&  
             ((xmlXPathTypeVal) op->value3 == NODE_TYPE_NODE /* 0 */))  
         {  
             /*  
             * This is a "child::foo"  
             */  
             xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];  
   
            if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&    if ((op->ch1 != -1) &&
                (prevop->ch1 != -1) &&        (op->op == XPATH_OP_COLLECT /* 11 */))
                ((xmlXPathAxisVal) prevop->value ==    {
                    AXIS_DESCENDANT_OR_SELF) &&        xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
                (prevop->ch2 == -1) &&
                ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&        if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&
                ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE) &&            ((xmlXPathAxisVal) prevop->value ==
                (comp->steps[prevop->ch1].op == XPATH_OP_ROOT))                AXIS_DESCENDANT_OR_SELF) &&
            {            (prevop->ch2 == -1) &&
                /*            ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
                * This is a "/descendant-or-self::node()" without predicates.            ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE))
                * Eliminate it.        {
                */            /*
                op->ch1 = prevop->ch1;            * This is a "descendant-or-self::node()" without predicates.
                op->rewriteType = XP_REWRITE_DOS_CHILD_ELEM;            * Try to eliminate it.
            }            */
 
             switch ((xmlXPathAxisVal) op->value) {
                 case AXIS_CHILD:
                 case AXIS_DESCENDANT:
                     /*
                     * Convert "descendant-or-self::node()/child::" or
                     * "descendant-or-self::node()/descendant::" to
                     * "descendant::"
                     */
                     op->ch1   = prevop->ch1;
                     op->value = AXIS_DESCENDANT;
                     break;
                 case AXIS_SELF:
                 case AXIS_DESCENDANT_OR_SELF:
                     /*
                     * Convert "descendant-or-self::node()/self::" or
                     * "descendant-or-self::node()/descendant-or-self::" to
                     * to "descendant-or-self::"
                     */
                     op->ch1   = prevop->ch1;
                     op->value = AXIS_DESCENDANT_OR_SELF;
                     break;
                 default:
                     break;
             }
         }          }
         if (op->ch1 != -1)  
             xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch1]);  
     }      }
   
       /* Recurse */
       if (op->ch1 != -1)
           xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
     if (op->ch2 != -1)      if (op->ch2 != -1)
        xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]);        xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]);
 }  }
   
 /**  /**
Line 14731  xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xml Line 14825  xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xml
         comp->string = xmlStrdup(str);          comp->string = xmlStrdup(str);
         comp->nb = 0;          comp->nb = 0;
 #endif  #endif
        if ((comp->expr != NULL) &&        if ((comp->nbStep > 1) && (comp->last >= 0)) {
            (comp->nbStep > 2) &&            xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]);
            (comp->last >= 0) && 
            (xmlXPathCanRewriteDosExpression(comp->expr) == 1)) 
        { 
            xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]); 
         }          }
     }      }
     return(comp);      return(comp);
Line 14913  xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { Line 15003  xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
 #endif  #endif
     {      {
         xmlXPathCompileExpr(ctxt, 1);          xmlXPathCompileExpr(ctxt, 1);
         /*  
         * In this scenario the expression string will sit in ctxt->base.  
         */  
         if ((ctxt->error == XPATH_EXPRESSION_OK) &&          if ((ctxt->error == XPATH_EXPRESSION_OK) &&
             (ctxt->comp != NULL) &&              (ctxt->comp != NULL) &&
            (ctxt->base != NULL) &&            (ctxt->comp->nbStep > 1) &&
            (ctxt->comp->nbStep > 2) &&            (ctxt->comp->last >= 0))
            (ctxt->comp->last >= 0) && 
            (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1)) 
         {          {
            xmlXPathRewriteDOSExpression(ctxt->comp,            xmlXPathOptimizeExpression(ctxt->comp,
                 &ctxt->comp->steps[ctxt->comp->last]);                  &ctxt->comp->steps[ctxt->comp->last]);
         }          }
     }      }
Line 14994  xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ct Line 15079  xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ct
 }  }
   
 /**  /**
    * xmlXPathSetContextNode:
    * @node: the node to to use as the context node
    * @ctx:  the XPath context
    *
    * Sets 'node' as the context node. The node must be in the same
    * document as that associated with the context.
    *
    * Returns -1 in case of error or 0 if successful
    */
   int
   xmlXPathSetContextNode(xmlNodePtr node, xmlXPathContextPtr ctx) {
       if ((node == NULL) || (ctx == NULL))
           return(-1);
   
       if (node->doc == ctx->doc) {
           ctx->node = node;
           return(0);
       }
       return(-1);
   }
   
   /**
    * xmlXPathNodeEval:
    * @node: the node to to use as the context node
    * @str:  the XPath expression
    * @ctx:  the XPath context
    *
    * Evaluate the XPath Location Path in the given context. The node 'node'
    * is set as the context node. The context node is not restored.
    *
    * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
    *         the caller has to free the object.
    */
   xmlXPathObjectPtr
   xmlXPathNodeEval(xmlNodePtr node, const xmlChar *str, xmlXPathContextPtr ctx) {
       if (str == NULL)
           return(NULL);
       if (xmlXPathSetContextNode(node, ctx) < 0)
           return(NULL);
       return(xmlXPathEval(str, ctx));
   }
   
   /**
  * xmlXPathEvalExpression:   * xmlXPathEvalExpression:
  * @str:  the XPath expression   * @str:  the XPath expression
  * @ctxt:  the XPath context   * @ctxt:  the XPath context
Line 15097  static void Line 15225  static void
 xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr str;      xmlXPathObjectPtr str;
     int escape_reserved;      int escape_reserved;
    xmlBufferPtr target;    xmlBufPtr target;
     xmlChar *cptr;      xmlChar *cptr;
     xmlChar escape[4];      xmlChar escape[4];
   
Line 15108  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctx Line 15236  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctx
     CAST_TO_STRING;      CAST_TO_STRING;
     str = valuePop(ctxt);      str = valuePop(ctxt);
   
    target = xmlBufferCreate();    target = xmlBufCreate();
   
     escape[0] = '%';      escape[0] = '%';
     escape[3] = 0;      escape[3] = 0;
Line 15133  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctx Line 15261  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctx
                   *cptr == ':' || *cptr == '@' || *cptr == '&' ||                    *cptr == ':' || *cptr == '@' || *cptr == '&' ||
                   *cptr == '=' || *cptr == '+' || *cptr == '$' ||                    *cptr == '=' || *cptr == '+' || *cptr == '$' ||
                   *cptr == ','))) {                    *cptr == ','))) {
                xmlBufferAdd(target, cptr, 1);                xmlBufAdd(target, cptr, 1);
             } else {              } else {
                 if ((*cptr >> 4) < 10)                  if ((*cptr >> 4) < 10)
                     escape[1] = '0' + (*cptr >> 4);                      escape[1] = '0' + (*cptr >> 4);
Line 15144  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctx Line 15272  xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctx
                 else                  else
                     escape[2] = 'A' - 10 + (*cptr & 0xF);                      escape[2] = 'A' - 10 + (*cptr & 0xF);
   
                xmlBufferAdd(target, &escape[0], 3);                xmlBufAdd(target, &escape[0], 3);
             }              }
         }          }
     }      }
     valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,      valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
        xmlBufferContent(target)));        xmlBufContent(target)));
    xmlBufferFree(target);    xmlBufFree(target);
     xmlXPathReleaseObject(ctxt->context, str);      xmlXPathReleaseObject(ctxt->context, str);
 }  }
   

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>