diff options
author | Paul Wicking <paul.wicking@qt.io> | 2023-04-07 08:30:54 +0200 |
---|---|---|
committer | Paul Wicking <paul.wicking@qt.io> | 2023-04-07 17:29:44 +0200 |
commit | f8d73cf765c9c81d195ccd7e5f4f50574d82e859 (patch) | |
tree | 28cd69eb96bd6edea862da306c91a741c284be8b /tests | |
parent | 1c7cca268a06b5a3c34765e1e0e4dd1b020f3302 (diff) | |
download | qttools-f8d73cf765c9c81d195ccd7e5f4f50574d82e859.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
Pick-to: 6.5
Change-Id: I3633e5473b60013968becac4cd7bdacdbbdcb9ff
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
Diffstat (limited to 'tests')
7 files changed, 98 insertions, 0 deletions
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 16bb7dc7b..6b48d914d 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", |