Qt QXmlStreamReader Нарушение прав доступа

Я использую Qt 5.11.1 (MSVSC2015 32bit) и QtCreator 4.6.2.
У меня проблемы с анализом XML с помощью QXmlStreamReader. Код написан на основе Пример Qt.
Когда мой код выполняется, он вызывает нарушение доступа в QIODevice.cpp в функции checkWarnMessage.
это образ показывает стек вызовов и точную строку, где произошло нарушение доступа.

Фактический XML более сложен и имеет вложенные элементы. Функции, которые анализируют XML, реализованы так же, как и функция void XbelReader :: readXBEL () из примера Qt (на основе имени элемента для анализа этого элемента вызывается соответствующая функция). Но на этом простом примере мне удалось воспроизвести имеющуюся у меня проблему в реальном решении.

XML это:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<element1>1</element1>
<element2>2</element2>
<element3>3</element3>
<element4>4</element4>
<element5>5</element5>
<element6>6</element6>
</root>

Код, который анализирует этот XML:

#include <string>
#include <stdexcept>
#include <iostream>

#include <QCoreApplication>
#include <QXmlStreamReader>
#include <QFile>
#include <QString>

#define ASSERT_ELEMENT_NAME(NAME) Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == NAME);

using namespace std;

void OpenFile(const QString& fileName, QXmlStreamReader& xmlReader)
{
QFile configFile(fileName);
if (configFile.open(QFile::ReadOnly | QFile::Text) == false)
throw runtime_error(string("Failed to open file: ") + configFile.errorString().toStdString());

xmlReader.setDevice(&configFile);
if (xmlReader.readNextStartElement() == false)
throw runtime_error("File does not have root element");

if (xmlReader.name() != "root")
throw runtime_error("File has invalid root element");
}

void ParseElement1(QXmlStreamReader& xmlReader)
{
ASSERT_ELEMENT_NAME("element1");

auto text = xmlReader.readElementText().trimmed();
auto isOk = false;
auto value = text.toInt(&isOk);

if (isOk == false)
throw runtime_error(string("invalid value: ") + text.toStdString());
else
cout << "element1: " << value << endl;
}

void ParseElement2(QXmlStreamReader& xmlReader)
{
ASSERT_ELEMENT_NAME("element2");

auto text = xmlReader.readElementText().trimmed();
auto isOk = false;
auto value = text.toInt(&isOk);

if (isOk == false)
throw runtime_error(string("invalid value: ") + text.toStdString());
else
cout << "element2: " << value << endl;
}

int main()
{
QXmlStreamReader xmlReader;

OpenFile("config.xml", xmlReader);

while(xmlReader.readNextStartElement())
{
if(xmlReader.name() == "element1")
ParseElement1(xmlReader);
if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
else
xmlReader.skipCurrentElement();
}
}

Если я прокомментирую две строки в основной функции:

        if(xmlReader.name() == "element2")
ParseElement2(xmlReader);

нарушения доступа не происходит.

Я действительно не могу понять, что я делаю не так. Или в QXmlStreamReader есть ошибка? Я думаю, что даже если я что-то сделал не так, нарушение прав доступа не должно происходить в библиотеке Qt.

Весь проект (XmlParser.pro, main.cpp и config.xml) можно загрузить из этого ссылка на сайт

РЕДАКТИРОВАТЬ

Я исправил свой пример, как предложил Мантан, и он сработал, как и ожидалось. Я добавил еще одну вещь в XML. Я добавил большой многострочный комментарий перед element1. Сам комментарий имеет 8019 символов, включая пробельные символы, тогда как весь XML-файл содержит 8266 символов.

XML теперь выглядит

<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, co
-->
<element1>1</element1>
<element2>2</element2>
<element3>3</element3>
<element4>4</element4>
<element5>5</element5>
<element6>6</element6>
</root>

Я проверил, что XML допустим в Notepad ++ с плагином XML Tools, а также в xmlvalidation.xml. Когда я выполняю фиксированный пример с новым XML, у меня снова возникает нарушение прав доступа в том же месте, что и на ранее связанном изображении.

Теперь, если я удаляю последний символ «o» из комментария в XML (или любой другой символ из комментария, или, например, «6» из текста элемента 6, или фактически любой символ из XML, сохраняя XML действительным), пример выполнено успешно. И это моя изначальная проблема. У меня есть много комментариев в моем исходном файле XML, в результате чего размер файла превышает 8 КБ. Пока что в качестве обходного пути я удаляю комментарии, чтобы избежать нарушения прав доступа.

Мне не ясно, как длина комментария (или файла) вызывает нарушение прав доступа.

Весь проект можно скачать с этого ссылка на сайт

4

Решение

Проблема в цикле. Обновите это как ниже.

while(xmlReader.readNextStartElement())
{
if(xmlReader.name() == "element1")
ParseElement1(xmlReader);
else if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
else
xmlReader.skipCurrentElement();
}

В вашем коде первый элемент имеет тип ‘element1’, затем сначала он обрабатывается (с первым if) и они снова дошли до else где это попытаться пропустить это, которые вызывают проблемы.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]