Closed GoogleCodeExporter closed 9 years ago
You are returning pointers to local variables from the function:
CXmlDocument::GetChildNode(const std::wstring& xpath,uint index, CXmlNode& node)
{
...
pugi::xml_node rNode;
...
node.m_XmlNode = &rNode;
...
}
It's not safe. Don't do that.
Also you don't need to use first_element_by_path and select_nodes at the same
time - just pick one. first_element_by_path does not use XPath, select_nodes
does.
Original comment by arseny.k...@gmail.com
on 17 Sep 2012 at 8:31
I have changed code to following. It returns garbage in node. Please read
CDS_RETVAL as int and CDS_UINT32 as uint
CDS_RETVAL CXmlDocument::GetChildNode(const std::wstring& xpath, CDS_UINT32
index, CXmlNode& node) const
{
CConverter m_Converter;
CDS_UINT32 nodeIndex = 0;
pugi::xpath_node_set xPathNodeSet;
CDS_RETVAL retVal;
pugi::xml_node findNode;
//Convert wstring to pugi::char_t*
std::string strXpath = m_Converter.WideStringToString(xpath);
const pugi::char_t* pugiXpath = strXpath.c_str();
if(NULL == m_XmlDocument)
return CDS_ERROR_INSTANCE;
retVal = OK;
//check if nodelist is empty then fail
xPathNodeSet = m_XmlDocument->select_nodes(pugiXpath);
int size = xPathNodeSet.size();
if(1 > xPathNodeSet.size())
{
retVal = CDS_ERROR_VALUE_NOT_FOUND; goto CleanUp;
}
//retVal = GetChildNodes(xpath,nodeList);
if (NULL != node.m_XmlNode)
{
#ifdef DEBUG
assert(0);
#else
m_log.AddLog(cModuleUtility, cLevelError, "MEMORY LEAK in CXmlDocument::GetChildNode");
#endif
}
//Search nodelist for the node with index
node.m_XmlNode = &m_XmlDocument->first_element_by_path(pugiXpath);
if(NULL == node.m_XmlNode)
{
retVal = CDS_ERROR_INSTANCE; goto CleanUp;
}
node.m_XmlNode = &xPathNodeSet[index].node() ;//.operator [index-1];
if(NULL == node.m_XmlNode)
{
retVal = CDS_ERROR_INSTANCE; goto CleanUp;
}CleanUp:
return retVal;
}
Original comment by rajesh.s...@gmail.com
on 17 Sep 2012 at 9:18
This code has the same issue. xml_node objects are temporary; the real data is
stored in an internal object, xml_node has a pointer to it.
If you have a pointer to xml_node anywhere in your program except for output
parameters in a function, it is probably a mistake. Replace all pointers to
xml_node with values; don't hesitate to copy xml_node objects (it's almost
free).
Original comment by arseny.k...@gmail.com
on 17 Sep 2012 at 9:20
Will appreciate if you show it by example.
Thanks and Best Regards,
Rajesh
Original comment by rajesh.s...@gmail.com
on 18 Sep 2012 at 3:43
Here's how I would write this code.
struct CXmlNode
{
pugi::xml_node m_XmlNode;
};
CDS_RETVAL CXmlDocument::GetChildNode(const std::wstring& xpath, CDS_UINT32
index, CXmlNode& node) const
{
if (NULL == m_XmlDocument)
return CDS_ERROR_INSTANCE;
std::string query = pugi::as_utf8(xpath);
pugi::xpath_node_set nodes = m_XmlDocument->select_nodes(query.c_str());
if (index >= nodes.size())
return CDS_ERROR_VALUE_NOT_FOUND
node.m_XmlNode = nodes[index].node();
if (!node.m_XmlNode)
return CDS_ERROR_INSTANCE;
return OK;
}
Original comment by arseny.k...@gmail.com
on 18 Sep 2012 at 3:57
Original comment by arseny.k...@gmail.com
on 18 Sep 2012 at 3:58
Original issue reported on code.google.com by
rajesh.s...@gmail.com
on 17 Sep 2012 at 7:42