PDA

View Full Version : Infinite loop in QXmlSchemaValidator::validate()?



TropicalPenguin
9th November 2010, 15:09
Using the following schema definition


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">

<xs:simpleType name="nonEmptyElement">

<xs:restriction base="xs:string">

<xs:minLength value="1"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="Alphanumeric">

<xs:restriction base="nonEmptyElement">

<xs:pattern value="[a-z A-Z0-9]*"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="nameType">

<xs:restriction base="nonEmptyElement"/>

</xs:simpleType>

<xs:simpleType name="shortnameType">

<xs:restriction base="Alphanumeric">

<xs:maxLength value="4096"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="developerType">

<xs:restriction base="nonEmptyElement"/>

</xs:simpleType>

<xs:simpleType name="publisherType">

<xs:restriction base="nonEmptyElement"/>

</xs:simpleType>

<xs:simpleType name="versionType">

<xs:restriction base="nonEmptyElement"/>

</xs:simpleType>

<xs:simpleType name="genreType">

<xs:restriction base="nonEmptyElement"/>

</xs:simpleType>

<xs:simpleType name="licenseType">

<xs:restriction base="nonEmptyElement">

<xs:maxLength value="4096"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="installerType">

<xs:restriction base="nonEmptyElement">

<xs:maxLength value="4096"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="childType">

<xs:restriction base="nonEmptyElement">

<xs:maxLength value="4096"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="iconPathType">

<xs:restriction base="xs:string">

<xs:maxLength value="4096"/>

<xs:minLength value="4096"/>

</xs:restriction>

</xs:simpleType>

<xs:complexType name="iconType">

<xs:simpleContent>

<xs:extension base="iconPathType">

<xs:attribute name="height" type="xs:integer"/>

<xs:attribute name="width" type="xs:integer"/>

</xs:extension>

</xs:simpleContent>

</xs:complexType>

<xs:complexType name="metaType">

<xs:all>

<xs:element name="name" type="nameType" nillable="false" minOccurs="1" maxOccurs="1"/>

<xs:element name="shortname" type="shortnameType" nillable="false" minOccurs="1" maxOccurs="1"/>

<xs:element name="developer" type="developerType" nillable="false" minOccurs="1" maxOccurs="1"/>

<xs:element name="publisher" type="publisherType" nillable="false" minOccurs="0" maxOccurs="1"/>

<xs:element name="version" type="versionType" nillable="false" minOccurs="1" maxOccurs="1"/>

<xs:element name="genre" type="genreType" nillable="false" minOccurs="0"/>

<xs:element name="summary" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>

<xs:element name="description" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>

<xs:element name="icon" type="iconType" nillable="false" minOccurs="0"/>

<xs:element name="license" type="licenseType" nillable="false" minOccurs="0" maxOccurs="1"/>

<xs:element name="installer" type="installerType" minOccurs="1" maxOccurs="1"/>

<xs:element name="child" type="childType" minOccurs="0"/>

</xs:all>

</xs:complexType>

<xs:element name="meta" type="metaType">

</xs:element>

</xs:schema>

In both the xmlpatterns/schema example that comes with the Qt examples (by replacing one of the included - and note, working - schemas), and this little test program


#include <QtXmlPatterns>

#include <iostream>

class MessageHandler : public QAbstractMessageHandler
{
public:
MessageHandler()
: QAbstractMessageHandler(0)
{
}

QString statusMessage() const
{
return m_description;
}

int line() const
{
return m_sourceLocation.line();
}

int column() const
{
return m_sourceLocation.column();
}

protected:
virtual void handleMessage(QtMsgType type, const QString &description,
const QUrl &identifier, const QSourceLocation &sourceLocation)
{
Q_UNUSED(type);
Q_UNUSED(identifier);

m_messageType = type;
m_description = description;
m_sourceLocation = sourceLocation;

std::cerr << m_description.toUtf8().data() << ", " << m_sourceLocation.line() << std::endl;
}

private:
QtMsgType m_messageType;
QString m_description;
QSourceLocation m_sourceLocation;
};

int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);

QFile schemaFile("metadata.xsd");
schemaFile.open(QIODevice::ReadOnly);

const QString schemaText(QString::fromUtf8(schemaFile.readAll()) );

QFile instanceFile("test.xml");
instanceFile.open(QIODevice::ReadOnly);
const QString instanceText(QString::fromUtf8(instanceFile.readAl l()));

const QByteArray schemaData = schemaText.toUtf8();
const QByteArray instanceData = instanceText.toUtf8();

QXmlSchema schema;
MessageHandler messageHandler;
schema.setMessageHandler(&messageHandler);
schema.load(schemaData);

bool errorOccurred = false;
if (!schema.isValid()) {
std::cerr << "Schema invalid." << std::endl;
} else {
std::cerr << "Schema is valid, proceeding" << std::endl;
QXmlSchemaValidator validator(schema);
std::cerr << "Created validator" << std::endl;
if (!validator.validate(instanceData))
std::cerr << "Failed validation" << std::endl;
else
std::cerr << "Validated." << std::endl;
}

return app.exec();
}


// It seems to encounter an infinite loop on the line


if (!validator.validate(instanceData))

If I make the schema invalid by (for example) setting the 'mixed' attribute
on the complexType element that contains simpleContent (iconType), then the
program properly runs saying "Schema Invalid".

It happens with the following XML data, but I'm not sure how much that
should make a difference:


<?xml version="1.0" encoding="utf-8" ?>
<meta>
<shortname>foo</shortname>
<installer>install/fooinstall.xml</installer>
<name>Foo</name>
<version>0.1</version>
<license>licenses/license.txt</license>
<developer>Quixote</developer>
<description>ABC</description>
<child>children/bar.xml</child>
</meta>

Any ideas?

EDIT: The kernel also kills the xmlpatternsvalidator command-line app that comes with the 'qt4-dev-tools' package under Ubuntu when it tries to validate that XML against the schema, too.