From d14eec536da0504170c14bdfc5a5d7295032ea3f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 4 Mar 2024 13:30:14 -0700 Subject: [PATCH] QTextMarkdownImporter::import(): don't crash if file has only yaml If a markdown file has FrontMatter, we look for the end of the newlines after the `---` marker to begin parsing the actual markdown. But check bounds in case the file contains only front matter and not markdown. Fixes: QTBUG-122982 Change-Id: I09c4ae90c47ebd84877738aecc1d1cad0b0bfca2 Reviewed-by: Anton Kudryavtsev Reviewed-by: Axel Spoerl --- src/gui/text/qtextmarkdownimporter.cpp | 2 +- .../qtextmarkdownimporter/data/yaml-only.md | 6 ++++++ .../tst_qtextmarkdownimporter.cpp | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp index c9aac01fa9..511c0883a4 100644 --- a/src/gui/text/qtextmarkdownimporter.cpp +++ b/src/gui/text/qtextmarkdownimporter.cpp @@ -148,7 +148,7 @@ void QTextMarkdownImporter::import(const QString &markdown) ++firstLinePos; QByteArray frontMatter = md.sliced(firstLinePos, endMarkerPos - firstLinePos); firstLinePos = endMarkerPos + 4; // first line of markdown after yaml - while (md.at(firstLinePos) == '\n' || md.at(firstLinePos) == '\r') + while (md.size() > firstLinePos && (md.at(firstLinePos) == '\n' || md.at(firstLinePos) == '\r')) ++firstLinePos; md.remove(0, firstLinePos); doc->setMetaInformation(QTextDocument::FrontMatter, QString::fromUtf8(frontMatter)); diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md b/tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md new file mode 100644 index 0000000000..1eff4db37f --- /dev/null +++ b/tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md @@ -0,0 +1,6 @@ +--- +name: "Space" +title: "Outer space" +keywords: + - astronomy +--- diff --git a/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp b/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp index 53fa827446..645dd9c102 100644 --- a/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp +++ b/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp @@ -44,6 +44,7 @@ private slots: void pathological(); void fencedCodeBlocks_data(); void fencedCodeBlocks(); + void frontMatter_data(); void frontMatter(); private: @@ -634,9 +635,21 @@ void tst_QTextMarkdownImporter::fencedCodeBlocks() QCOMPARE(doc.toMarkdown(), rewrite); } +void tst_QTextMarkdownImporter::frontMatter_data() +{ + QTest::addColumn("inputFile"); + QTest::addColumn("expectedBlockCount"); + + QTest::newRow("yaml + markdown") << QFINDTESTDATA("data/yaml.md") << 1; + QTest::newRow("yaml only") << QFINDTESTDATA("data/yaml-only.md") << 0; +} + void tst_QTextMarkdownImporter::frontMatter() { - QFile f(QFINDTESTDATA("data/yaml.md")); + QFETCH(QString, inputFile); + QFETCH(int, expectedBlockCount); + + QFile f(inputFile); QVERIFY(f.open(QFile::ReadOnly | QIODevice::Text)); QString md = QString::fromUtf8(f.readAll()); f.close(); @@ -652,7 +665,7 @@ void tst_QTextMarkdownImporter::frontMatter() if (!iterator.currentBlock().text().isEmpty()) ++blockCount; } - QCOMPARE(blockCount, 1); // yaml is not part of the markdown text + QCOMPARE(blockCount, expectedBlockCount); // yaml is not part of the markdown text QCOMPARE(doc.metaInformation(QTextDocument::FrontMatter), yaml); // without fences }