summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Wicking <paul.wicking@qt.io>2023-04-07 08:30:54 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-04-07 15:52:05 +0000
commit594d381e65de3cb02631997138dbae6d3b9886a0 (patch)
tree7e9e95cd4a82feb3393f4dc8c8bc501a072c0b3a
parentab395e5e4ae90e2206925437c01f65b770ef6fce (diff)
downloadqttools-594d381e65de3cb02631997138dbae6d3b9886a0.tar.gz
QDoc: Prevent crash in WebXMLGenerator
`WebXMLGenerator::startLink` is responsible for writing the WebXML tags for links. The method takes a pointer to `Atom`, from which a string is obtained for use in parts of the output. In most locations, the callee pre-qualifies the validity of the pointer it passes to the method (e.g. `if (atom) startLink([...]`). However, there's an exception to this in `WebXMLGenerator::generateAnnotatedList`, which calls `Text::firstAtom()` -- that may return `nullptr` -- in the call to `startLink`. This is considered a valid use-case that occurs when there's only title/meta commands and no body in the documentation. In such a case, or if the string obtained from `Atom::string()` is empty, `WebXMLGenerator::startLink` is designed to fall back to the full name of the `Node` being processed. However, in the case when generating a link for an example, `Generator::exampleFileTitle()` is called to obtain a file name for the example, and the `Atom*` is dereferenced to obtain a string is input for the latter method. At that point, the `Atom*` may be an unguarded null pointer. This change updates the generatedOutput test for QDoc by adding a minimal documentation project that serves as means to reproduce a bug that was observed in Qt3D, and fixes the bug in QDoc. The documentation project is designed such that the preconditions outlined in the first paragraph are met; that is to say, the structure of the documentation is such that, for an `Atom` that's constructed while generating the documentation set, `Atom::firstAtom()` is going to return a null pointer. The change to the test serves to validate the bug fix as well as to guard for future regressions. Avoid the crash that would occur when dereferencing this null pointer in `WebXMLGenerator::startLink` by checking the validity of the `Atom*` before dereferencing it to obtain a string used as file title when generating a link for an example. Fixes: QTBUG-112641 Change-Id: I3633e5473b60013968becac4cd7bdacdbbdcb9ff Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io> (cherry picked from commit f8d73cf765c9c81d195ccd7e5f4f50574d82e859) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/qdoc/webxmlgenerator.cpp2
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/illformatted-examples.webxml31
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation-someexample-example.webxml8
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index13
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted-examples.qdoc17
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf12
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/some_example.qdoc8
-rw-r--r--tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp9
8 files changed, 99 insertions, 1 deletions
diff --git a/src/qdoc/webxmlgenerator.cpp b/src/qdoc/webxmlgenerator.cpp
index 79a58df4b..974156bb1 100644
--- a/src/qdoc/webxmlgenerator.cpp
+++ b/src/qdoc/webxmlgenerator.cpp
@@ -794,7 +794,7 @@ void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom, cons
break;
case Node::Example: {
const auto *en = static_cast<const ExampleNode *>(node);
- QString fileTitle = exampleFileTitle(en, atom->string());
+ const QString fileTitle = atom ? exampleFileTitle(en, atom->string()) : QString();
if (!fileTitle.isEmpty()) {
writer.writeAttribute("page", fileTitle);
break;
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/illformatted-examples.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatted-examples.webxml
new file mode 100644
index 000000000..b49d1b297
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatted-examples.webxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<WebXML>
+ <document>
+ <page name="illformatted-examples.html" href="illformatted-examples.html" status="active" location="illformatted-examples.qdoc" documented="true" groups="all-examples" subtype="page" title="Test generated output for illformatted examples" fulltitle="Test generated output for illformatted examples" subtitle="" brief="Demonstrate correctness for example generation">
+ <contents name="qml-examples" title="QML Examples" level="1"/>
+ <contents name="c-examples" title="C++ Examples" level="1"/>
+ <description>
+ <brief>Demonstrate correctness for example generation.</brief>
+ <para>This test includes the following examples:</para>
+ <section id="qml-examples">
+ <heading level="1">QML Examples</heading>
+ <table width="100%">
+ <row>
+ <item>
+ <para>
+ <link raw="QDoc: some example" href="illformatteddocumentation-someexample-example.html" type="page" page="QDoc: some example"/>
+ </para>
+ </item>
+ <item>
+ <para></para>
+ </item>
+ </row>
+ </table>
+ </section>
+ <section id="c-examples">
+ <heading level="1">C++ Examples</heading>
+ </section>
+ </description>
+ </page>
+ </document>
+</WebXML>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation-someexample-example.webxml b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation-someexample-example.webxml
new file mode 100644
index 000000000..675e3d74f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation-someexample-example.webxml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<WebXML>
+ <document>
+ <page name="someexample" href="illformatteddocumentation-someexample-example.html" status="active" location="some_example.qdoc" documented="true" groups="illformatted-examples-qml" subtype="example" title="QDoc: some example" fulltitle="QDoc: some example" subtitle="">
+ <description/>
+ </page>
+ </document>
+</WebXML>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index
new file mode 100644
index 000000000..eae4c7eda
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/html/illformatteddocumentation.index
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QDOCINDEX>
+<INDEX url="" title="IllformattedDocumentation Reference Documentation" version="" project="IllformattedDocumentation">
+ <namespace name="" status="active" access="public" module="illformatteddocumentation">
+ <page name="someexample" href="illformatteddocumentation-someexample-example.html" status="active" location="some_example.qdoc" documented="true" groups="illformatted-examples-qml" subtype="example" title="QDoc: some example" fulltitle="QDoc: some example" subtitle=""/>
+ <page name="illformatted-examples.html" href="illformatted-examples.html" status="active" location="illformatted-examples.qdoc" documented="true" groups="all-examples" subtype="page" title="Test generated output for illformatted examples" fulltitle="Test generated output for illformatted examples" subtitle="" brief="Demonstrate correctness for example generation">
+ <contents name="qml-examples" title="QML Examples" level="1"/>
+ <contents name="c-examples" title="C++ Examples" level="1"/>
+ </page>
+ <group name="all-examples" href="all-examples.html" status="internal" seen="false" title=""/>
+ <group name="illformatted-examples-qml" href="illformatted-examples-qml.html" status="internal" seen="false" title=""/>
+ </namespace>
+</INDEX>
diff --git a/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted-examples.qdoc b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted-examples.qdoc
new file mode 100644
index 000000000..5bfa9e7f6
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted-examples.qdoc
@@ -0,0 +1,17 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page illformatted-examples.html
+ \ingroup all-examples
+ \title Test generated output for illformatted examples
+ \brief Demonstrate correctness for example generation.
+
+ This test includes the following examples:
+
+ \section1 QML Examples
+ \annotatedlist illformatted-examples-qml
+
+ \section1 C++ Examples
+ \annotatedlist illformatted-examples-cpp
+*/
diff --git a/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf
new file mode 100644
index 000000000..307dd36b1
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/illformatted_documentation.qdocconf
@@ -0,0 +1,12 @@
+include(../configs/config.qdocconf)
+project = IllformattedDocumentation
+
+headerdirs = .
+sourcedirs = .
+exampledirs = .
+
+outputformats = WebXML
+WebXML.quotinginformation = true
+WebXML.nosubdirs = true
+
+warninglimit = 3 # The broken example generates three warnings
diff --git a/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/some_example.qdoc b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/some_example.qdoc
new file mode 100644
index 000000000..a64605b87
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/illformatted_documentation/some_example.qdoc
@@ -0,0 +1,8 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example someexample
+ \title QDoc: some example
+ \ingroup illformatted-examples-qml
+*/
diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
index e8aadeffd..041b90cb1 100644
--- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
+++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
@@ -27,6 +27,7 @@ private slots:
void webXmlFromCpp();
void webXmlFromQml();
void webXmlFromCppBug80259();
+ void illformated_documentation_caused_qtbug112641();
// DocBook generator
void docBookFromQDocFile();
@@ -291,6 +292,14 @@ void tst_generatedOutput::webXmlFromCppBug80259()
"html/index.webxml");
}
+void tst_generatedOutput::illformated_documentation_caused_qtbug112641()
+{
+ testAndCompare("testdata/illformatted_documentation/illformatted_documentation.qdocconf",
+ "html/illformatted-examples.webxml "
+ "html/illformatteddocumentation-someexample-example.webxml "
+ "html/illformatteddocumentation.index");
+}
+
void tst_generatedOutput::docBookFromQDocFile()
{
testAndCompare("testdata/configs/docbook_test.qdocconf",