Skip to content

Commit 22c2992

Browse files
committed
Fix potential crash if section titles contain unsupported markup
1 parent 2271493 commit 22c2992

File tree

2 files changed

+51
-18
lines changed

2 files changed

+51
-18
lines changed

src/docnode.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,15 @@ DocRef::DocRef(DocParser *parser,DocNodeVariant *parent,const QCString &target,c
777777
qPrint(target));
778778
}
779779

780+
void DocNodeList::move_append(DocNodeList &elements)
781+
{
782+
for (auto &&elem : elements)
783+
{
784+
emplace_back(std::move(elem));
785+
}
786+
elements.clear();
787+
}
788+
780789
static void flattenParagraphs(DocNodeVariant *root,DocNodeList &children)
781790
{
782791
DocNodeList newChildren;
@@ -797,6 +806,15 @@ static void flattenParagraphs(DocNodeVariant *root,DocNodeList &children)
797806
for (auto &cn : children)
798807
{
799808
setParent(&cn,root);
809+
// we also need to set the parent for each child of cn, as cn's address may have changed.
810+
auto *innerChildren = ::children(&cn);
811+
if (innerChildren)
812+
{
813+
for (auto &ccn : *innerChildren)
814+
{
815+
setParent(&ccn,&cn);
816+
}
817+
}
800818
}
801819
}
802820

src/docnode.h

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,37 +40,43 @@ class DocParser;
4040
/* 0 */ DN(DocWord) DN_SEP DN(DocLinkedWord) DN_SEP DN(DocURL) DN_SEP DN(DocLineBreak) DN_SEP DN(DocHorRuler) DN_SEP \
4141
/* 5 */ DN(DocAnchor) DN_SEP DN(DocCite) DN_SEP DN(DocStyleChange) DN_SEP DN(DocSymbol) DN_SEP DN(DocEmoji) DN_SEP \
4242
/* 10 */ DN(DocWhiteSpace) DN_SEP DN(DocSeparator) DN_SEP DN(DocVerbatim) DN_SEP DN(DocInclude) DN_SEP DN(DocIncOperator) DN_SEP \
43-
/* 15 */ DN(DocFormula) DN_SEP DN(DocIndexEntry) DN_SEP DN(DocAutoList) DN_SEP DN(DocAutoListItem) DN_SEP DN(DocTitle) DN_SEP \
44-
/* 20 */ DN(DocXRefItem) DN_SEP DN(DocImage) DN_SEP DN(DocDotFile) DN_SEP DN(DocMscFile) DN_SEP DN(DocDiaFile) DN_SEP \
45-
/* 25 */ DN(DocVhdlFlow) DN_SEP DN(DocLink) DN_SEP DN(DocRef) DN_SEP DN(DocInternalRef) DN_SEP DN(DocHRef) DN_SEP \
46-
/* 30 */ DN(DocHtmlHeader) DN_SEP DN(DocHtmlDescTitle) DN_SEP DN(DocHtmlDescList) DN_SEP DN(DocSection) DN_SEP DN(DocSecRefItem) DN_SEP \
47-
/* 35 */ DN(DocSecRefList) DN_SEP DN(DocInternal) DN_SEP DN(DocParBlock) DN_SEP DN(DocSimpleList) DN_SEP DN(DocHtmlList) DN_SEP \
48-
/* 40 */ DN(DocSimpleSect) DN_SEP DN(DocSimpleSectSep) DN_SEP DN(DocParamSect) DN_SEP DN(DocPara) DN_SEP DN(DocParamList) DN_SEP \
49-
/* 45 */ DN(DocSimpleListItem) DN_SEP DN(DocHtmlListItem) DN_SEP DN(DocHtmlDescData) DN_SEP DN(DocHtmlCell) DN_SEP DN(DocHtmlCaption) DN_SEP \
50-
/* 50 */ DN(DocHtmlRow) DN_SEP DN(DocHtmlTable) DN_SEP DN(DocHtmlBlockQuote) DN_SEP DN(DocText) DN_SEP DN(DocRoot) DN_SEP \
51-
/* 55 */ DN(DocHtmlDetails) DN_SEP DN(DocHtmlSummary) \
43+
/* 15 */ DN(DocFormula) DN_SEP DN(DocIndexEntry) DN_SEP DC(DocAutoList) DN_SEP DC(DocAutoListItem) DN_SEP DC(DocTitle) DN_SEP \
44+
/* 20 */ DC(DocXRefItem) DN_SEP DC(DocImage) DN_SEP DC(DocDotFile) DN_SEP DC(DocMscFile) DN_SEP DC(DocDiaFile) DN_SEP \
45+
/* 25 */ DC(DocVhdlFlow) DN_SEP DC(DocLink) DN_SEP DC(DocRef) DN_SEP DC(DocInternalRef) DN_SEP DC(DocHRef) DN_SEP \
46+
/* 30 */ DC(DocHtmlHeader) DN_SEP DC(DocHtmlDescTitle) DN_SEP DC(DocHtmlDescList) DN_SEP DC(DocSection) DN_SEP DC(DocSecRefItem) DN_SEP \
47+
/* 35 */ DC(DocSecRefList) DN_SEP DC(DocInternal) DN_SEP DC(DocParBlock) DN_SEP DC(DocSimpleList) DN_SEP DC(DocHtmlList) DN_SEP \
48+
/* 40 */ DC(DocSimpleSect) DN_SEP DN(DocSimpleSectSep) DN_SEP DC(DocParamSect) DN_SEP DC(DocPara) DN_SEP DN(DocParamList) DN_SEP \
49+
/* 45 */ DN(DocSimpleListItem) DN_SEP DC(DocHtmlListItem) DN_SEP DC(DocHtmlDescData) DN_SEP DC(DocHtmlCell) DN_SEP DC(DocHtmlCaption) DN_SEP \
50+
/* 50 */ DC(DocHtmlRow) DN_SEP DC(DocHtmlTable) DN_SEP DC(DocHtmlBlockQuote) DN_SEP DC(DocText) DN_SEP DC(DocRoot) DN_SEP \
51+
/* 55 */ DC(DocHtmlDetails) DN_SEP DC(DocHtmlSummary) \
5252

5353
// forward declarations
5454
#define DN(x) class x;
55+
#define DC(x) class x;
5556
#define DN_SEP
5657
DOC_NODES
5758
#undef DN
59+
#undef DC
5860
#undef DN_SEP
5961

6062
// define a variant type
6163
#define DN(x) x
64+
#define DC(x) x
6265
#define DN_SEP ,
6366
using DocNodeVariant = std::variant<
6467
DOC_NODES
6568
>;
6669
#undef DN
70+
#undef DC
6771
#undef DN_SEP
6872

6973
// getter functions to return the name of a doc node type
7074
#define DN(x) constexpr const char *docNodeName(const x &/* n */) { return #x; }
75+
#define DC(x) DN(x)
7176
#define DN_SEP
7277
DOC_NODES
7378
#undef DN
79+
#undef DC
7480
#undef DN_SEP
7581

7682
/** Abstract node interface with type information. */
@@ -1294,6 +1300,18 @@ constexpr const DocNodeVariant *parent(const DocNodeVariant *n)
12941300
return n ? std::visit([](auto &&x)->decltype(auto) { return x.parent(); }, *n) : nullptr;
12951301
}
12961302

1303+
constexpr DocNodeList *children(DocNodeVariant *n)
1304+
{
1305+
#define DN(x)
1306+
#define DC(x) { auto *compNode = std::get_if<x>(n); if (compNode) return &compNode->children(); }
1307+
#define DN_SEP
1308+
DOC_NODES
1309+
#undef DN
1310+
#undef DC
1311+
#undef DN_SEP
1312+
return nullptr;
1313+
}
1314+
12971315
namespace details
12981316
{
12991317

@@ -1337,15 +1355,6 @@ inline void DocNodeList::append(Args&&... args)
13371355
std::get_if<T>(&back())->setThisVariant(&back());
13381356
}
13391357

1340-
inline void DocNodeList::move_append(DocNodeList &elements)
1341-
{
1342-
for (auto &&elem : elements)
1343-
{
1344-
emplace_back(std::move(elem));
1345-
}
1346-
elements.clear();
1347-
}
1348-
13491358
template<class T>
13501359
inline T *DocNodeList::get_last()
13511360
{
@@ -1355,27 +1364,33 @@ inline T *DocNodeList::get_last()
13551364
// ---------------- Debug helpers -------------------------------
13561365

13571366
#define DN(x) #x
1367+
#define DC(x) #x
13581368
#define DN_SEP ,
13591369
inline const char *docNodeName(const DocNodeVariant &v)
13601370
{
13611371
static const char *table[] = { DOC_NODES };
13621372
return table[v.index()];
13631373
}
13641374
#undef DN
1375+
#undef DC
13651376
#undef DN_SEP
13661377

13671378
inline void dumpDocNodeSizes()
13681379
{
13691380
#define DN(x) #x
1381+
#define DC(x) #x
13701382
#define DN_SEP ,
13711383
static const char *tableWithNames[] = { DOC_NODES };
13721384
#undef DN
1385+
#undef DC
13731386
#undef DN_SEP
13741387

13751388
#define DN(x) sizeof(x)
1389+
#define DC(x) sizeof(x)
13761390
#define DN_SEP ,
13771391
static size_t tableWithSizes[] = { DOC_NODES };
13781392
#undef DN
1393+
#undef DC
13791394
#undef DN_SEP
13801395

13811396
size_t maxSize=0;

0 commit comments

Comments
 (0)