MCPcopy Create free account
hub / github.com/ClusterLabs/pacemaker / getXpathResult

Function getXpathResult

lib/common/xml.c:2691–2745  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2689}
2690
2691xmlNode *
2692getXpathResult(xmlXPathObjectPtr xpathObj, int index)
2693{
2694 xmlNode *match = NULL;
2695 CRM_CHECK(index >= 0, return NULL);
2696 CRM_CHECK(xpathObj != NULL, return NULL);
2697
2698 if(index >= xpathObj->nodesetval->nodeNr) {
2699 crm_err("Requested index %d of only %d items", index, xpathObj->nodesetval->nodeNr);
2700 return NULL;
2701 }
2702
2703 match = xpathObj->nodesetval->nodeTab[index];
2704 CRM_CHECK(match != NULL, return NULL);
2705
2706 /*
2707 * From xpath2.c
2708 *
2709 * All the elements returned by an XPath query are pointers to
2710 * elements from the tree *except* namespace nodes where the XPath
2711 * semantic is different from the implementation in libxml2 tree.
2712 * As a result when a returned node set is freed when
2713 * xmlXPathFreeObject() is called, that routine must check the
2714 * element type. But node from the returned set may have been removed
2715 * by xmlNodeSetContent() resulting in access to freed data.
2716 * This can be exercised by running
2717 * valgrind xpath2 test3.xml '//discarded' discarded
2718 * There is 2 ways around it:
2719 * - make a copy of the pointers to the nodes from the result set
2720 * then call xmlXPathFreeObject() and then modify the nodes
2721 * or
2722 * - remove the reference to the modified nodes from the node set
2723 * as they are processed, if they are not namespace nodes.
2724 */
2725 if (xpathObj->nodesetval->nodeTab[index]->type != XML_NAMESPACE_DECL) {
2726 xpathObj->nodesetval->nodeTab[index] = NULL;
2727 }
2728
2729 if(match->type == XML_DOCUMENT_NODE) {
2730 /* Will happen if section = '/' */
2731 match = match->children;
2732
2733 } else if(match->type != XML_ELEMENT_NODE
2734 && match->parent
2735 && match->parent->type == XML_ELEMENT_NODE) {
2736 /* reurning the parent instead */
2737 match = match->parent;
2738
2739 } else if(match->type != XML_ELEMENT_NODE) {
2740 /* We only support searching nodes */
2741 crm_err("We only support %d not %d", XML_ELEMENT_NODE, match->type);
2742 match = NULL;
2743 }
2744 return match;
2745}
2746
2747/* the caller needs to check if the result contains a xmlDocPtr or xmlNodePtr */
2748xmlXPathObjectPtr

Callers 14

crm_diff_updateFunction · 0.85
get_on_target_actionsFunction · 0.85
remove_cib_deviceFunction · 0.85
remove_fencing_topologyFunction · 0.85
register_cib_deviceFunction · 0.85
cib_config_changedFunction · 0.85
cib_process_xpathFunction · 0.85
search_xpath_objectsFunction · 0.85
stonith_api_queryFunction · 0.85
get_xpath_objectFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected