This is an automated email from the git hooks/post-receive script.
sparks pushed a commit to branch master
in repository defensive-coding-guide.
commit 38f436ea1c2633219e6b9f335c61b02aa35ce303
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Wed Apr 24 12:09:44 2013 +0200
Add documentation for parsing XML with Qt
---
defensive-coding/en-US/Tasks/Serialization.xml | 56 ++++++++++
.../Serialization-XML-Qt-NoEntityHandler.xml | 42 ++++++++
.../Serialization-XML-Qt-NoEntityReader.xml | 25 +++++
.../snippets/Serialization-XML-Qt-QDomDocument.xml | 16 +++
defensive-coding/src/.gitignore | 1 +
defensive-coding/src/XML-Parser-Qt.cpp | 120 +++++++++++++++++++++
defensive-coding/src/src.mk | 2 +
7 files changed, 262 insertions(+)
diff --git a/defensive-coding/en-US/Tasks/Serialization.xml
b/defensive-coding/en-US/Tasks/Serialization.xml
index 60427c5..3d4abb1 100644
--- a/defensive-coding/en-US/Tasks/Serialization.xml
+++ b/defensive-coding/en-US/Tasks/Serialization.xml
@@ -255,6 +255,62 @@
</para>
</section>
+ <section id="sect-Defensive_Coding-Tasks-Serialization-Qt">
+ <title>Using Qt for XML parsing</title>
+ <para>
+ The XML component of Qt, QtXml, does not resolve external IDs
+ by default, so it is not requred to prevent such resolution.
+ Internal entities are processed, though. To change that, a
+ custom <literal>QXmlDeclHandler</literal> and
+ <literal>QXmlSimpleReader</literal> subclasses are needed. It
+ is not possible to use the
+ <function>QDomDocument::setContent(const QByteArray
+ &)</function> convenience methods.
+ </para>
+ <para>
+ <xref
linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityHandler"/>
+ shows an entity handler which always returns errors, causing
+ parsing to stop when encountering entity declarations.
+ </para>
+ <example
id="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityHandler">
+ <title>A QtXml entity handler which blocks entity processing</title>
+ <xi:include href="snippets/Serialization-XML-Qt-NoEntityHandler.xml"
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </example>
+ <para>
+ This handler is used in the custom
+ <literal>QXmlReader</literal> subclass in <xref
+ linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityReader"/>.
+ Some parts of QtXml will call the
+ <function>setDeclHandler(QXmlDeclHandler *)</function> method.
+ Consequently, we prevent overriding our custom handler by
+ providing a definition of this method which does nothing. In
+ the constructor, we activate namespace processing; this part
+ may need adjusting.
+ </para>
+ <example
id="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityReader">
+ <title>A QtXml XML reader which blocks entity processing</title>
+ <xi:include href="snippets/Serialization-XML-Qt-NoEntityReader.xml"
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </example>
+ <para>
+ Our <literal>NoEntityReader</literal> class can be used with
+ one of the overloaded
+ <function>QDomDocument::setContent</function> methods.
+ <xref
linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-QDomDocument"/>
+ shows how the <literal>buffer</literal> object (of type
+ <literal>QByteArray</literal>) is wrapped as a
+ <literal>QXmlInputSource</literal>. After calling the
+ <function>setContent</function> method, you should check the
+ return value and report any error.
+ </para>
+ <example
id="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-QDomDocument">
+ <title>Parsing an XML document with QDomDocument, without entity
expansion</title>
+ <xi:include href="snippets/Serialization-XML-Qt-QDomDocument.xml"
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </example>
+ </section>
+
<section
id="sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse">
<title>Using OpenJDK for XML parsing and validation</title>
<para>
diff --git
a/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-NoEntityHandler.xml
b/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-NoEntityHandler.xml
new file mode 100644
index 0000000..3a5ef31
--- /dev/null
+++ b/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-NoEntityHandler.xml
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<!-- Automatically generated file. Do not edit. -->
+<programlisting language="C">
+class NoEntityHandler : public QXmlDeclHandler {
+public:
+ bool attributeDecl(const QString&, const QString&, const
QString&,
+ const QString&, const QString&);
+ bool internalEntityDecl(const QString&, const QString&);
+ bool externalEntityDecl(const QString&, const QString&,
+ const QString&);
+ QString errorString() const;
+};
+
+ bool
+NoEntityHandler::attributeDecl
+ (const QString&, const QString&, const QString&, const
QString&,
+ const QString&)
+{
+ return false;
+}
+
+bool
+NoEntityHandler::internalEntityDecl(const QString&, const QString&)
+{
+ return false;
+}
+
+bool
+NoEntityHandler::externalEntityDecl(const QString&, const QString&,
const
+ QString&)
+{
+ return false;
+}
+
+QString
+NoEntityHandler::errorString() const
+{
+ return "XML declaration not permitted";
+}
+</programlisting>
diff --git a/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-NoEntityReader.xml
b/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-NoEntityReader.xml
new file mode 100644
index 0000000..0a70fa4
--- /dev/null
+++ b/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-NoEntityReader.xml
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<!-- Automatically generated file. Do not edit. -->
+<programlisting language="C">
+class NoEntityReader : public QXmlSimpleReader {
+ NoEntityHandler handler;
+public:
+ NoEntityReader();
+ void setDeclHandler(QXmlDeclHandler *);
+};
+
+ NoEntityReader::NoEntityReader()
+{
+ QXmlSimpleReader::setDeclHandler(&handler);
+
setFeature("http://xml.org/sax/features/namespaces", true);
+
setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+ }
+
+void
+NoEntityReader::setDeclHandler(QXmlDeclHandler *)
+{
+ // Ignore the handler which was passed in.
+}
+</programlisting>
diff --git a/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-QDomDocument.xml
b/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-QDomDocument.xml
new file mode 100644
index 0000000..ff0e056
--- /dev/null
+++ b/defensive-coding/en-US/Tasks/snippets/Serialization-XML-Qt-QDomDocument.xml
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<!-- Automatically generated file. Do not edit. -->
+<programlisting language="C">
+NoEntityReader reader;
+QBuffer buffer(&data);
+buffer.open(QIODevice::ReadOnly);
+QXmlInputSource source(&buffer);
+QDomDocument doc;
+QString errorMsg;
+int errorLine;
+int errorColumn;
+bool okay = doc.setContent
+ (&source, &reader, &errorMsg, &errorLine,
&errorColumn);
+</programlisting>
diff --git a/defensive-coding/src/.gitignore b/defensive-coding/src/.gitignore
index 2f86977..4adbfe5 100644
--- a/defensive-coding/src/.gitignore
+++ b/defensive-coding/src/.gitignore
@@ -3,5 +3,6 @@
/TLS-Client-NSS
/TLS-Client-OpenSSL
/XML-Parser-Expat
+/XML-Parser-Qt
*.class
*.o
diff --git a/defensive-coding/src/XML-Parser-Qt.cpp
b/defensive-coding/src/XML-Parser-Qt.cpp
new file mode 100644
index 0000000..e4c970e
--- /dev/null
+++ b/defensive-coding/src/XML-Parser-Qt.cpp
@@ -0,0 +1,120 @@
+#include <QtCore/QBuffer>
+#include <QtCore/QByteArray>
+#include <QtCore/QFile>
+#include <QtXml/QDomDocument>
+#include <QtXml/QXmlSimpleReader>
+
+#include <stdio.h>
+
+namespace {
+ //+ Tasks Serialization-XML-Qt-NoEntityHandler
+ class NoEntityHandler : public QXmlDeclHandler {
+ public:
+ bool attributeDecl(const QString&, const QString&, const QString&,
+ const QString&, const QString&);
+ bool internalEntityDecl(const QString&, const QString&);
+ bool externalEntityDecl(const QString&, const QString&,
+ const QString&);
+ QString errorString() const;
+ };
+
+ bool
+ NoEntityHandler::attributeDecl
+ (const QString&, const QString&, const QString&, const QString&,
+ const QString&)
+ {
+ return false;
+ }
+
+ bool
+ NoEntityHandler::internalEntityDecl(const QString&, const QString&)
+ {
+ return false;
+ }
+
+ bool
+ NoEntityHandler::externalEntityDecl(const QString&, const QString&, const
+ QString&)
+ {
+ return false;
+ }
+
+ QString
+ NoEntityHandler::errorString() const
+ {
+ return "XML declaration not permitted";
+ }
+ //-
+
+ //+ Tasks Serialization-XML-Qt-NoEntityReader
+ class NoEntityReader : public QXmlSimpleReader {
+ NoEntityHandler handler;
+ public:
+ NoEntityReader();
+ void setDeclHandler(QXmlDeclHandler *);
+ };
+
+ NoEntityReader::NoEntityReader()
+ {
+ QXmlSimpleReader::setDeclHandler(&handler);
+
setFeature("http://xml.org/sax/features/namespaces", true);
+
setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+ }
+
+ void
+ NoEntityReader::setDeclHandler(QXmlDeclHandler *)
+ {
+ // Ignore the handler which was passed in.
+ }
+ //-
+}
+
+
+int
+main(int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s XML-FILE\n", argv[0]);
+ return 1;
+ }
+
+ QByteArray data;
+ {
+ QFile f(argv[1]);
+ if (!f.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "error: could not open file: %s\n", argv[1]);
+ return 1;
+ }
+ data = f.readAll();
+ if (f.error()) {
+ fprintf(stderr, "error: could not read file: %s\n", argv[1]);
+ return 1;
+ }
+ }
+
+ //+ Tasks Serialization-XML-Qt-QDomDocument
+ NoEntityReader reader;
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ QXmlInputSource source(&buffer);
+ QDomDocument doc;
+ QString errorMsg;
+ int errorLine;
+ int errorColumn;
+ bool okay = doc.setContent
+ (&source, &reader, &errorMsg, &errorLine, &errorColumn);
+ //-
+ if (!okay) {
+ fprintf(stderr, "%d:%d: %s\n", errorLine, errorColumn,
+ errorMsg.toUtf8().constData());
+ return 1;
+ }
+
+ data = doc.toByteArray(1);
+ if (fwrite(data.constData(), data.size(), 1, stdout) != 1) {
+ perror("fwrite");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/defensive-coding/src/src.mk b/defensive-coding/src/src.mk
index 4212094..f2eac6f 100644
--- a/defensive-coding/src/src.mk
+++ b/defensive-coding/src/src.mk
@@ -28,6 +28,8 @@ CFLAGS_TLS-Client-NSS = -I/usr/include/nspr4 -I/usr/include/nss3
LIBS_TLS-Client-NSS = -lnss3 -lnspr4 -lssl3
compile_and_link += XML-Parser-Expat
LIBS_XML-Parser-Expat = -lexpat
+compile_and_link += XML-Parser-Qt
+LIBS_XML-Parser-Qt = -lQtCore -lQtXml
# Define preprocessor symbols if certain functions exist.
CHECK_FUNCTION = crypto/X509_check_host/-DHAVE_X509_CHECK_HOST \
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.