[xml] Recursive call to xmlXPathNewContext



I written a wrapper around  xmlXPathNewContext and  xmlXPathEvalExpression (maybe re-inventing the wheel :) ) to obtain an xmlXPathObjectPtr.
Here below there is the function:
/**
 * =====================================================================================
 * fn xmlXPathObjectPtr get_xml_elements(xmlNodePtr nodePtr,char *elementName)
 *         @brief this function looks for elements named elementName in the
 *         passed xmlNodePtr.
 *         @param nodePtr a  xmlNodePtr where to look for element named
 *         elementName
 *         @param context an xmlXPathContextPtr passed in case of recursive
 *         parsing and recusive use of get_xml_elements 
 *         @return xmlXPathObjectPtr containing one or more element named
 *         elementName. NOTE: Returned pointer must be freed by the caller with
 *         xmlXPathFreeObject()
 * =====================================================================================
 */
xmlXPathObjectPtr get_xml_elements(xmlNodePtr nodePtr,char *elementName)
{
  xmlXPathObjectPtr result=NULL;
  xmlChar * lookup=NULL;
  int extraSpace=strlen("child::");
  xmlXPathContextPtr context=NULL;
  /** check parameters */
  if(nodePtr==NULL || elementName == NULL){
    ERRORS(EINVAL,"null pointer param passed\nnodePtr=%p,elementName=%p",nodePtr,elementName);
    return NULL;
  }
 
  /** xmlXPathNewContext allocs a xmlXPathContextPtr */

  context = xmlXPathNewContext(nodePtr->doc);
  if(context==NULL){
    ERRORS(ENOMEM,"xmlXPathNewContext fails\n");
    return NULL;
  }
  /** configure node, the current node, to the one passed in the arg */
  context->node=nodePtr;

  /** resize lookup of extraspace+1 :1 for \0 and extraspace for axis */
  lookup=calloc(strlen(elementName)+extraSpace+1,sizeof(xmlChar));
  if(lookup==NULL){
    ERRORS(ENOMEM,"Error allocating space for alloc new string child::%s\n",elementName);
    return NULL;
  }
  strcat((char *)lookup,"child::");
  strcat((char *)lookup,elementName);
  result = xmlXPathEvalExpression(lookup,context);
  free(lookup);

  xmlXPathFreeContext(context);
  if(result == NULL){
    ERROR("error in xmlXPathEvalExpression\n");
    return NULL;
  }
  if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
    xmlXPathFreeObject(result);
    ERROR("No Element %s found\n",elementName);
    //print_element_names((xmlNodePtr)nodePtr);
    return NULL;
  }
  return result;
}

the returned xmlXPathObjectPtr is used to cycle on the single element and it's possible that during that, get_xml_elements is called again passing as nodePtr parameter the node obtained from the previous call to xml_get_elements.
It happens that on the second call I get a segmentation fault creating the context:
context = xmlXPathNewContext(nodePtr->doc);
here the stack:

malloc () from /lib/libc.so.6
xmlHashCreate () from /usr/lib/libxml2.so.2
xmlXPathNewContext () from /usr/lib/libxml2.so.2
get_xml_elements (nodePtr=0x8057940, elementName=0x804e51d "field", context=0x0) at xmlParse.c:169

Can someone tell me if I'm doing a well known error, that is: creating a context by using an element obtained from a previous created and already freed context?
I hope the question is clear.
 Regards
   zad


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]