diff options
Diffstat (limited to 'xpath.c')
-rw-r--r-- | xpath.c | 636 |
1 files changed, 254 insertions, 382 deletions
@@ -55,8 +55,6 @@ #include <libxml/pattern.h> #endif -#include "buf.h" - #ifdef LIBXML_PATTERN_ENABLED #define XPATH_STREAMING #endif @@ -66,15 +64,6 @@ "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 @@ -101,76 +90,12 @@ /* #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 * data. These should be enhanced for full UTF8 support (see particularly * 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) /************************************************************************ @@ -328,7 +253,6 @@ static const char *xmlXPathErrorMessages[] = { "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) / \ @@ -496,7 +420,8 @@ xmlPointerListAddSize(xmlPointerListPtr list, 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"); @@ -505,17 +430,12 @@ xmlPointerListAddSize(xmlPointerListPtr list, 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, - "xmlPointerListAddSize: re-allocating item\n"); + "xmlPointerListCreate: re-allocating item\n"); list->size = 0; return(-1); } @@ -633,6 +553,8 @@ typedef enum { NODE_TYPE_PI = XML_PI_NODE } xmlXPathTypeVal; +#define XP_REWRITE_DOS_CHILD_ELEM 1 + typedef struct _xmlXPathStepOp xmlXPathStepOp; typedef xmlXPathStepOp *xmlXPathStepOpPtr; struct _xmlXPathStepOp { @@ -646,6 +568,7 @@ struct _xmlXPathStepOp { void *value5; void *cache; void *cacheURI; + int rewriteType; }; struct _xmlXPathCompExpr { @@ -800,10 +723,6 @@ xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, 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)); @@ -815,6 +734,7 @@ xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, 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; @@ -2132,11 +2052,6 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val) 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 @@ -2565,16 +2480,11 @@ valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value) 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) { - xmlXPathErrMemory(NULL, "pushing value\n"); + xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); ctxt->error = XPATH_MEMORY_ERROR; return (0); } @@ -3410,19 +3320,13 @@ turtle_comparison: */ void xmlXPathNodeSetSort(xmlNodeSetPtr set) { -#ifndef WITH_TIM_SORT int i, j, incr, len; xmlNodePtr tmp; -#endif if (set == NULL) return; -#ifndef WITH_TIM_SORT - /* - * Use the old Shell's sort implementation to sort the node-set - * Timsort ought to be quite faster - */ + /* Use Shell's sort to sort the node-set */ len = set->nodeNr; for (incr = len / 2; incr > 0; incr /= 2) { for (i = incr; i < len; i++) { @@ -3445,9 +3349,6 @@ xmlXPathNodeSetSort(xmlNodeSetPtr set) { } } } -#else /* WITH_TIM_SORT */ - libxml_domnode_tim_sort(set->nodeTab, set->nodeNr); -#endif /* WITH_TIM_SORT */ } #define XML_NODESET_DEFAULT 10 @@ -3626,10 +3527,8 @@ xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) { * @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 */ -int +void xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { int i; @@ -3637,7 +3536,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { if ((cur == NULL) || (ns == NULL) || (node == NULL) || (ns->type != XML_NAMESPACE_DECL) || (node->type != XML_ELEMENT_NODE)) - return(-1); + return; /* @@ with_ns to check whether namespace nodes should be looked at @@ */ /* @@ -3648,7 +3547,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) && (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) && (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix))) - return(0); + return; } /* @@ -3659,7 +3558,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { sizeof(xmlNodePtr)); if (cur->nodeTab == NULL) { xmlXPathErrMemory(NULL, "growing nodeset\n"); - return(-1); + return; } memset(cur->nodeTab, 0 , XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); @@ -3667,21 +3566,16 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { } else if (cur->nodeNr == cur->nodeMax) { 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 * sizeof(xmlNodePtr)); if (temp == NULL) { xmlXPathErrMemory(NULL, "growing nodeset\n"); - return(-1); + return; } cur->nodeMax *= 2; cur->nodeTab = temp; } cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns); - return(0); } /** @@ -3690,21 +3584,24 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { * @val: a new xmlNodePtr * * add a new xmlNodePtr to an existing NodeSet - * - * Returns 0 in case of success, and -1 in case of error */ -int +void xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { int i; - if ((cur == NULL) || (val == NULL)) return(-1); + if ((cur == NULL) || (val == NULL)) return; + +#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 @@ */ /* * prevent duplcates */ for (i = 0;i < cur->nodeNr;i++) - if (cur->nodeTab[i] == val) return(0); + if (cur->nodeTab[i] == val) return; /* * grow the nodeTab if needed @@ -3714,7 +3611,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { sizeof(xmlNodePtr)); if (cur->nodeTab == NULL) { xmlXPathErrMemory(NULL, "growing nodeset\n"); - return(-1); + return; } memset(cur->nodeTab, 0 , XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); @@ -3722,15 +3619,11 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { } else if (cur->nodeNr == cur->nodeMax) { 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 * sizeof(xmlNodePtr)); if (temp == NULL) { xmlXPathErrMemory(NULL, "growing nodeset\n"); - return(-1); + return; } cur->nodeMax *= 2; cur->nodeTab = temp; @@ -3742,7 +3635,6 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); } else cur->nodeTab[cur->nodeNr++] = val; - return(0); } /** @@ -3752,12 +3644,15 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { * * 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 */ -int +void xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { - if ((cur == NULL) || (val == NULL)) return(-1); + if ((cur == NULL) || (val == NULL)) return; + +#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 @@ */ /* @@ -3768,7 +3663,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { sizeof(xmlNodePtr)); if (cur->nodeTab == NULL) { xmlXPathErrMemory(NULL, "growing nodeset\n"); - return(-1); + return; } memset(cur->nodeTab, 0 , XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); @@ -3776,15 +3671,11 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { } else if (cur->nodeNr == cur->nodeMax) { 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 * sizeof(xmlNodePtr)); if (temp == NULL) { xmlXPathErrMemory(NULL, "growing nodeset\n"); - return(-1); + return; } cur->nodeTab = temp; cur->nodeMax *= 2; @@ -3796,7 +3687,6 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) { xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); } else cur->nodeTab[cur->nodeNr++] = val; - return(0); } /** @@ -3892,10 +3782,6 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { } else if (val1->nodeNr == val1->nodeMax) { 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 * sizeof(xmlNodePtr)); if (temp == NULL) { @@ -3917,6 +3803,68 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { 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: @@ -4003,10 +3951,6 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2, } else if (set1->nodeNr >= set1->nodeMax) { xmlNodePtr *temp; - if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) { - xmlXPathErrMemory(NULL, "merging nodeset hit limit\n"); - return(NULL); - } temp = (xmlNodePtr *) xmlRealloc( set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr)); if (temp == NULL) { @@ -4091,10 +4035,6 @@ xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2, } else if (set1->nodeNr >= set1->nodeMax) { xmlNodePtr *temp; - if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) { - xmlXPathErrMemory(NULL, "merging nodeset hit limit\n"); - return(NULL); - } temp = (xmlNodePtr *) xmlRealloc( set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr)); if (temp == NULL) { @@ -4393,12 +4333,9 @@ xmlXPathNewNodeSetList(xmlNodeSetPtr val) ret = xmlXPathNewNodeSet(NULL); else { ret = xmlXPathNewNodeSet(val->nodeTab[0]); - if (ret) { - for (i = 1; i < val->nodeNr; ++i) { - if (xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]) - < 0) break; - } - } + if (ret) + for (i = 1; i < val->nodeNr; ++i) + xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]); } return (ret); @@ -4474,10 +4411,8 @@ xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { for (i = 0; i < l1; i++) { cur = xmlXPathNodeSetItem(nodes1, i); - if (!xmlXPathNodeSetContains(nodes2, cur)) { - if (xmlXPathNodeSetAddUnique(ret, cur) < 0) - break; - } + if (!xmlXPathNodeSetContains(nodes2, cur)) + xmlXPathNodeSetAddUnique(ret, cur); } return(ret); } @@ -4510,10 +4445,8 @@ xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) { for (i = 0; i < l1; i++) { cur = xmlXPathNodeSetItem(nodes1, i); - if (xmlXPathNodeSetContains(nodes2, cur)) { - if (xmlXPathNodeSetAddUnique(ret, cur) < 0) - break; - } + if (xmlXPathNodeSetContains(nodes2, cur)) + xmlXPathNodeSetAddUnique(ret, cur); } return(ret); } @@ -4549,8 +4482,7 @@ xmlXPathDistinctSorted (xmlNodeSetPtr nodes) { strval = xmlXPathCastNodeToString(cur); if (xmlHashLookup(hash, strval) == NULL) { xmlHashAddEntry(hash, strval, strval); - if (xmlXPathNodeSetAddUnique(ret, cur) < 0) - break; + xmlXPathNodeSetAddUnique(ret, cur); } else { xmlFree(strval); } @@ -4642,8 +4574,7 @@ xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { cur = xmlXPathNodeSetItem(nodes, i); if (cur == node) break; - if (xmlXPathNodeSetAddUnique(ret, cur) < 0) - break; + xmlXPathNodeSetAddUnique(ret, cur); } return(ret); } @@ -4747,8 +4678,7 @@ xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { cur = xmlXPathNodeSetItem(nodes, i); if (cur == node) break; - if (xmlXPathNodeSetAddUnique(ret, cur) < 0) - break; + xmlXPathNodeSetAddUnique(ret, cur); } xmlXPathNodeSetSort(ret); /* bug 413451 */ return(ret); @@ -7771,7 +7701,6 @@ xmlXPathNextChildElement(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { return(NULL); } -#if 0 /** * xmlXPathNextDescendantOrSelfElemParent: * @ctxt: the XPath Parser context @@ -7799,7 +7728,7 @@ xmlXPathNextDescendantOrSelfElemParent(xmlNodePtr cur, #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); @@ -7847,7 +7776,6 @@ next_sibling: } return(NULL); } -#endif /** * xmlXPathNextDescendant: @@ -7875,8 +7803,6 @@ xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { return(ctxt->context->node->children); } - if (cur->type == XML_NAMESPACE_DECL) - return(NULL); if (cur->children != NULL) { /* * Do not descend on entities declarations @@ -8259,10 +8185,6 @@ xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 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 */ @@ -8300,7 +8222,7 @@ xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) if (cur->type == XML_ATTRIBUTE_NODE) return(cur->parent); } - if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) + if (cur == NULL) return (NULL); if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) cur = cur->prev; @@ -8347,8 +8269,6 @@ xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, 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) { @@ -8556,7 +8476,7 @@ xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) { int i = 0; tmp = cur->nodesetval->nodeTab[0]; - if ((tmp != NULL) && (tmp->type != XML_NAMESPACE_DECL)) { + if (tmp != NULL) { tmp = tmp->children; while (tmp != NULL) { tmp = tmp->next; @@ -9226,7 +9146,7 @@ void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr str; xmlXPathObjectPtr find; - xmlBufPtr target; + xmlBufferPtr target; const xmlChar *point; int offset; @@ -9236,16 +9156,16 @@ xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { CAST_TO_STRING; str = valuePop(ctxt); - target = xmlBufCreate(); + target = xmlBufferCreate(); if (target) { point = xmlStrstr(str->stringval, find->stringval); if (point) { offset = (int)(point - str->stringval); - xmlBufAdd(target, str->stringval, offset); + xmlBufferAdd(target, str->stringval, offset); } valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, - xmlBufContent(target))); - xmlBufFree(target); + xmlBufferContent(target))); + xmlBufferFree(target); } xmlXPathReleaseObject(ctxt->context, str); xmlXPathReleaseObject(ctxt->context, find); @@ -9269,7 +9189,7 @@ void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr str; xmlXPathObjectPtr find; - xmlBufPtr target; + xmlBufferPtr target; const xmlChar *point; int offset; @@ -9279,17 +9199,17 @@ xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { CAST_TO_STRING; str = valuePop(ctxt); - target = xmlBufCreate(); + target = xmlBufferCreate(); if (target) { point = xmlStrstr(str->stringval, find->stringval); if (point) { offset = (int)(point - str->stringval) + xmlStrlen(find->stringval); - xmlBufAdd(target, &str->stringval[offset], + xmlBufferAdd(target, &str->stringval[offset], xmlStrlen(str->stringval) - offset); } valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, - xmlBufContent(target))); - xmlBufFree(target); + xmlBufferContent(target))); + xmlBufferFree(target); } xmlXPathReleaseObject(ctxt->context, str); xmlXPathReleaseObject(ctxt->context, find); @@ -9313,7 +9233,7 @@ void xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr obj = NULL; xmlChar *source = NULL; - xmlBufPtr target; + xmlBufferPtr target; xmlChar blank; if (ctxt == NULL) return; @@ -9331,7 +9251,7 @@ xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { obj = valuePop(ctxt); source = obj->stringval; - target = xmlBufCreate(); + target = xmlBufferCreate(); if (target && source) { /* Skip leading whitespaces */ @@ -9345,16 +9265,16 @@ xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { blank = 0x20; } else { if (blank) { - xmlBufAdd(target, &blank, 1); + xmlBufferAdd(target, &blank, 1); blank = 0; } - xmlBufAdd(target, source, 1); + xmlBufferAdd(target, source, 1); } source++; } valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, - xmlBufContent(target))); - xmlBufFree(target); + xmlBufferContent(target))); + xmlBufferFree(target); } xmlXPathReleaseObject(ctxt->context, obj); } @@ -9385,7 +9305,7 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr str; xmlXPathObjectPtr from; xmlXPathObjectPtr to; - xmlBufPtr target; + xmlBufferPtr target; int offset, max; xmlChar ch; const xmlChar *point; @@ -9400,7 +9320,7 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { CAST_TO_STRING; str = valuePop(ctxt); - target = xmlBufCreate(); + target = xmlBufferCreate(); if (target) { max = xmlUTF8Strlen(to->stringval); for (cptr = str->stringval; (ch=*cptr); ) { @@ -9409,10 +9329,10 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { if (offset < max) { point = xmlUTF8Strpos(to->stringval, offset); if (point) - xmlBufAdd(target, point, xmlUTF8Strsize(point, 1)); + xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1)); } } else - xmlBufAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); + xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); /* Step to next character in input */ cptr++; @@ -9438,8 +9358,8 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { } } valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, - xmlBufContent(target))); - xmlBufFree(target); + xmlBufferContent(target))); + xmlBufferFree(target); xmlXPathReleaseObject(ctxt->context, str); xmlXPathReleaseObject(ctxt->context, from); xmlXPathReleaseObject(ctxt->context, to); @@ -9946,7 +9866,7 @@ xmlChar * xmlXPathParseName(xmlXPathParserContextPtr ctxt) { const xmlChar *in; xmlChar *ret; - size_t count = 0; + int count = 0; if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL); /* @@ -9965,10 +9885,6 @@ xmlXPathParseName(xmlXPathParserContextPtr ctxt) { 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); @@ -10012,9 +9928,6 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { 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); @@ -10026,9 +9939,6 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { (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)); @@ -10381,7 +10291,7 @@ xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { name, prefix); SKIP_BLANKS; if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) { - XP_ERROR(XPATH_FORBID_VARIABLE_ERROR); + XP_ERROR(XPATH_UNDEF_VARIABLE_ERROR); } } @@ -11745,13 +11655,9 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt, */ if (contextObj == NULL) contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode); - else { - if (xmlXPathNodeSetAddUnique(contextObj->nodesetval, - contextNode) < 0) { - ctxt->error = XPATH_MEMORY_ERROR; - goto evaluation_exit; - } - } + else + xmlXPathNodeSetAddUnique(contextObj->nodesetval, + contextNode); valuePush(ctxt, contextObj); @@ -11897,13 +11803,9 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, */ if (contextObj == NULL) contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode); - else { - if (xmlXPathNodeSetAddUnique(contextObj->nodesetval, - contextNode) < 0) { - ctxt->error = XPATH_MEMORY_ERROR; - goto evaluation_exit; - } - } + else + xmlXPathNodeSetAddUnique(contextObj->nodesetval, + contextNode); frame = xmlXPathSetFrame(ctxt); valuePush(ctxt, contextObj); @@ -12075,25 +11977,22 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, #define XP_TEST_HIT \ if (hasAxisRange != 0) { \ if (++pos == maxPos) { \ - if (addNode(seq, cur) < 0) \ - ctxt->error = XPATH_MEMORY_ERROR; \ - goto axis_range_end; } \ + addNode(seq, cur); \ + goto axis_range_end; } \ } else { \ - if (addNode(seq, cur) < 0) \ - ctxt->error = XPATH_MEMORY_ERROR; \ + addNode(seq, cur); \ if (breakOnFirstHit) goto first_hit; } #define XP_TEST_HIT_NS \ if (hasAxisRange != 0) { \ if (++pos == maxPos) { \ hasNsNodes = 1; \ - if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \ - ctxt->error = XPATH_MEMORY_ERROR; \ + xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur); \ goto axis_range_end; } \ } else { \ hasNsNodes = 1; \ - if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \ - ctxt->error = XPATH_MEMORY_ERROR; \ + xmlXPathNodeSetAddNs(seq, \ + xpctxt->node, (xmlNsPtr) cur); \ if (breakOnFirstHit) goto first_hit; } xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value; @@ -12113,6 +12012,8 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 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; /* @@ -12128,7 +12029,9 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, int breakOnFirstHit; xmlXPathTraversalFunction next = NULL; - int (*addNode) (xmlNodeSetPtr, xmlNodePtr); + /* compound axis traversal */ + xmlXPathTraversalFunctionExt outerNext = NULL; + void (*addNode) (xmlNodeSetPtr, xmlNodePtr); xmlXPathNodeSetMergeFunction mergeAndClear; xmlNodePtr oldContextNode; xmlXPathContextPtr xpctxt = ctxt->context; @@ -12177,6 +12080,13 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 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)) { @@ -12306,13 +12216,32 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, addNode = xmlXPathNodeSetAddUnique; outSeq = NULL; seq = NULL; + outerContextNode = NULL; contextNode = NULL; contextIdx = 0; - while (((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) && - (ctxt->error == XPATH_EXPRESSION_OK)) { - xpctxt->node = contextSeq->nodeTab[contextIdx++]; + 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++]; if (seq == NULL) { seq = xmlXPathNodeSetCreate(NULL); @@ -12399,7 +12328,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, break; } } else if (cur->type == type) { - if (cur->type == XML_NAMESPACE_DECL) + if (type == XML_NAMESPACE_DECL) XP_TEST_HIT_NS else XP_TEST_HIT @@ -12510,7 +12439,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, } break; } /* switch(test) */ - } while ((cur != NULL) && (ctxt->error == XPATH_EXPRESSION_OK)); + } while (cur != NULL); goto apply_predicates; @@ -12551,16 +12480,13 @@ first_hit: /* ---------------------------------------------------------- */ #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. @@ -12569,7 +12495,7 @@ apply_predicates: /* --------------------------------------------------- */ * 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. @@ -13062,10 +12988,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, tmp = xmlXPathCacheNewNodeSet(ctxt->context, ctxt->context->node); } else { - if (xmlXPathNodeSetAddUnique(tmp->nodesetval, - ctxt->context->node) < 0) { - ctxt->error = XPATH_MEMORY_ERROR; - } + xmlXPathNodeSetAddUnique(tmp->nodesetval, + ctxt->context->node); } valuePush(ctxt, tmp); if (op->ch2 != -1) @@ -13178,10 +13102,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, tmp = xmlXPathCacheNewNodeSet(ctxt->context, ctxt->context->node); } else { - if (xmlXPathNodeSetAddUnique(tmp->nodesetval, - ctxt->context->node) < 0) { - ctxt->error = XPATH_MEMORY_ERROR; - } + xmlXPathNodeSetAddUnique(tmp->nodesetval, + ctxt->context->node); } valuePush(ctxt, tmp); ctxt->context->contextSize = oldset->nodeNr; @@ -13199,8 +13121,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, */ res = valuePop(ctxt); if (xmlXPathEvaluatePredicateResult(ctxt, res)) { - if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) < 0) - ctxt->error = XPATH_MEMORY_ERROR; + xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); } /* * Cleanup @@ -13879,10 +13800,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) tmp = xmlXPathCacheNewNodeSet(ctxt->context, ctxt->context->node); } else { - if (xmlXPathNodeSetAddUnique(tmp->nodesetval, - ctxt->context->node) < 0) { - ctxt->error = XPATH_MEMORY_ERROR; - } + xmlXPathNodeSetAddUnique(tmp->nodesetval, + ctxt->context->node); } valuePush(ctxt, tmp); ctxt->context->contextSize = oldset->nodeNr; @@ -13912,9 +13831,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) */ res = valuePop(ctxt); if (xmlXPathEvaluatePredicateResult(ctxt, res)) { - if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) - < 0) - ctxt->error = XPATH_MEMORY_ERROR; + xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); } /* @@ -14277,7 +14194,7 @@ xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp, if (toBool) return(1); xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, - (xmlNodePtr) ctxt->doc); + (xmlNodePtr) ctxt->doc); } else { /* Select "self::node()" */ if (toBool) @@ -14370,11 +14287,7 @@ next_node: } else if (ret == 1) { if (toBool) goto return_1; - if (xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur) - < 0) { - ctxt->lastError.domain = XML_FROM_XPATH; - ctxt->lastError.code = XML_ERR_NO_MEMORY; - } + xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur); } if ((cur->children == NULL) || (depth >= max_depth)) { ret = xmlStreamPop(patstream); @@ -14390,7 +14303,6 @@ next_node: } scan_children: - if (cur->type == XML_NAMESPACE_DECL) break; if ((cur->children != NULL) && (depth < max_depth)) { /* * Do not descend on entities declarations @@ -14711,63 +14623,57 @@ xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { } #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 -xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op) +xmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op) { /* * Try to rewrite "descendant-or-self::node()/foo" to an optimized * internal representation. */ - - 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) { + 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) + xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch1]); } - - /* Recurse */ - if (op->ch1 != -1) - xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]); if (op->ch2 != -1) - xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]); + xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]); } /** @@ -14825,8 +14731,12 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { comp->string = xmlStrdup(str); comp->nb = 0; #endif - if ((comp->nbStep > 1) && (comp->last >= 0)) { - xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]); + if ((comp->expr != NULL) && + (comp->nbStep > 2) && + (comp->last >= 0) && + (xmlXPathCanRewriteDosExpression(comp->expr) == 1)) + { + xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]); } } return(comp); @@ -15003,12 +14913,17 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { #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->comp->nbStep > 1) && - (ctxt->comp->last >= 0)) + (ctxt->base != NULL) && + (ctxt->comp->nbStep > 2) && + (ctxt->comp->last >= 0) && + (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1)) { - xmlXPathOptimizeExpression(ctxt->comp, + xmlXPathRewriteDOSExpression(ctxt->comp, &ctxt->comp->steps[ctxt->comp->last]); } } @@ -15079,49 +14994,6 @@ xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { } /** - * 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: * @str: the XPath expression * @ctxt: the XPath context @@ -15225,7 +15097,7 @@ static void xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr str; int escape_reserved; - xmlBufPtr target; + xmlBufferPtr target; xmlChar *cptr; xmlChar escape[4]; @@ -15236,7 +15108,7 @@ xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { CAST_TO_STRING; str = valuePop(ctxt); - target = xmlBufCreate(); + target = xmlBufferCreate(); escape[0] = '%'; escape[3] = 0; @@ -15261,7 +15133,7 @@ xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { *cptr == ':' || *cptr == '@' || *cptr == '&' || *cptr == '=' || *cptr == '+' || *cptr == '$' || *cptr == ','))) { - xmlBufAdd(target, cptr, 1); + xmlBufferAdd(target, cptr, 1); } else { if ((*cptr >> 4) < 10) escape[1] = '0' + (*cptr >> 4); @@ -15272,13 +15144,13 @@ xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { else escape[2] = 'A' - 10 + (*cptr & 0xF); - xmlBufAdd(target, &escape[0], 3); + xmlBufferAdd(target, &escape[0], 3); } } } valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, - xmlBufContent(target))); - xmlBufFree(target); + xmlBufferContent(target))); + xmlBufferFree(target); xmlXPathReleaseObject(ctxt->context, str); } |