#include <libxml/pattern.h>
#endif
+#include "buf.h"
+
#ifdef LIBXML_PATTERN_ENABLED
#define XPATH_STREAMING
#endif
"Unimplemented block at %s:%d\n", \
__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:
* If defined, this will use xmlXPathCmpNodesExt() instead of
*/
/* #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:
* There are a few spots where some tests are done which depend upon ascii
* 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)
/************************************************************************
"Encoding error\n",
"Char out of XML range\n",
"Invalid or incomplete context\n",
+ "Stack usage errror\n",
+ "Forbidden variable\n",
"?? Unknown error ??\n" /* Must be last in the list! */
};
#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \
if (list->items == NULL) {
if (initialSize <= 0)
initialSize = 1;
- list->items = (void **) xmlMalloc(
- initialSize * sizeof(void *));
+ list->items = (void **) xmlMalloc(initialSize * sizeof(void *));
if (list->items == NULL) {
xmlXPathErrMemory(NULL,
"xmlPointerListCreate: allocating item\n");
list->number = 0;
list->size = initialSize;
} else if (list->size <= list->number) {
+ if (list->size > 50000000) {
+ xmlXPathErrMemory(NULL,
+ "xmlPointerListAddSize: re-allocating item\n");
+ return(-1);
+ }
list->size *= 2;
list->items = (void **) xmlRealloc(list->items,
list->size * sizeof(void *));
if (list->items == NULL) {
xmlXPathErrMemory(NULL,
- "xmlPointerListCreate: re-allocating item\n");
+ "xmlPointerListAddSize: re-allocating item\n");
list->size = 0;
return(-1);
}
NODE_TYPE_PI = XML_PI_NODE
} xmlXPathTypeVal;
-#define XP_REWRITE_DOS_CHILD_ELEM 1
-
typedef struct _xmlXPathStepOp xmlXPathStepOp;
typedef xmlXPathStepOp *xmlXPathStepOpPtr;
struct _xmlXPathStepOp {
void *value5;
void *cache;
void *cacheURI;
- int rewriteType;
};
struct _xmlXPathCompExpr {
if (comp->nbStep >= comp->maxStep) {
xmlXPathStepOp *real;
+ if (comp->maxStep >= XPATH_MAX_STEPS) {
+ xmlXPathErrMemory(NULL, "adding step\n");
+ return(-1);
+ }
comp->maxStep *= 2;
real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
comp->maxStep * sizeof(xmlXPathStepOp));
comp->steps = real;
}
comp->last = comp->nbStep;
- comp->steps[comp->nbStep].rewriteType = 0;
comp->steps[comp->nbStep].ch1 = ch1;
comp->steps[comp->nbStep].ch2 = ch2;
comp->steps[comp->nbStep].op = op;
ret->type = XPATH_NODESET;
ret->boolval = 0;
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
xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
#endif
* *
************************************************************************/
+/**
+ * xmlXPathSetFrame:
+ * @ctxt: an XPath parser context
+ *
+ * Set the callee evaluation frame
+ *
+ * Returns the previous frame value to be restored once done
+ */
+static int
+xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
+ int ret;
+
+ if (ctxt == NULL)
+ return(0);
+ ret = ctxt->valueFrame;
+ ctxt->valueFrame = ctxt->valueNr;
+ return(ret);
+}
+
+/**
+ * xmlXPathPopFrame:
+ * @ctxt: an XPath parser context
+ * @frame: the previous frame value
+ *
+ * Remove the callee evaluation frame
+ */
+static void
+xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) {
+ if (ctxt == NULL)
+ return;
+ if (ctxt->valueNr < ctxt->valueFrame) {
+ xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
+ }
+ ctxt->valueFrame = frame;
+}
+
/**
* valuePop:
* @ctxt: an XPath evaluation context
if ((ctxt == NULL) || (ctxt->valueNr <= 0))
return (NULL);
+
+ if (ctxt->valueNr <= ctxt->valueFrame) {
+ xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
+ return (NULL);
+ }
+
ctxt->valueNr--;
if (ctxt->valueNr > 0)
ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
if (ctxt->valueNr >= ctxt->valueMax) {
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,
2 * ctxt->valueMax *
sizeof(ctxt->valueTab[0]));
if (tmp == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
+ xmlXPathErrMemory(NULL, "pushing value\n");
+ ctxt->error = XPATH_MEMORY_ERROR;
return (0);
}
ctxt->valueMax *= 2;
*/
void
xmlXPathNodeSetSort(xmlNodeSetPtr set) {
+#ifndef WITH_TIM_SORT
int i, j, incr, len;
xmlNodePtr tmp;
+#endif
if (set == NULL)
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;
for (incr = len / 2; incr > 0; incr /= 2) {
for (i = incr; i < len; i++) {
}
}
}
+#else /* WITH_TIM_SORT */
+ libxml_domnode_tim_sort(set->nodeTab, set->nodeNr);
+#endif /* WITH_TIM_SORT */
}
#define XML_NODESET_DEFAULT 10
* @ns: a the namespace node
*
* add a new namespace node to an existing NodeSet
+ *
+ * Returns 0 in case of success and -1 in case of error
*/
-void
+int
xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
int i;
if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
(ns->type != XML_NAMESPACE_DECL) ||
(node->type != XML_ELEMENT_NODE))
- return;
+ return(-1);
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
/*
(cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
(((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
(xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
- return;
+ return(0);
}
/*
sizeof(xmlNodePtr));
if (cur->nodeTab == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
- return;
+ return(-1);
}
memset(cur->nodeTab, 0 ,
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
} else if (cur->nodeNr == cur->nodeMax) {
xmlNodePtr *temp;
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+ if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+ xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
+ return(-1);
+ }
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
- return;
+ return(-1);
}
+ cur->nodeMax *= 2;
cur->nodeTab = temp;
}
cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
+ return(0);
}
/**
* @val: a new xmlNodePtr
*
* add a new xmlNodePtr to an existing NodeSet
+ *
+ * Returns 0 in case of success, and -1 in case of error
*/
-void
+int
xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
int i;
- if ((cur == NULL) || (val == NULL)) return;
-
-#if 0
- if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
- return; /* an XSLT fake node */
-#endif
+ if ((cur == NULL) || (val == NULL)) return(-1);
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
/*
* prevent duplcates
*/
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
sizeof(xmlNodePtr));
if (cur->nodeTab == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
- return;
+ return(-1);
}
memset(cur->nodeTab, 0 ,
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
} else if (cur->nodeNr == cur->nodeMax) {
xmlNodePtr *temp;
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+ if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+ xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
+ return(-1);
+ }
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
- return;
+ return(-1);
}
+ cur->nodeMax *= 2;
cur->nodeTab = temp;
}
if (val->type == XML_NAMESPACE_DECL) {
xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
} else
cur->nodeTab[cur->nodeNr++] = val;
+ return(0);
}
/**
*
* add a new xmlNodePtr to an existing NodeSet, optimized version
* when we are sure the node is not already in the set.
+ *
+ * Returns 0 in case of success and -1 in case of failure
*/
-void
+int
xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
- if ((cur == NULL) || (val == NULL)) return;
-
-#if 0
- if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
- return; /* an XSLT fake node */
-#endif
+ if ((cur == NULL) || (val == NULL)) return(-1);
/* @@ with_ns to check whether namespace nodes should be looked at @@ */
/*
sizeof(xmlNodePtr));
if (cur->nodeTab == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
- return;
+ return(-1);
}
memset(cur->nodeTab, 0 ,
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
} else if (cur->nodeNr == cur->nodeMax) {
xmlNodePtr *temp;
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+ if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+ xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
+ return(-1);
+ }
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
- return;
+ return(-1);
}
cur->nodeTab = temp;
+ cur->nodeMax *= 2;
}
if (val->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) val;
xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
} else
cur->nodeTab[cur->nodeNr++] = val;
+ return(0);
}
/**
} else if (val1->nodeNr == val1->nodeMax) {
xmlNodePtr *temp;
- val1->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
+ if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+ xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
+ return(NULL);
+ }
+ temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
val1->nodeTab = temp;
+ val1->nodeMax *= 2;
}
if (n2->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) n2;
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:
} else if (set1->nodeNr >= set1->nodeMax) {
xmlNodePtr *temp;
- set1->nodeMax *= 2;
+ if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+ xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
+ return(NULL);
+ }
temp = (xmlNodePtr *) xmlRealloc(
- set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+ set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
set1->nodeTab = temp;
+ set1->nodeMax *= 2;
}
if (n2->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) n2;
} else if (set1->nodeNr >= set1->nodeMax) {
xmlNodePtr *temp;
- set1->nodeMax *= 2;
+ if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+ xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
+ return(NULL);
+ }
temp = (xmlNodePtr *) xmlRealloc(
- set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+ set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
set1->nodeTab = temp;
+ set1->nodeMax *= 2;
}
set1->nodeTab[set1->nodeNr++] = n2;
}
ret = xmlXPathNewNodeSet(NULL);
else {
ret = xmlXPathNewNodeSet(val->nodeTab[0]);
- if (ret)
- for (i = 1; i < val->nodeNr; ++i)
- xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
+ if (ret) {
+ for (i = 1; i < val->nodeNr; ++i) {
+ if (xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i])
+ < 0) break;
+ }
+ }
}
return (ret);
for (i = 0; i < l1; i++) {
cur = xmlXPathNodeSetItem(nodes1, i);
- if (!xmlXPathNodeSetContains(nodes2, cur))
- xmlXPathNodeSetAddUnique(ret, cur);
+ if (!xmlXPathNodeSetContains(nodes2, cur)) {
+ if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
+ break;
+ }
}
return(ret);
}
for (i = 0; i < l1; i++) {
cur = xmlXPathNodeSetItem(nodes1, i);
- if (xmlXPathNodeSetContains(nodes2, cur))
- xmlXPathNodeSetAddUnique(ret, cur);
+ if (xmlXPathNodeSetContains(nodes2, cur)) {
+ if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
+ break;
+ }
}
return(ret);
}
strval = xmlXPathCastNodeToString(cur);
if (xmlHashLookup(hash, strval) == NULL) {
xmlHashAddEntry(hash, strval, strval);
- xmlXPathNodeSetAddUnique(ret, cur);
+ if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
+ break;
} else {
xmlFree(strval);
}
cur = xmlXPathNodeSetItem(nodes, i);
if (cur == node)
break;
- xmlXPathNodeSetAddUnique(ret, cur);
+ if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
+ break;
}
return(ret);
}
cur = xmlXPathNodeSetItem(nodes, i);
if (cur == node)
break;
- xmlXPathNodeSetAddUnique(ret, cur);
+ if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
+ break;
}
xmlXPathNodeSetSort(ret); /* bug 413451 */
return(ret);
ret->valueNr = 0;
ret->valueMax = 10;
ret->value = NULL;
+ ret->valueFrame = 0;
ret->context = ctxt;
ret->comp = comp;
return(NULL);
}
+#if 0
/**
* xmlXPathNextDescendantOrSelfElemParent:
* @ctxt: the XPath Parser context
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
- case XML_HTML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
return(contextNode);
default:
return(NULL);
}
return(NULL);
}
+#endif
/**
* xmlXPathNextDescendant:
return(ctxt->context->node->children);
}
+ if (cur->type == XML_NAMESPACE_DECL)
+ return(NULL);
if (cur->children != NULL) {
/*
* Do not descend on entities declarations
static int
xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
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 */
if (ancestor->doc != node->doc) return(0);
/* avoid searching if ancestor or node is the root node */
if (cur->type == XML_ATTRIBUTE_NODE)
return(cur->parent);
}
- if (cur == NULL)
+ if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
return (NULL);
if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
cur = cur->prev;
return (NULL);
ctxt->ancestor = cur->parent;
}
+ if (cur->type == XML_NAMESPACE_DECL)
+ return(NULL);
if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
cur = cur->prev;
while (cur->prev == NULL) {
int i = 0;
tmp = cur->nodesetval->nodeTab[0];
- if (tmp != NULL) {
+ if ((tmp != NULL) && (tmp->type != XML_NAMESPACE_DECL)) {
tmp = tmp->children;
while (tmp != NULL) {
tmp = tmp->next;
xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr str;
xmlXPathObjectPtr find;
- xmlBufferPtr target;
+ xmlBufPtr target;
const xmlChar *point;
int offset;
CAST_TO_STRING;
str = valuePop(ctxt);
- target = xmlBufferCreate();
+ target = xmlBufCreate();
if (target) {
point = xmlStrstr(str->stringval, find->stringval);
if (point) {
offset = (int)(point - str->stringval);
- xmlBufferAdd(target, str->stringval, offset);
+ xmlBufAdd(target, str->stringval, offset);
}
valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
- xmlBufferContent(target)));
- xmlBufferFree(target);
+ xmlBufContent(target)));
+ xmlBufFree(target);
}
xmlXPathReleaseObject(ctxt->context, str);
xmlXPathReleaseObject(ctxt->context, find);
xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr str;
xmlXPathObjectPtr find;
- xmlBufferPtr target;
+ xmlBufPtr target;
const xmlChar *point;
int offset;
CAST_TO_STRING;
str = valuePop(ctxt);
- target = xmlBufferCreate();
+ target = xmlBufCreate();
if (target) {
point = xmlStrstr(str->stringval, find->stringval);
if (point) {
offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
- xmlBufferAdd(target, &str->stringval[offset],
+ xmlBufAdd(target, &str->stringval[offset],
xmlStrlen(str->stringval) - offset);
}
valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
- xmlBufferContent(target)));
- xmlBufferFree(target);
+ xmlBufContent(target)));
+ xmlBufFree(target);
}
xmlXPathReleaseObject(ctxt->context, str);
xmlXPathReleaseObject(ctxt->context, find);
xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr obj = NULL;
xmlChar *source = NULL;
- xmlBufferPtr target;
+ xmlBufPtr target;
xmlChar blank;
if (ctxt == NULL) return;
obj = valuePop(ctxt);
source = obj->stringval;
- target = xmlBufferCreate();
+ target = xmlBufCreate();
if (target && source) {
/* Skip leading whitespaces */
blank = 0x20;
} else {
if (blank) {
- xmlBufferAdd(target, &blank, 1);
+ xmlBufAdd(target, &blank, 1);
blank = 0;
}
- xmlBufferAdd(target, source, 1);
+ xmlBufAdd(target, source, 1);
}
source++;
}
valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
- xmlBufferContent(target)));
- xmlBufferFree(target);
+ xmlBufContent(target)));
+ xmlBufFree(target);
}
xmlXPathReleaseObject(ctxt->context, obj);
}
xmlXPathObjectPtr str;
xmlXPathObjectPtr from;
xmlXPathObjectPtr to;
- xmlBufferPtr target;
+ xmlBufPtr target;
int offset, max;
xmlChar ch;
const xmlChar *point;
CAST_TO_STRING;
str = valuePop(ctxt);
- target = xmlBufferCreate();
+ target = xmlBufCreate();
if (target) {
max = xmlUTF8Strlen(to->stringval);
for (cptr = str->stringval; (ch=*cptr); ) {
if (offset < max) {
point = xmlUTF8Strpos(to->stringval, offset);
if (point)
- xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1));
+ xmlBufAdd(target, point, xmlUTF8Strsize(point, 1));
}
} else
- xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
+ xmlBufAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
/* Step to next character in input */
cptr++;
if ( (ch & 0xc0) != 0xc0 ) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathTranslateFunction: Invalid UTF8 string\n");
+ /* not asserting an XPath error is probably better */
break;
}
/* then skip over remaining bytes for this char */
if ( (*cptr++ & 0xc0) != 0x80 ) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathTranslateFunction: Invalid UTF8 string\n");
+ /* not asserting an XPath error is probably better */
break;
}
if (ch & 0x80) /* must have had error encountered */
}
}
valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
- xmlBufferContent(target)));
- xmlBufferFree(target);
+ xmlBufContent(target)));
+ xmlBufFree(target);
xmlXPathReleaseObject(ctxt->context, str);
xmlXPathReleaseObject(ctxt->context, from);
xmlXPathReleaseObject(ctxt->context, to);
xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
const xmlChar *in;
xmlChar *ret;
- int count = 0;
+ size_t count = 0;
if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
/*
in++;
if ((*in > 0) && (*in < 0x80)) {
count = in - ctxt->cur;
+ if (count > XML_MAX_NAME_LENGTH) {
+ ctxt->cur = in;
+ XP_ERRORNULL(XPATH_EXPR_ERROR);
+ }
ret = xmlStrndup(ctxt->cur, count);
ctxt->cur = in;
return(ret);
xmlChar *buffer;
int max = len * 2;
+ if (len > XML_MAX_NAME_LENGTH) {
+ XP_ERRORNULL(XPATH_EXPR_ERROR);
+ }
buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
XP_ERRORNULL(XPATH_MEMORY_ERROR);
(IS_COMBINING(c)) ||
(IS_EXTENDER(c))) {
if (len + 10 > max) {
+ if (max > XML_MAX_NAME_LENGTH) {
+ XP_ERRORNULL(XPATH_EXPR_ERROR);
+ }
max *= 2;
buffer = (xmlChar *) xmlRealloc(buffer,
max * sizeof(xmlChar));
xmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
{
double ret = 0.0;
- double mult = 1;
int ok = 0;
int exponent = 0;
int is_exponent_negative = 0;
name, prefix);
SKIP_BLANKS;
if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {
- XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR);
+ XP_ERROR(XPATH_FORBID_VARIABLE_ERROR);
}
}
*/
if (contextObj == NULL)
contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
- else
- xmlXPathNodeSetAddUnique(contextObj->nodesetval,
- contextNode);
+ else {
+ if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+ contextNode) < 0) {
+ ctxt->error = XPATH_MEMORY_ERROR;
+ goto evaluation_exit;
+ }
+ }
valuePush(ctxt, contextObj);
xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
xmlNodePtr oldContextNode, contextNode = NULL;
xmlXPathContextPtr xpctxt = ctxt->context;
+ int frame;
#ifdef LIBXML_XPTR_ENABLED
/*
*/
exprOp = &ctxt->comp->steps[op->ch2];
for (i = 0; i < set->nodeNr; i++) {
+ xmlXPathObjectPtr tmp;
+
if (set->nodeTab[i] == NULL)
continue;
*/
if (contextObj == NULL)
contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
- else
- xmlXPathNodeSetAddUnique(contextObj->nodesetval,
- contextNode);
+ else {
+ if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+ contextNode) < 0) {
+ ctxt->error = XPATH_MEMORY_ERROR;
+ goto evaluation_exit;
+ }
+ }
+ frame = xmlXPathSetFrame(ctxt);
valuePush(ctxt, contextObj);
res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
+ tmp = valuePop(ctxt);
+ xmlXPathPopFrame(ctxt, frame);
if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
- xmlXPathObjectPtr tmp;
- /* pop the result */
- tmp = valuePop(ctxt);
- xmlXPathReleaseObject(xpctxt, tmp);
- /* then pop off contextObj, which will be freed later */
- valuePop(ctxt);
+ while (tmp != contextObj) {
+ /*
+ * Free up the result
+ * then pop off contextObj, which will be freed later
+ */
+ xmlXPathReleaseObject(xpctxt, tmp);
+ tmp = valuePop(ctxt);
+ }
goto evaluation_error;
}
+ /* push the result back onto the stack */
+ valuePush(ctxt, tmp);
if (res)
pos++;
#define XP_TEST_HIT \
if (hasAxisRange != 0) { \
if (++pos == maxPos) { \
- addNode(seq, cur); \
- goto axis_range_end; } \
+ if (addNode(seq, cur) < 0) \
+ ctxt->error = XPATH_MEMORY_ERROR; \
+ goto axis_range_end; } \
} else { \
- addNode(seq, cur); \
+ if (addNode(seq, cur) < 0) \
+ ctxt->error = XPATH_MEMORY_ERROR; \
if (breakOnFirstHit) goto first_hit; }
#define XP_TEST_HIT_NS \
if (hasAxisRange != 0) { \
if (++pos == maxPos) { \
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; } \
} else { \
hasNsNodes = 1; \
- xmlXPathNodeSetAddNs(seq, \
- xpctxt->node, (xmlNsPtr) cur); \
+ if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
+ ctxt->error = XPATH_MEMORY_ERROR; \
if (breakOnFirstHit) goto first_hit; }
xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;
xmlNodeSetPtr contextSeq;
int contextIdx;
xmlNodePtr contextNode;
- /* The context node for a compound traversal */
- xmlNodePtr outerContextNode;
/* The final resulting node set wrt to all context nodes */
xmlNodeSetPtr outSeq;
/*
int breakOnFirstHit;
xmlXPathTraversalFunction next = NULL;
- /* compound axis traversal */
- xmlXPathTraversalFunctionExt outerNext = NULL;
- void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
+ int (*addNode) (xmlNodeSetPtr, xmlNodePtr);
xmlXPathNodeSetMergeFunction mergeAndClear;
xmlNodePtr oldContextNode;
xmlXPathContextPtr xpctxt = ctxt->context;
break;
case AXIS_CHILD:
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)) &&
(type == NODE_TYPE_NODE))
{
addNode = xmlXPathNodeSetAddUnique;
outSeq = NULL;
seq = NULL;
- outerContextNode = NULL;
contextNode = NULL;
contextIdx = 0;
- while ((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) {
- if (outerNext != NULL) {
- /*
- * 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++];
+ while (((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) &&
+ (ctxt->error == XPATH_EXPRESSION_OK)) {
+ xpctxt->node = contextSeq->nodeTab[contextIdx++];
if (seq == NULL) {
seq = xmlXPathNodeSetCreate(NULL);
}
break;
} /* switch(test) */
- } while (cur != NULL);
+ } while ((cur != NULL) && (ctxt->error == XPATH_EXPRESSION_OK));
goto apply_predicates;
#endif
apply_predicates: /* --------------------------------------------------- */
+ if (ctxt->error != XPATH_EXPRESSION_OK)
+ goto error;
+
/*
* Apply predicates.
*/
if ((predOp != NULL) && (seq->nodeNr > 0)) {
/*
* E.g. when we have a "/foo[some expression][n]".
- */
+ */
/*
* QUESTION TODO: The old predicate evaluation took into
* account location-sets.
* All what I learned now from the evaluation semantics
* does not indicate that a location-set will be processed
* here, so this looks OK.
- */
+ */
/*
* Iterate over all predicates, starting with the outermost
* predicate.
tmp = xmlXPathCacheNewNodeSet(ctxt->context,
ctxt->context->node);
} else {
- xmlXPathNodeSetAddUnique(tmp->nodesetval,
- ctxt->context->node);
+ if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
+ ctxt->context->node) < 0) {
+ ctxt->error = XPATH_MEMORY_ERROR;
+ }
}
valuePush(ctxt, tmp);
if (op->ch2 != -1)
tmp = xmlXPathCacheNewNodeSet(ctxt->context,
ctxt->context->node);
} else {
- xmlXPathNodeSetAddUnique(tmp->nodesetval,
- ctxt->context->node);
+ if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
+ ctxt->context->node) < 0) {
+ ctxt->error = XPATH_MEMORY_ERROR;
+ }
}
valuePush(ctxt, tmp);
ctxt->context->contextSize = oldset->nodeNr;
*/
res = valuePop(ctxt);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
- xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
+ if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) < 0)
+ ctxt->error = XPATH_MEMORY_ERROR;
}
/*
* Cleanup
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
(char *) op->value4, (char *)op->value5);
+ ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
return (total);
}
val = xmlXPathVariableLookupNS(ctxt->context,
xmlXPathFunction func;
const xmlChar *oldFunc, *oldFuncURI;
int i;
+ int frame;
+ frame = xmlXPathSetFrame(ctxt);
if (op->ch1 != -1)
total +=
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: parameter error\n");
ctxt->error = XPATH_INVALID_OPERAND;
+ xmlXPathPopFrame(ctxt, frame);
return (total);
}
- for (i = 0; i < op->value; i++)
+ for (i = 0; i < op->value; i++) {
if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: parameter error\n");
ctxt->error = XPATH_INVALID_OPERAND;
+ xmlXPathPopFrame(ctxt, frame);
return (total);
}
+ }
if (op->cache != NULL)
XML_CAST_FPTR(func) = op->cache;
else {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
(char *)op->value4, (char *)op->value5);
+ xmlXPathPopFrame(ctxt, frame);
+ ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
return (total);
}
func = xmlXPathFunctionLookupNS(ctxt->context,
func(ctxt, op->value);
ctxt->context->function = oldFunc;
ctxt->context->functionURI = oldFuncURI;
+ xmlXPathPopFrame(ctxt, frame);
return (total);
}
case XPATH_OP_ARG:
tmp = xmlXPathCacheNewNodeSet(ctxt->context,
ctxt->context->node);
} else {
- xmlXPathNodeSetAddUnique(tmp->nodesetval,
- ctxt->context->node);
+ if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
+ ctxt->context->node) < 0) {
+ ctxt->error = XPATH_MEMORY_ERROR;
+ }
}
valuePush(ctxt, tmp);
ctxt->context->contextSize = oldset->nodeNr;
*/
res = valuePop(ctxt);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
- xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
+ if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i])
+ < 0)
+ ctxt->error = XPATH_MEMORY_ERROR;
}
/*
}
xmlGenericError(xmlGenericErrorContext,
"XPath: unknown precompiled operation %d\n", op->op);
+ ctxt->error = XPATH_INVALID_OPERAND;
return (total);
}
if (toBool)
return(1);
xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
- (xmlNodePtr) ctxt->doc);
+ (xmlNodePtr) ctxt->doc);
} else {
/* Select "self::node()" */
if (toBool)
} else if (ret == 1) {
if (toBool)
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)) {
ret = xmlStreamPop(patstream);
}
scan_children:
+ if (cur->type == XML_NAMESPACE_DECL) break;
if ((cur->children != NULL) && (depth < max_depth)) {
/*
* Do not descend on entities declarations
ctxt->valueNr = 0;
ctxt->valueMax = 10;
ctxt->value = NULL;
+ ctxt->valueFrame = 0;
}
#ifdef XPATH_STREAMING
if (ctxt->comp->stream) {
}
#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
-xmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
+xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
{
/*
* Try to rewrite "descendant-or-self::node()/foo" to an optimized
* 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 */) &&
- (prevop->ch1 != -1) &&
- ((xmlXPathAxisVal) prevop->value ==
- AXIS_DESCENDANT_OR_SELF) &&
- (prevop->ch2 == -1) &&
- ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
- ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE) &&
- (comp->steps[prevop->ch1].op == XPATH_OP_ROOT))
- {
- /*
- * This is a "/descendant-or-self::node()" without predicates.
- * Eliminate it.
- */
- op->ch1 = prevop->ch1;
- op->rewriteType = XP_REWRITE_DOS_CHILD_ELEM;
- }
+
+ if ((op->ch1 != -1) &&
+ (op->op == XPATH_OP_COLLECT /* 11 */))
+ {
+ xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
+
+ if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&
+ ((xmlXPathAxisVal) prevop->value ==
+ AXIS_DESCENDANT_OR_SELF) &&
+ (prevop->ch2 == -1) &&
+ ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
+ ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE))
+ {
+ /*
+ * This is a "descendant-or-self::node()" without predicates.
+ * 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)
- xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]);
+ xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]);
}
/**
comp->string = xmlStrdup(str);
comp->nb = 0;
#endif
- if ((comp->expr != NULL) &&
- (comp->nbStep > 2) &&
- (comp->last >= 0) &&
- (xmlXPathCanRewriteDosExpression(comp->expr) == 1))
- {
- xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]);
+ if ((comp->nbStep > 1) && (comp->last >= 0)) {
+ xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]);
}
}
return(comp);
#endif
{
xmlXPathCompileExpr(ctxt, 1);
- /*
- * In this scenario the expression string will sit in ctxt->base.
- */
if ((ctxt->error == XPATH_EXPRESSION_OK) &&
(ctxt->comp != NULL) &&
- (ctxt->base != NULL) &&
- (ctxt->comp->nbStep > 2) &&
- (ctxt->comp->last >= 0) &&
- (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1))
+ (ctxt->comp->nbStep > 1) &&
+ (ctxt->comp->last >= 0))
{
- xmlXPathRewriteDOSExpression(ctxt->comp,
+ xmlXPathOptimizeExpression(ctxt->comp,
&ctxt->comp->steps[ctxt->comp->last]);
}
}
xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr str;
int escape_reserved;
- xmlBufferPtr target;
+ xmlBufPtr target;
xmlChar *cptr;
xmlChar escape[4];
CAST_TO_STRING;
str = valuePop(ctxt);
- target = xmlBufferCreate();
+ target = xmlBufCreate();
escape[0] = '%';
escape[3] = 0;
*cptr == ':' || *cptr == '@' || *cptr == '&' ||
*cptr == '=' || *cptr == '+' || *cptr == '$' ||
*cptr == ','))) {
- xmlBufferAdd(target, cptr, 1);
+ xmlBufAdd(target, cptr, 1);
} else {
if ((*cptr >> 4) < 10)
escape[1] = '0' + (*cptr >> 4);
else
escape[2] = 'A' - 10 + (*cptr & 0xF);
- xmlBufferAdd(target, &escape[0], 3);
+ xmlBufAdd(target, &escape[0], 3);
}
}
}
valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
- xmlBufferContent(target)));
- xmlBufferFree(target);
+ xmlBufContent(target)));
+ xmlBufFree(target);
xmlXPathReleaseObject(ctxt->context, str);
}