summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/settings.cpp47
-rw-r--r--tests/auto/installer/settings/data/empty_config.xml3
-rw-r--r--tests/auto/installer/settings/data/full_config.xml171
-rw-r--r--tests/auto/installer/settings/data/minimal_config.xml5
-rw-r--r--tests/auto/installer/settings/data/unknown_element_config.xml6
-rw-r--r--tests/auto/installer/settings/settings.qrc6
-rw-r--r--tests/auto/installer/settings/tst_settings.cpp43
7 files changed, 269 insertions, 12 deletions
diff --git a/src/libs/installer/settings.cpp b/src/libs/installer/settings.cpp
index d52ff2f52..3bf979bee 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -97,12 +97,22 @@ static QSet<Repository> readRepositories(QXmlStreamReader &reader, bool isDefaul
else if (reader.name() == QLatin1String("Enabled"))
repo.setEnabled(bool(reader.readElementText().toInt()));
else
- reader.skipCurrentElement();
+ reader.raiseError(QString::fromLatin1("Unexpected element '%1'.").arg(
+ reader.name().toString()));
+
+ if (!reader.attributes().isEmpty())
+ reader.raiseError(QString::fromLatin1("Unexpected attribute for element '%1'.").arg(
+ reader.name().toString()));
}
set.insert(repo);
} else {
- reader.skipCurrentElement();
+ reader.raiseError(QString::fromLatin1("Unexpected element '%1'.").arg(
+ reader.name().toString()));
}
+
+ if (!reader.attributes().isEmpty())
+ reader.raiseError(QString::fromLatin1("Unexpected attribute for element '%1'.").arg(
+ reader.name().toString()));
}
return set;
}
@@ -121,7 +131,10 @@ static QHash<QString, QVariantHash> readPages(QXmlStreamReader &reader)
while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("Page")) {
QVariantHash pageElements;
- QString pageName = reader.attributes().value(QLatin1String("name")).toString();
+ const QString pageName = reader.attributes().value(QLatin1String("name")).toString();
+ if (pageName.isEmpty())
+ reader.raiseError(QLatin1String("Expected non-empty attribute 'name' for element 'Page'."));
+
while (reader.readNextStartElement()) {
const QString name = reader.name().toString();
if (name == QLatin1String("Title") || name == QLatin1String("SubTitle")) {
@@ -131,6 +144,8 @@ static QHash<QString, QVariantHash> readPages(QXmlStreamReader &reader)
}
}
hash.insert(pageName, pageElements);
+ } else {
+ reader.raiseError(QString::fromLatin1("Unexpected element '%1'.").arg(reader.name().toString()));
}
}
return hash;
@@ -196,8 +211,19 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix)
QXmlStreamReader reader(&file);
if (reader.readNextStartElement()) {
if (reader.name() != QLatin1String("Installer"))
- throw Error(tr("%1 is not valid: Installer root node expected.").arg(path));
+ reader.raiseError(QString::fromLatin1("Unexpected element '%1' as root element.").arg(
+ reader.name().toString()));
}
+ QStringList elementList;
+ elementList << scName << scVersion << scTitle << scPublisher << scProductUrl
+ << scTargetDir << scAdminTargetDir
+ << scIcon << scLogo << scLogoSmall << scWatermark << scBackground
+ << scStartMenuDir << scUninstallerName << scUninstallerIniFile << scRemoveTargetDir
+ << scRunProgram << scRunProgramDescription
+ << scSigningCertificate << scDependsOnLocalInstallerBinary
+ << scAllowSpaceInPath << scAllowNonAsciiCharacters
+ << scRepositorySettingsPageVisible << scTargetConfigurationFile
+ << scRemoteRepositories << scPages;
QStringList blackList;
blackList << scRemoteRepositories << scSigningCertificate << scPages;
@@ -206,6 +232,13 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix)
s.d->m_data.insert(scPrefix, prefix);
while (reader.readNextStartElement()) {
const QString name = reader.name().toString();
+
+ if (!elementList.contains(name))
+ reader.raiseError(QString::fromLatin1("Unexpected element '%1'.").arg(name));
+
+ if (!reader.attributes().isEmpty())
+ reader.raiseError(QString::fromLatin1("Unexpected attribute for element '%1'.").arg(name));
+
if (blackList.contains(name)) {
if (name == scSigningCertificate)
s.d->m_data.insertMulti(name, s.d->makeAbsolutePath(reader.readElementText()));
@@ -221,14 +254,14 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix)
}
} else {
if (s.d->m_data.contains(name))
- throw Error(tr("Multiple %1 elements found, but only one allowed.").arg(name));
+ reader.raiseError(QString::fromLatin1("Element '%1' has been defined before.").arg(name));
s.d->m_data.insert(name, reader.readElementText(QXmlStreamReader::SkipChildElements));
}
}
if (reader.error() != QXmlStreamReader::NoError) {
- throw Error(QString::fromLatin1("Xml parse error in %1: %2 Line: %3, Column: %4").arg(path)
- .arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()));
+ throw Error(QString::fromLatin1("Error in %1, line %2, column %3: %4")
+ .arg(path).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
}
if (s.d->m_data.value(scName).isNull())
diff --git a/tests/auto/installer/settings/data/empty_config.xml b/tests/auto/installer/settings/data/empty_config.xml
new file mode 100644
index 000000000..66c9879a5
--- /dev/null
+++ b/tests/auto/installer/settings/data/empty_config.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+</Installer>
diff --git a/tests/auto/installer/settings/data/full_config.xml b/tests/auto/installer/settings/data/full_config.xml
new file mode 100644
index 000000000..2b11c0166
--- /dev/null
+++ b/tests/auto/installer/settings/data/full_config.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+File should contain all elements we allow in a config.xml
+-->
+
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+ <Title>Your application Installer</Title>
+ <Publisher>Your vendor</Publisher>
+ <ProductUrl>Your vendor</ProductUrl>
+
+ <TargetDir>@homeDir@InstallationDirectory</TargetDir>
+ <AdminTargetDir>@rootDir@InstallationDirectory</AdminTargetDir>
+
+ <Icon>icon</Icon>
+ <Logo>logo</Logo>
+ <LogoSmall>logo_small</LogoSmall>
+ <Watermark>watermark</Watermark>
+ <Background>background</Background>
+
+ <StartMenuDir>Super App</StartMenuDir>
+
+ <UninstallerName>uninstaller</UninstallerName>
+ <UninstallerIniFile>uninstaller.ini</UninstallerIniFile>
+ <RemoveTargetDir>true</RemoveTargetDir>
+
+ <RunProgram>myapp</RunProgram>
+ <RunProgramDescription>Launch MyApp</RunProgramDescription>
+
+ <SigningCertificate>certificate1</SigningCertificate>
+ <SigningCertificate>certificate2</SigningCertificate>
+
+ <DependsOnLocalInstallerBinary>true</DependsOnLocalInstallerBinary>
+ <AllowSpaceInPath>true</AllowSpaceInPath>
+ <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>
+ <RepositorySettingsPageVisible>false</RepositorySettingsPageVisible>
+ <TargetConfigurationFile>components.xml</TargetConfigurationFile>
+
+ <RemoteRepositories>
+ <Repository>
+ <Url>http://www.yourcompany.com/packages</Url>
+ <Enabled>1</Enabled>
+ <Username>user</Username>
+ <Password>password</Password>
+ </Repository>
+ </RemoteRepositories>
+
+ <Pages>
+ <Page name="IntroductionPage">
+ <Title>
+ <Default>Introduction Page Title</Default>
+ </Title>
+ <SubTitle>
+ <Default>Introduction Page Sub Title</Default>
+ </SubTitle>
+ <MessageLabel>Introduction Page Message Label</MessageLabel>
+ </Page>
+ <Page name="LicenseAgreementPage">
+ <Title>
+ <Default>License Agreement Page Title</Default>
+ </Title>
+ <SubTitle>
+ <Default>License Agreement Page Sub Title</Default>
+ </SubTitle>
+ <AcceptLicenseLabel>Accept License Radio Button</AcceptLicenseLabel>
+ <RejectLicenseLabel>Reject License Radio Button</RejectLicenseLabel>
+ </Page>
+ <Page name="ComponentSelectionPage">
+ <Title>
+ <Default>Component Selection Page Title</Default>
+ <Updater>Component Selection Page Sub Title Updater</Updater>
+ <Installer>Component Selection Page Sub Title Installer</Installer>
+ <Uninstaller>Component Selection Page Sub Title Uninstaller</Uninstaller>
+ <PackageManager>Component Selection Page Sub Title Package Manager</PackageManager>
+ </Title>
+ <SubTitle>
+ <Default>Component Selection Page Sub Title</Default>
+ <Updater>Component Selection Page Sub Title Updater</Updater>
+ <Installer>Component Selection Page Sub Title Installer</Installer>
+ <Uninstaller>Component Selection Page Sub Title Uninstaller</Uninstaller>
+ <PackageManager>Component Selection Page Sub Title Package Manager</PackageManager>
+ </SubTitle>
+ <SelectDefaultComponentsButton>Default Button</SelectDefaultComponentsButton>
+ <SelectAllComponentsButton>Select All Button</SelectAllComponentsButton>
+ <DeselectAllComponentsButton>Deselect All Button</DeselectAllComponentsButton>
+ <ComponentSizeLabel>Component Size Label</ComponentSizeLabel>
+ </Page>
+ <Page name="TargetDirectoryPage">
+ <Title>
+ <Default>Target Directory Page Title</Default>
+ </Title>
+ <SubTitle>
+ <Default>Target Directory Page Sub Title</Default>
+ </SubTitle>
+ <MessageLabel>Target Directory Page Message Label</MessageLabel>
+ <BrowseDirectoryButton>Browse Directory Button</BrowseDirectoryButton>
+ <EmptyTargetDirectoryMessage>Empty Target Directory Message</EmptyTargetDirectoryMessage>
+ <ForbiddenTargetDirectoryMessage>Forbidden Target Directory Message</ForbiddenTargetDirectoryMessage>
+ <OverwriteTargetDirectoryMessage>Overwrite Target Directory Message</OverwriteTargetDirectoryMessage>
+ <SelectInstallationFolderCaption>Select Installation Folder Caption</SelectInstallationFolderCaption>
+ </Page>
+ <Page name="StartMenuDirectoryPage">
+ <Title>
+ <Default>Start Menu Directory Page Title</Default>
+ </Title>
+ <SubTitle>
+ <Default>Start Menu Directory Page Sub Title</Default>
+ </SubTitle>
+ </Page>
+ <Page name="ReadyForInstallationPage">
+ <Title>
+ <Default>Ready for Installation Page Title</Default>
+ <Updater>Ready for Installation Page Title Updater</Updater>
+ <Installer>Ready for Installation Page Title Installer</Installer>
+ <Uninstaller>Ready for Installation Page Title Uninstaller</Uninstaller>
+ <PackageManager>Ready for Installation Page Title Package Manager</PackageManager>
+ </Title>
+ <SubTitle>
+ <Default>Ready for Installation Page Sub Title</Default>
+ <Updater>Ready for Installation Page Sub Title Updater</Updater>
+ <Installer>Ready for Installation Page Sub Title Installer</Installer>
+ <Uninstaller>Ready for Installation Page Sub Title Uninstaller</Uninstaller>
+ <PackageManager>Ready for Installation Page Sub Title Package Manager</PackageManager>
+ </SubTitle>
+ <MessageLabel>Ready for Installation Page Message Label</MessageLabel>
+ </Page>
+ <Page name="PerformInstallationPage">
+ <Title>
+ <Default>Perform Installation Page Title</Default>
+ <Updater>Perform Installation Page Title Updater</Updater>
+ <Installer>Perform Installation Page Title Installer</Installer>
+ <Uninstaller>Perform Installation Page Title Uninstaller</Uninstaller>
+ <PackageManager>Perform Installation Page Title Package Manager</PackageManager>
+ </Title>
+ <SubTitle>
+ <Default>Perform Installation Page Sub Title</Default>
+ <Updater>Perform Installation Page Sub Title Updater</Updater>
+ <Installer>Perform Installation Page Sub Title Installer</Installer>
+ <Uninstaller>Perform Installation Page Sub Title Uninstaller</Uninstaller>
+ <PackageManager>Perform Installation Page Sub Title Package Manager</PackageManager>
+ </SubTitle>
+ </Page>
+ <Page name ="FinishedPage">
+ <Title>
+ <Default>Finished Page Title</Default>
+ <Updater>Finished Page Title Updater</Updater>
+ <Installer>Finished Page Title Installer</Installer>
+ <Uninstaller>Finished Page Title Uninstaller</Uninstaller>
+ <PackageManager>Finished Page Title Package Manager</PackageManager>
+ </Title>
+ <SubTitle>
+ <Default>Finished Page Sub Title</Default>
+ <Updater>Finished Page Sub Title Updater</Updater>
+ <Installer>Finished Page Sub Title Installer</Installer>
+ <Uninstaller>Finished Page Sub Title Uninstaller</Uninstaller>
+ <PackageManager>Finished Page Sub Title Package Manager</PackageManager>
+ </SubTitle>
+ <MessageLabel>Finished Page Message Label</MessageLabel>
+ </Page>
+ <Page name="RestartPage">
+ <Title>
+ <Default>Restart Page Title</Default>
+ </Title>
+ <SubTitle>
+ <Default>Restart Page Sub Title</Default>
+ </SubTitle>
+ </Page>
+ </Pages>
+</Installer>
diff --git a/tests/auto/installer/settings/data/minimal_config.xml b/tests/auto/installer/settings/data/minimal_config.xml
new file mode 100644
index 000000000..1b4e1d25d
--- /dev/null
+++ b/tests/auto/installer/settings/data/minimal_config.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+</Installer>
diff --git a/tests/auto/installer/settings/data/unknown_element_config.xml b/tests/auto/installer/settings/data/unknown_element_config.xml
new file mode 100644
index 000000000..0d97564e6
--- /dev/null
+++ b/tests/auto/installer/settings/data/unknown_element_config.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+ <unknown></unknown>
+</Installer>
diff --git a/tests/auto/installer/settings/settings.qrc b/tests/auto/installer/settings/settings.qrc
index eaa92b93e..de130ea10 100644
--- a/tests/auto/installer/settings/settings.qrc
+++ b/tests/auto/installer/settings/settings.qrc
@@ -1,6 +1,10 @@
<RCC>
<qresource prefix="/">
- <file>data/tutorial_config.xml</file>
+ <file>data/empty_config.xml</file>
+ <file>data/full_config.xml</file>
<file>data/malformed_config.xml</file>
+ <file>data/minimal_config.xml</file>
+ <file>data/tutorial_config.xml</file>
+ <file>data/unknown_element_config.xml</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/settings/tst_settings.cpp b/tests/auto/installer/settings/tst_settings.cpp
index 2fcd6bf3f..9fbbd8292 100644
--- a/tests/auto/installer/settings/tst_settings.cpp
+++ b/tests/auto/installer/settings/tst_settings.cpp
@@ -12,12 +12,15 @@ class tst_Settings : public QObject
Q_OBJECT
private slots:
- void loadConfig();
+ void loadTutorialConfig();
+ void loadFullConfig();
+ void loadEmptyConfig();
void loadNotExistingConfig();
void loadMalformedConfig();
+ void loadUnknownElementConfig();
};
-void tst_Settings::loadConfig()
+void tst_Settings::loadTutorialConfig()
{
Settings settings =
Settings::fromFileAndPrefix(":///data/tutorial_config.xml", ":///data");
@@ -62,12 +65,31 @@ void tst_Settings::loadConfig()
QCOMPARE(settings.httpProxy(), QNetworkProxy());
}
+void tst_Settings::loadFullConfig()
+{
+ Settings settings =
+ Settings::fromFileAndPrefix(":///data/full_config.xml", ":///data");
+}
+
+void tst_Settings::loadEmptyConfig()
+{
+ try {
+ Settings::fromFileAndPrefix(":/data/empty_config.xml", ":/data");
+ } catch (const Error &error) {
+ QCOMPARE(error.message(), QLatin1String("Missing or empty <Name> tag in :/data/empty_config.xml."));
+ return;
+ }
+ QFAIL("No exception thrown");
+}
+
void tst_Settings::loadNotExistingConfig()
{
try {
Settings::fromFileAndPrefix(":/data/inexisting_config.xml", ":/data");
} catch (const Error &error) {
- QVERIFY(error.message() == ("Could not open settings file :/data/inexisting_config.xml for reading: Unknown error"));
+ QCOMPARE(error.message(), QLatin1String("Could not open settings file "
+ ":/data/inexisting_config.xml for reading: "
+ "Unknown error"));
return;
}
QFAIL("No exception thrown");
@@ -78,7 +100,20 @@ void tst_Settings::loadMalformedConfig()
try {
Settings::fromFileAndPrefix(":/data/malformed_config.xml", ":/data");
} catch (const Error &error) {
- QVERIFY(error.message().startsWith("Xml parse error"));
+ QCOMPARE(error.message(), QLatin1String("Error in :/data/malformed_config.xml, line 9, column 0: "
+ "Premature end of document."));
+ return;
+ }
+ QFAIL("No exception thrown");
+}
+
+void tst_Settings::loadUnknownElementConfig()
+{
+ try {
+ Settings::fromFileAndPrefix(":/data/unknown_element_config.xml", ":/data");
+ } catch (const Error &error) {
+ QCOMPARE(error.message(), QLatin1String("Error in :/data/unknown_element_config.xml, line 5, "
+ "column 13: Unexpected element 'unknown'."));
return;
}
QFAIL("No exception thrown");