2 Commits

Author SHA1 Message Date
Oleg Shparber 0dfb36c837 build(cmake): set CMP0218 to NEW (#1952) 2026-08-14 04:47:44 +03:00
Oleg Shparber ae4086f7a0 fix(util,registry): tolerate broken Info.plist (#1951)
Fixes #1949.
2026-08-13 22:24:25 +03:00
5 changed files with 131 additions and 3 deletions
+7 -1
View File
@@ -9,9 +9,15 @@ setup_homebrew()
# CMake options.
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_ERROR_DEPRECATED TRUE)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
if(POLICY CMP0218)
cmake_policy(SET CMP0218 NEW)
cmake_diagnostic(SET CMD_DEPRECATED FATAL_ERROR)
else()
set(CMAKE_ERROR_DEPRECATED TRUE)
endif()
# VERSION is the next development version, bumped automatically after each release.
# ZEAL_RELEASE_VERSION is the last released version, updated by `just release-prepare`.
# When both match, the build is treated as a release; otherwise it's a dev build.
-1
View File
@@ -104,7 +104,6 @@ Docset::Docset(QString path)
if (plist.hasError()) {
qCWarning(log, "Failed to parse 'Info.plist' for docset at '%s'.", qPrintable(m_path));
return;
}
if (m_name.isEmpty()) {
+2 -1
View File
@@ -22,7 +22,8 @@ bool Plist::read(const QString &fileName)
return false;
}
QXmlStreamReader xml(&file);
// Some docsets ship an Info.plist with whitespace before the XML declaration.
QXmlStreamReader xml(file.readAll().trimmed());
while (!xml.atEnd()) {
const QXmlStreamReader::TokenType token = xml.readNext();
+6
View File
@@ -6,6 +6,12 @@ target_link_libraries(fuzzy_test PRIVATE Util Qt6::Test)
zeal_add_test(fuzzy_test)
# Property list tests
add_executable(plist_test plist_test.cpp)
target_link_libraries(plist_test PRIVATE Util Qt6::Test)
zeal_add_test(plist_test)
# SQLite Statement tests
add_executable(statement_test statement_test.cpp)
target_link_libraries(statement_test PRIVATE Util Qt6::Test)
+116
View File
@@ -0,0 +1,116 @@
// Copyright (C) Oleg Shparber, et al. <https://zealdocs.org>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "../plist.h"
#include <QtTest>
using namespace Zeal::Util;
class PlistTest : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void testReadsKeys();
void testLeadingNewline();
void testLeadingIndentation();
void testByteOrderMark();
void testMalformedContent();
void testMissingFile();
private:
QString writePlist(const QByteArray &data);
QTemporaryDir m_dir;
int m_counter = 0;
};
namespace {
const QByteArray Body = QByteArrayLiteral("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\""
" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
" <dict>\n"
" <key>CFBundleName</key>\n"
" <string>Android KTX</string>\n"
" <key>isDashDocset</key>\n"
" <true/>\n"
" <key>isJavaScriptEnabled</key>\n"
" <false/>\n"
" </dict>\n"
"</plist>\n");
} // namespace
QString PlistTest::writePlist(const QByteArray &data)
{
const QString path = m_dir.filePath(QStringLiteral("Info%1.plist").arg(++m_counter));
QFile file(path);
if (!file.open(QIODevice::WriteOnly) || file.write(data) != data.size()) {
return {};
}
return path;
}
void PlistTest::initTestCase()
{
QVERIFY(m_dir.isValid());
}
void PlistTest::testReadsKeys()
{
Plist plist;
QVERIFY(plist.read(writePlist(Body)));
QVERIFY(!plist.hasError());
QCOMPARE(plist.value(QStringLiteral("CFBundleName")), QVariant(QStringLiteral("Android KTX")));
QCOMPARE(plist.value(QStringLiteral("isDashDocset")), QVariant(true));
QCOMPARE(plist.value(QStringLiteral("isJavaScriptEnabled")), QVariant(false));
}
// See: https://github.com/zealdocs/zeal/issues/1949
void PlistTest::testLeadingNewline()
{
Plist plist;
QVERIFY(plist.read(writePlist(QByteArrayLiteral("\n") + Body)));
QVERIFY(!plist.hasError());
QCOMPARE(plist[QStringLiteral("CFBundleName")].toString(), QStringLiteral("Android KTX"));
}
void PlistTest::testLeadingIndentation()
{
Plist plist;
QVERIFY(plist.read(writePlist(QByteArrayLiteral("\n ") + Body)));
QVERIFY(!plist.hasError());
QCOMPARE(plist[QStringLiteral("CFBundleName")].toString(), QStringLiteral("Android KTX"));
}
void PlistTest::testByteOrderMark()
{
Plist plist;
QVERIFY(plist.read(writePlist(QByteArrayLiteral("\xEF\xBB\xBF") + Body)));
QVERIFY(!plist.hasError());
QCOMPARE(plist[QStringLiteral("CFBundleName")].toString(), QStringLiteral("Android KTX"));
}
void PlistTest::testMalformedContent()
{
const QString path = writePlist(QByteArrayLiteral("<plist><dict><key>CFBundleName</key>"));
QVERIFY(!path.isEmpty());
Plist plist;
QVERIFY(!plist.read(path));
QVERIFY(plist.hasError());
}
void PlistTest::testMissingFile()
{
Plist plist;
QVERIFY(!plist.read(m_dir.filePath(QStringLiteral("Missing.plist"))));
QVERIFY(plist.hasError());
}
QTEST_GUILESS_MAIN(PlistTest)
#include "plist_test.moc"