Мы используем 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), так и в CentOS (libboost_serialization.so.5), и я получаю аналогичные сбои.
[ Я не уверен, но думаю, что дерево свойств boost находится в библиотеке сериализации... ]
В CentOS это происходит немного дальше, но заканчивается аналогичным сбоем.
Более чем благодарен за помощь, у нас есть пользователи, ожидающие исправления ...