我们在pub/sub代理实现中使用boost/rapidxml进行XML解析,对于某个XML有效负载,代理崩溃了.
为了消除尽可能多的变量,我实现了一个只执行XML解析的简短测试程序,崩溃类似.
我的简短测试程序在这里找到:
#include// printf #include // read #include // open #include // open #include // open #include // errno #include // 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)和CentOS(libboost_serialization.so.5)中都试过了,我遇到了类似的崩溃.
[我不确定,但我认为boost属性树驻留在序列化库中......]
它在CentOS中稍微进一步,但在类似的崩溃中结束.
感谢这里的帮助,我们让用户等待修复......
首先.
> OMG <那里有相当多的代码 - 很遗憾地说,或许直言不讳.
这不是c ++!更换你的整个main
使用
int main(int argc, char* argv[]) { std::ifstream ifs(argc>1? argv[1] : "input.txt"); std::string buf(std::istreambuf_iterator(ifs), {}); xml_node<>* father = xmlDocPrepare(&buf[0]); xmlTreePresent(father, ""); }
rapidxml不是Boost的一部分.它在Boost属性树中使用(实现细节)
Boost Property Tree是它自己的库,与Boost Serialization无关(这意味着您不必链接到共享库)
真正的错误在这里:
static xml_node<>* xmlDocPrepare(char* xml) { xml_document<> doc; .. xml_node<>* father = doc.first_node(); return father; }
这将返回对(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(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:看到Live On Coliru,它可以看到解析样本XML,但删除了可忽略的空格,这样你就可以更好地看到输出.
当然,它也适用于'漂亮'的xml.
#include#include #include #include 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 (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; }
这是删除了调试信息的输出(如/ 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