kza*_*eli 1 c++ boost rapidxml
我们在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;
}
Run Code Online (Sandbox Code Playgroud)
这里有一个示例输入XML:http://pastebin.com/rYiDjP7E
我在Ubuntu(libboost_serialization.so.1.49.0)和CentOS(libboost_serialization.so.5)中都试过了,我遇到了类似的崩溃.
[我不确定,但我认为boost属性树驻留在序列化库中......]
它在CentOS中稍微进一步,但在类似的崩溃中结束.
感谢这里的帮助,我们让用户等待修复......
首先.
这不是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, "");
}
Run Code Online (Sandbox Code Playgroud)rapidxml不是Boost的一部分.它在Boost属性树中使用(实现细节)
真正的错误在这里:
static xml_node<>* xmlDocPrepare(char* xml)
{
xml_document<> doc;
..
xml_node<>* father = doc.first_node();
return father;
}
Run Code Online (Sandbox Code Playgroud)
这将返回对(into)本地的引用,但local(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;
}
Run Code Online (Sandbox Code Playgroud)
请注意我如何将76行代码减少到17 :)并减少内存泄漏.
更新这里是一个完全清理的版本--HURRAY - c ++而不是C:看到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;
}
Run Code Online (Sandbox Code Playgroud)
这是删除了调试信息的输出(如/ comment /中所示):
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
Run Code Online (Sandbox Code Playgroud)