Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: third_party/libxml/src/xpath.c

Issue 1977213002: Roll libxml to 8effcb578e0590cc01bbcab0f9dccefc6bdbcdbd (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update README.chromium. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * xpath.c: XML Path Language implementation 2 * xpath.c: XML Path Language implementation
3 * XPath is a language for addressing parts of an XML document, 3 * XPath is a language for addressing parts of an XML document,
4 * designed to be used by both XSLT and XPointer 4 * designed to be used by both XSLT and XPointer
5 *f 5 *f
6 * Reference: W3C Recommendation 16 November 1999 6 * Reference: W3C Recommendation 16 November 1999
7 * http://www.w3.org/TR/1999/REC-xpath-19991116 7 * http://www.w3.org/TR/1999/REC-xpath-19991116
8 * Public reference: 8 * Public reference:
9 * http://www.w3.org/TR/xpath 9 * http://www.w3.org/TR/xpath
10 * 10 *
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 void *cache; 938 void *cache;
939 void *cacheURI; 939 void *cacheURI;
940 }; 940 };
941 941
942 struct _xmlXPathCompExpr { 942 struct _xmlXPathCompExpr {
943 int nbStep; /* Number of steps in this expression */ 943 int nbStep; /* Number of steps in this expression */
944 int maxStep; /* Maximum number of steps allocated */ 944 int maxStep; /* Maximum number of steps allocated */
945 xmlXPathStepOp *steps; /* ops for computation of this expression */ 945 xmlXPathStepOp *steps; /* ops for computation of this expression */
946 int last; /* index of last step in expression */ 946 int last; /* index of last step in expression */
947 xmlChar *expr; /* the expression being computed */ 947 xmlChar *expr; /* the expression being computed */
948 xmlDictPtr dict;» » /* the dictionnary to use if any */ 948 xmlDictPtr dict;» » /* the dictionary to use if any */
949 #ifdef DEBUG_EVAL_COUNTS 949 #ifdef DEBUG_EVAL_COUNTS
950 int nb; 950 int nb;
951 xmlChar *string; 951 xmlChar *string;
952 #endif 952 #endif
953 #ifdef XPATH_STREAMING 953 #ifdef XPATH_STREAMING
954 xmlPatternPtr stream; 954 xmlPatternPtr stream;
955 #endif 955 #endif
956 }; 956 };
957 957
958 /************************************************************************ 958 /************************************************************************
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 comp->steps[comp->nbStep].value5 = (xmlChar *) 1125 comp->steps[comp->nbStep].value5 = (xmlChar *)
1126 (void *)xmlDictLookup(comp->dict, value5, -1); 1126 (void *)xmlDictLookup(comp->dict, value5, -1);
1127 xmlFree(value5); 1127 xmlFree(value5);
1128 } else 1128 } else
1129 comp->steps[comp->nbStep].value5 = NULL; 1129 comp->steps[comp->nbStep].value5 = NULL;
1130 } else { 1130 } else {
1131 comp->steps[comp->nbStep].value4 = value4; 1131 comp->steps[comp->nbStep].value4 = value4;
1132 comp->steps[comp->nbStep].value5 = value5; 1132 comp->steps[comp->nbStep].value5 = value5;
1133 } 1133 }
1134 comp->steps[comp->nbStep].cache = NULL; 1134 comp->steps[comp->nbStep].cache = NULL;
1135 comp->steps[comp->nbStep].cacheURI = NULL;
1136 return(comp->nbStep++); 1135 return(comp->nbStep++);
1137 } 1136 }
1138 1137
1139 /** 1138 /**
1140 * xmlXPathCompSwap: 1139 * xmlXPathCompSwap:
1141 * @comp: the compiled expression 1140 * @comp: the compiled expression
1142 * @op: operation index 1141 * @op: operation index
1143 * 1142 *
1144 * Swaps 2 operations in the compiled expression 1143 * Swaps 2 operations in the compiled expression
1145 */ 1144 */
(...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after
3700 * Returns 0 in case of success, and -1 in case of error 3699 * Returns 0 in case of success, and -1 in case of error
3701 */ 3700 */
3702 int 3701 int
3703 xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { 3702 xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
3704 int i; 3703 int i;
3705 3704
3706 if ((cur == NULL) || (val == NULL)) return(-1); 3705 if ((cur == NULL) || (val == NULL)) return(-1);
3707 3706
3708 /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 3707 /* @@ with_ns to check whether namespace nodes should be looked at @@ */
3709 /* 3708 /*
3710 * prevent duplcates 3709 * prevent duplicates
3711 */ 3710 */
3712 for (i = 0;i < cur->nodeNr;i++) 3711 for (i = 0;i < cur->nodeNr;i++)
3713 if (cur->nodeTab[i] == val) return(0); 3712 if (cur->nodeTab[i] == val) return(0);
3714 3713
3715 /* 3714 /*
3716 * grow the nodeTab if needed 3715 * grow the nodeTab if needed
3717 */ 3716 */
3718 if (cur->nodeMax == 0) { 3717 if (cur->nodeMax == 0) {
3719 cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * 3718 cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
3720 sizeof(xmlNodePtr)); 3719 sizeof(xmlNodePtr));
(...skipping 4663 matching lines...) Expand 10 before | Expand all | Expand 10 after
8384 * be empty unless the context node is an element 8383 * be empty unless the context node is an element
8385 * 8384 *
8386 * We keep the XML namespace node at the end of the list. 8385 * We keep the XML namespace node at the end of the list.
8387 * 8386 *
8388 * Returns the next element following that axis 8387 * Returns the next element following that axis
8389 */ 8388 */
8390 xmlNodePtr 8389 xmlNodePtr
8391 xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 8390 xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8392 if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 8391 if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8393 if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); 8392 if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
8394 if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNames pace) { 8393 if (cur == NULL) {
8395 if (ctxt->context->tmpNsList != NULL) 8394 if (ctxt->context->tmpNsList != NULL)
8396 xmlFree(ctxt->context->tmpNsList); 8395 xmlFree(ctxt->context->tmpNsList);
8397 ctxt->context->tmpNsList = 8396 ctxt->context->tmpNsList =
8398 xmlGetNsList(ctxt->context->doc, ctxt->context->node); 8397 xmlGetNsList(ctxt->context->doc, ctxt->context->node);
8399 ctxt->context->tmpNsNr = 0; 8398 ctxt->context->tmpNsNr = 0;
8400 if (ctxt->context->tmpNsList != NULL) { 8399 if (ctxt->context->tmpNsList != NULL) {
8401 while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) { 8400 while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
8402 ctxt->context->tmpNsNr++; 8401 ctxt->context->tmpNsNr++;
8403 } 8402 }
8404 } 8403 }
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after
9990 int c; 9989 int c;
9991 9990
9992 /* 9991 /*
9993 * Handler for more complex cases 9992 * Handler for more complex cases
9994 */ 9993 */
9995 c = CUR_CHAR(l); 9994 c = CUR_CHAR(l);
9996 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 9995 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
9997 (c == '[') || (c == ']') || (c == '@') || /* accelerators */ 9996 (c == '[') || (c == ']') || (c == '@') || /* accelerators */
9998 (c == '*') || /* accelerators */ 9997 (c == '*') || /* accelerators */
9999 (!IS_LETTER(c) && (c != '_') && 9998 (!IS_LETTER(c) && (c != '_') &&
10000 ((qualified) && (c != ':')))) { 9999 ((!qualified) || (c != ':')))) {
10001 return(NULL); 10000 return(NULL);
10002 } 10001 }
10003 10002
10004 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 10003 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
10005 ((IS_LETTER(c)) || (IS_DIGIT(c)) || 10004 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
10006 (c == '.') || (c == '-') || 10005 (c == '.') || (c == '-') ||
10007 (c == '_') || ((qualified) && (c == ':')) || 10006 (c == '_') || ((qualified) && (c == ':')) ||
10008 (IS_COMBINING(c)) || 10007 (IS_COMBINING(c)) ||
10009 (IS_EXTENDER(c)))) { 10008 (IS_EXTENDER(c)))) {
10010 COPY_BUF(l,buf,len,c); 10009 COPY_BUF(l,buf,len,c);
(...skipping 2362 matching lines...) Expand 10 before | Expand all | Expand 10 after
12373 #ifdef DEBUG_STEP 12372 #ifdef DEBUG_STEP
12374 xmlGenericError(xmlGenericErrorContext, " %s", cur->name); 12373 xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
12375 #endif 12374 #endif
12376 12375
12377 switch (test) { 12376 switch (test) {
12378 case NODE_TEST_NONE: 12377 case NODE_TEST_NONE:
12379 total = 0; 12378 total = 0;
12380 STRANGE 12379 STRANGE
12381 goto error; 12380 goto error;
12382 case NODE_TEST_TYPE: 12381 case NODE_TEST_TYPE:
12383 /*
12384 * TODO: Don't we need to use
12385 * xmlXPathNodeSetAddNs() for namespace nodes here?
12386 * Surprisingly, some c14n tests fail, if we do this.
12387 */
12388 if (type == NODE_TYPE_NODE) { 12382 if (type == NODE_TYPE_NODE) {
12389 switch (cur->type) { 12383 switch (cur->type) {
12390 case XML_DOCUMENT_NODE: 12384 case XML_DOCUMENT_NODE:
12391 case XML_HTML_DOCUMENT_NODE: 12385 case XML_HTML_DOCUMENT_NODE:
12392 #ifdef LIBXML_DOCB_ENABLED 12386 #ifdef LIBXML_DOCB_ENABLED
12393 case XML_DOCB_DOCUMENT_NODE: 12387 case XML_DOCB_DOCUMENT_NODE:
12394 #endif 12388 #endif
12395 case XML_ELEMENT_NODE: 12389 case XML_ELEMENT_NODE:
12396 case XML_ATTRIBUTE_NODE: 12390 case XML_ATTRIBUTE_NODE:
12397 case XML_PI_NODE: 12391 case XML_PI_NODE:
12398 case XML_COMMENT_NODE: 12392 case XML_COMMENT_NODE:
12399 case XML_CDATA_SECTION_NODE: 12393 case XML_CDATA_SECTION_NODE:
12400 case XML_TEXT_NODE: 12394 case XML_TEXT_NODE:
12401 case XML_NAMESPACE_DECL:
12402 XP_TEST_HIT 12395 XP_TEST_HIT
12403 break; 12396 break;
12397 case XML_NAMESPACE_DECL: {
12398 if (axis == AXIS_NAMESPACE) {
12399 XP_TEST_HIT_NS
12400 } else {
12401 hasNsNodes = 1;
12402 XP_TEST_HIT
12403 }
12404 break;
12405 }
12404 default: 12406 default:
12405 break; 12407 break;
12406 } 12408 }
12407 } else if (cur->type == type) { 12409 } else if (cur->type == type) {
12408 if (cur->type == XML_NAMESPACE_DECL) 12410 if (cur->type == XML_NAMESPACE_DECL)
12409 XP_TEST_HIT_NS 12411 XP_TEST_HIT_NS
12410 else 12412 else
12411 XP_TEST_HIT 12413 XP_TEST_HIT
12412 } else if ((type == NODE_TYPE_TEXT) && 12414 } else if ((type == NODE_TYPE_TEXT) &&
12413 (cur->type == XML_CDATA_SECTION_NODE)) 12415 (cur->type == XML_CDATA_SECTION_NODE))
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
12685 } 12687 }
12686 /* 12688 /*
12687 * Hand over the result. Better to push the set also in 12689 * Hand over the result. Better to push the set also in
12688 * case of errors. 12690 * case of errors.
12689 */ 12691 */
12690 valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq)); 12692 valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq));
12691 /* 12693 /*
12692 * Reset the context node. 12694 * Reset the context node.
12693 */ 12695 */
12694 xpctxt->node = oldContextNode; 12696 xpctxt->node = oldContextNode;
12697 /*
12698 * When traversing the namespace axis in "toBool" mode, it's
12699 * possible that tmpNsList wasn't freed.
12700 */
12701 if (xpctxt->tmpNsList != NULL) {
12702 xmlFree(xpctxt->tmpNsList);
12703 xpctxt->tmpNsList = NULL;
12704 }
12695 12705
12696 #ifdef DEBUG_STEP 12706 #ifdef DEBUG_STEP
12697 xmlGenericError(xmlGenericErrorContext, 12707 xmlGenericError(xmlGenericErrorContext,
12698 "\nExamined %d nodes, found %d nodes at that step\n", 12708 "\nExamined %d nodes, found %d nodes at that step\n",
12699 total, nbMatches); 12709 total, nbMatches);
12700 #endif 12710 #endif
12701 12711
12702 return(total); 12712 return(total);
12703 } 12713 }
12704 12714
(...skipping 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after
14726 xmlDictReference(comp->dict); 14736 xmlDictReference(comp->dict);
14727 return(comp); 14737 return(comp);
14728 } 14738 }
14729 xmlFreePattern(stream); 14739 xmlFreePattern(stream);
14730 } 14740 }
14731 return(NULL); 14741 return(NULL);
14732 } 14742 }
14733 #endif /* XPATH_STREAMING */ 14743 #endif /* XPATH_STREAMING */
14734 14744
14735 static void 14745 static void
14736 xmlXPathOptimizeExpressionInternal(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr o p) 14746 xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
14737 { 14747 {
14738 /* Already optimized? */
14739 if (op->cacheURI != NULL)
14740 return;
14741
14742 /* 14748 /*
14743 * Try to rewrite "descendant-or-self::node()/foo" to an optimized 14749 * Try to rewrite "descendant-or-self::node()/foo" to an optimized
14744 * internal representation. 14750 * internal representation.
14745 */ 14751 */
14746 14752
14747 if ((op->op == XPATH_OP_COLLECT /* 11 */) && 14753 if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
14748 (op->ch1 != -1) && 14754 (op->ch1 != -1) &&
14749 (op->ch2 == -1 /* no predicate */)) 14755 (op->ch2 == -1 /* no predicate */))
14750 { 14756 {
14751 xmlXPathStepOpPtr prevop = &comp->steps[op->ch1]; 14757 xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
(...skipping 30 matching lines...) Expand all
14782 */ 14788 */
14783 op->ch1 = prevop->ch1; 14789 op->ch1 = prevop->ch1;
14784 op->value = AXIS_DESCENDANT_OR_SELF; 14790 op->value = AXIS_DESCENDANT_OR_SELF;
14785 break; 14791 break;
14786 default: 14792 default:
14787 break; 14793 break;
14788 } 14794 }
14789 } 14795 }
14790 } 14796 }
14791 14797
14792 /* Mark the node. */ 14798 /* OP_VALUE has invalid ch1. */
14793 op->cacheURI = (void*)(~0); 14799 if (op->op == XPATH_OP_VALUE)
14800 return;
14794 14801
14795 /* Recurse */ 14802 /* Recurse */
14796 if (op->ch1 != -1) 14803 if (op->ch1 != -1)
14797 xmlXPathOptimizeExpressionInternal(comp, &comp->steps[op->ch1]); 14804 xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
14798 if (op->ch2 != -1) 14805 if (op->ch2 != -1)
14799 » xmlXPathOptimizeExpressionInternal(comp, &comp->steps[op->ch2]); 14806 » xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]);
14800 }
14801
14802 static void
14803 xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, int root)
14804 {
14805 int i;
14806 /* The expression tree/graph traversal is linear, visiting
14807 * each node at most once. Mark each xmlXPathStepOp node
14808 * upon visiting, taking care of clearing out the marks
14809 * afterwards.
14810 */
14811 xmlXPathOptimizeExpressionInternal(comp, &comp->steps[root]);
14812 for (i = 0; i <= root; ++i)
14813 comp->steps[i].cacheURI = NULL;
14814 } 14807 }
14815 14808
14816 /** 14809 /**
14817 * xmlXPathCtxtCompile: 14810 * xmlXPathCtxtCompile:
14818 * @ctxt: an XPath context 14811 * @ctxt: an XPath context
14819 * @str: the XPath expression 14812 * @str: the XPath expression
14820 * 14813 *
14821 * Compile an XPath expression 14814 * Compile an XPath expression
14822 * 14815 *
14823 * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. 14816 * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
14862 } 14855 }
14863 xmlXPathFreeParserContext(pctxt); 14856 xmlXPathFreeParserContext(pctxt);
14864 14857
14865 if (comp != NULL) { 14858 if (comp != NULL) {
14866 comp->expr = xmlStrdup(str); 14859 comp->expr = xmlStrdup(str);
14867 #ifdef DEBUG_EVAL_COUNTS 14860 #ifdef DEBUG_EVAL_COUNTS
14868 comp->string = xmlStrdup(str); 14861 comp->string = xmlStrdup(str);
14869 comp->nb = 0; 14862 comp->nb = 0;
14870 #endif 14863 #endif
14871 if ((comp->nbStep > 1) && (comp->last >= 0)) { 14864 if ((comp->nbStep > 1) && (comp->last >= 0)) {
14872 » xmlXPathOptimizeExpression(comp, comp->last); 14865 » xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]);
14873 } 14866 }
14874 } 14867 }
14875 return(comp); 14868 return(comp);
14876 } 14869 }
14877 14870
14878 /** 14871 /**
14879 * xmlXPathCompile: 14872 * xmlXPathCompile:
14880 * @str: the XPath expression 14873 * @str: the XPath expression
14881 * 14874 *
14882 * Compile an XPath expression 14875 * Compile an XPath expression
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
15044 while (*ctxt->cur != 0) ctxt->cur++; 15037 while (*ctxt->cur != 0) ctxt->cur++;
15045 } else 15038 } else
15046 #endif 15039 #endif
15047 { 15040 {
15048 xmlXPathCompileExpr(ctxt, 1); 15041 xmlXPathCompileExpr(ctxt, 1);
15049 if ((ctxt->error == XPATH_EXPRESSION_OK) && 15042 if ((ctxt->error == XPATH_EXPRESSION_OK) &&
15050 (ctxt->comp != NULL) && 15043 (ctxt->comp != NULL) &&
15051 (ctxt->comp->nbStep > 1) && 15044 (ctxt->comp->nbStep > 1) &&
15052 (ctxt->comp->last >= 0)) 15045 (ctxt->comp->last >= 0))
15053 { 15046 {
15054 » xmlXPathOptimizeExpression(ctxt->comp, ctxt->comp->last); 15047 » xmlXPathOptimizeExpression(ctxt->comp,
15048 » » &ctxt->comp->steps[ctxt->comp->last]);
15055 } 15049 }
15056 } 15050 }
15057 CHECK_ERROR; 15051 CHECK_ERROR;
15058 xmlXPathRunEval(ctxt, 0); 15052 xmlXPathRunEval(ctxt, 0);
15059 } 15053 }
15060 15054
15061 /** 15055 /**
15062 * xmlXPathEval: 15056 * xmlXPathEval:
15063 * @str: the XPath expression 15057 * @str: the XPath expression
15064 * @ctx: the XPath context 15058 * @ctx: the XPath context
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
15389 xmlXPathTranslateFunction); 15383 xmlXPathTranslateFunction);
15390 15384
15391 xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", 15385 xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri",
15392 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", 15386 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions",
15393 xmlXPathEscapeUriFunction); 15387 xmlXPathEscapeUriFunction);
15394 } 15388 }
15395 15389
15396 #endif /* LIBXML_XPATH_ENABLED */ 15390 #endif /* LIBXML_XPATH_ENABLED */
15397 #define bottom_xpath 15391 #define bottom_xpath
15398 #include "elfgcchack.h" 15392 #include "elfgcchack.h"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698