我们在pub / sub代理实现中使用boost / rapidxml进行XML解析,对于某个XML有效负载,代理崩溃了。
为了消除尽可能多的变量,我实现了一个只执行XML解析的简短测试程序,崩溃类似。
我的简短测试程序在这里找到:
#include <stdio.h> // printf
#include <unistd.h> // read
#include <sys/types.h> // open
#include <sys/stat.h> // open
#include <fcntl.h> // open
#include <errno.h> // errno
#include <string.h> // strerror
#include "rapidxml.hpp"
#ifdef LONG_RAPIDXML_NAME_SPACE
// boost version >= 1.45
using namespace boost::property_tree::detail::rapidxml;
#else
// boost version <= 1.44
using namespace rapidxml;
#endif
/* ****************************************************************************
*
* xmlTreePresent -
*/
static void xmlTreePresent(xml_node<>* nodeP, std::string indent, int depth = 0)
{
static int callNo = 0;
++callNo;
if(nodeP == NULL)
{
printf("%sNULL NODE\n", indent.c_str());
}
char* name = nodeP->name();
char* value = nodeP->value();
printf("%s%s (%s) (call %d, depth %d)\n", indent.c_str(), name, value, callNo, depth);
xml_node<>* child = nodeP->first_node();
while(child != NULL)
{
printf("%schild at %p\n", indent.c_str(), child);
printf("%schild->name() at %p\n", indent.c_str(), child->name());
if((child->name() != NULL) && (child->name()[0] != 0))
{
xmlTreePresent(child, indent + " ", depth + 1);
}
child = child->next_sibling();
}
}
/* ****************************************************************************
*
* xmlDocPrepare -
*/
static xml_node<>* xmlDocPrepare(char* xml)
{
xml_document<> doc;
try
{
doc.parse<0>(xml);
}
catch(parse_error& e)
{
printf("PARSE ERROR: %s\n", e.what());
return NULL;
}
catch(...)
{
printf("GENERIC ERROR during doc.parse\n");
return NULL;
}
xml_node<>* father = doc.first_node();
return father;
}
/* ****************************************************************************
*
* main -
*/
int main(int argC, char* argV[])
{
char* fileName = argV[1];
int fd;
if((fd = open(fileName, O_RDONLY)) == -1)
{
printf("open('%s'): %s", fileName, strerror(errno));
exit(1);
}
struct stat statBuf;
if(stat(fileName, &statBuf) != 0)
{
printf("stat('%s'): %s", fileName, strerror(errno));
exit(2);
}
char* buf = (char*) calloc(1, statBuf.st_size + 1);
if(buf == NULL)
{
printf("calloc(%lu): %s", statBuf.st_size + 1, strerror(errno));
exit(3);
}
int nb = read(fd, buf, statBuf.st_size);
if(nb == -1)
{
printf("read('%s'): %s", fileName, strerror(errno));
exit(4);
}
else if(nb != statBuf.st_size)
{
printf("read %d characters, wanted %lu", nb, statBuf.st_size);
exit(5);
}
xml_node<>* father = xmlDocPrepare((char*) buf);
xmlTreePresent(father, "");
return 0;
}
示例输入XML位于:http://pastebin.com/rYiDjP7E
我在Ubuntu(libboost_serialization.so.1.49.0)和in中都试过了 CentOS(libboost_serialization.so.5)和我有类似的崩溃。
[我不确定,但我认为boost属性树位于序列化库中......]
它在CentOS中稍微进一步,但最终会发生类似的崩溃。
感谢这里的帮助,我们让用户等待修复......
答案 0 :(得分:6)
首先关闭。
这不是c ++!用
替换整个main
int main(int argc, char* argv[])
{
std::ifstream ifs(argc>1? argv[1] : "input.txt");
std::string buf(std::istreambuf_iterator<char>(ifs), {});
xml_node<>* father = xmlDocPrepare(&buf[0]);
xmlTreePresent(father, "");
}
rapidxml不是Boost的一部分。它在Boost Property Tree中使用(实现细节)
真正的错误在于:
static xml_node<>* xmlDocPrepare(char* xml)
{
xml_document<> doc;
..
xml_node<>* father = doc.first_node();
return father;
}
这会返回对( into )本地的引用,但是本地(doc
)在return语句之外不存在!我将按如下方式修复此实例:
int main(int argc, char* argv[])
{
std::ifstream ifs(argc>1? argv[1] : "input.txt");
std::string xml(std::istreambuf_iterator<char>(ifs), {});
try
{
xml_document<> doc;
doc.parse<0>(&xml[0]);
xmlTreePresent(doc.first_node());
return 0;
}
catch(parse_error& e) { printf("PARSE ERROR: %s\n", e.what()); }
catch(...) { printf("GENERIC ERROR during doc.parse\n"); }
return 1;
}
请注意我将76行代码减少为17行 :)并减少内存泄漏。
更新这是一个完全清理的版本--HURRAY - c ++而不是C:see it Live On Coliru,可以看到解析示例XML,但删除了可忽略的空格,这样你就可以了更好地看到输出。
当然,它也适用于'漂亮'的xml。
#include <fstream>
#include <iostream>
#include <iomanip>
#include <boost/property_tree/detail/rapidxml.hpp>
using namespace boost::property_tree::detail::rapidxml;
static void xmlTreePresent(xml_node<> const* nodeP, int depth = 0)
{
static int callNo = 0;
callNo += 1;
if(nodeP)
{
std::cout << std::setw(depth*2) << "" << nodeP->name()/* << " (" << nodeP->value() << ") (call " << callNo << ", depth " << depth << ")" */ << "\n";
for (xml_node<>* child = nodeP->first_node(); child; child = child->next_sibling())
{
auto name = child->name();
if(name && name[0])
{
xmlTreePresent(child, depth + 1);
}
}
} else
{
std::cout << std::setw(depth*2) << "" << "NULL NODE\n";
}
}
int main(int argc, char* argv[])
{
std::ifstream ifs(argc>1? argv[1] : "input.txt");
std::string xml(std::istreambuf_iterator<char>(ifs), {});
try
{
xml_document<> doc;
doc.parse<0>(&xml[0]);
xmlTreePresent(doc.first_node());
return 0;
}
catch(parse_error& e) { printf("PARSE ERROR: %s\n", e.what()); }
catch(...) { printf("GENERIC ERROR during doc.parse\n"); }
return 1;
}
这是删除了调试信息的输出(如/ 注释 /中所示):
updateContextRequest
contextElementList
contextElement
entityId
id
contextAttributeList
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextElement
entityId
id
contextAttributeList
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextElement
entityId
id
contextAttributeList
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextElement
entityId
id
contextAttributeList
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextElement
entityId
id
contextAttributeList
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
contextAttribute
name
type
contextValue
metadata
contextMetadata
name
type
value
updateAction