diff --git a/src/dconfigfile.cpp b/src/dconfigfile.cpp index 54ff4d03..d4222f7e 100644 --- a/src/dconfigfile.cpp +++ b/src/dconfigfile.cpp @@ -52,6 +52,12 @@ inline static bool isValidFilename(const QString& filename) QRegularExpressionMatch match = regex.match(filename); return match.hasMatch(); } +inline static bool isValidAppId(const QString& appId) +{ + if (appId.contains(' ')) + return false; + return isValidFilename(appId); +} /*! @~english \internal @@ -689,6 +695,10 @@ class Q_DECL_HIDDEN DConfigMetaImpl : public DConfigMeta { bool load(const QString &localPrefix) override { + if (!isValidAppId(configKey.appId)) { + qCWarning(cfLog, "AppId is invalid, appId=%s", qPrintable(configKey.appId)); + return false; + } if (!isValidFilename(configKey.fileName)) { qCWarning(cfLog, "Name is invalid, filename=%s", qPrintable(configKey.fileName)); return false; diff --git a/tests/ut_dconfigfile.cpp b/tests/ut_dconfigfile.cpp index 2ad38677..5d692325 100644 --- a/tests/ut_dconfigfile.cpp +++ b/tests/ut_dconfigfile.cpp @@ -517,3 +517,24 @@ INSTANTIATE_TEST_SUITE_P(checkName, ut_DConfigFileCheckName, std::tuple{QString("org/foo"), false}, std::tuple{QString("./org-foo"), false}, std::tuple{QString("../configs/org-foo"), false})); + +class ut_DConfigFileCheckAppId : public ut_DConfigFile, public ::testing::WithParamInterface> +{ + +}; + +TEST_P(ut_DConfigFileCheckAppId, checkAppId) +{ + const auto [appId, isValid] = GetParam(); + FileCopyGuard guard(":/data/dconf-example.meta.json", QString("%1/%2/%3.json").arg(noAppidMetaPath, appId, FILE_NAME)); + DConfigFile config(appId, FILE_NAME); + ASSERT_EQ(config.load(LocalPrefix), isValid); +} +INSTANTIATE_TEST_SUITE_P(checkAppId, ut_DConfigFileCheckAppId, + ::testing::Values( + std::tuple{QString("org-foo"), true}, + std::tuple{QString("org foo"), false}, + std::tuple{QString("org.foo2"), true}, + std::tuple{QString("org/foo"), false}, + std::tuple{QString("./org-foo"), false}, + std::tuple{QString("../configs/org-foo"), false}));