Do basic sanity check of a package's most important fields when checking for problems
This commit is contained in:
parent
77000ac7d3
commit
524b16815a
|
@ -443,6 +443,84 @@ bool Package::isArchAny() const
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool containsUnexpectedCharacters(std::string_view value)
|
||||
{
|
||||
for (auto c : value) {
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '_':
|
||||
case '.':
|
||||
continue;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool containsUnprintableCharacters(std::string_view value)
|
||||
{
|
||||
for (auto c : value) {
|
||||
if (c < ' ' || c >= 127) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define CHECK_FIELD_EMPTY(field) \
|
||||
if (field.empty()) { \
|
||||
problems.emplace_back(#field " is empty"); \
|
||||
}
|
||||
#define CHECK_FIELD_FOR_UNEXPECTED_CHARS(field) \
|
||||
if (containsUnexpectedCharacters(field)) { \
|
||||
problems.emplace_back(#field " contains unexpected characters"); \
|
||||
}
|
||||
#define CHECK_FIELD_FOR_UNPRINTABLE_CHARS(field) \
|
||||
if (containsUnprintableCharacters(field)) { \
|
||||
problems.emplace_back(#field " contains unprintable or non-ASCII characters"); \
|
||||
}
|
||||
#define CHECK_FIELD_STRICT(field) \
|
||||
CHECK_FIELD_EMPTY(field) \
|
||||
CHECK_FIELD_FOR_UNEXPECTED_CHARS(field)
|
||||
#define CHECK_FIELD_RELAXED(field) \
|
||||
CHECK_FIELD_EMPTY(field) \
|
||||
CHECK_FIELD_FOR_UNPRINTABLE_CHARS(field)
|
||||
|
||||
/*!
|
||||
* \brief Performs a basic sanity check of the package's fields.
|
||||
* \returns Returns an empty vector if no problems were found; otherwise returns the problem descriptions.
|
||||
*/
|
||||
std::vector<std::string> Package::validate() const
|
||||
{
|
||||
// check basic fields
|
||||
auto problems = std::vector<std::string>();
|
||||
CHECK_FIELD_STRICT(name)
|
||||
CHECK_FIELD_RELAXED(version)
|
||||
CHECK_FIELD_STRICT(arch)
|
||||
|
||||
// check dependencies
|
||||
const auto checkDeps = sourceInfo ? sourceInfo->checkDependencies : std::vector<Dependency>();
|
||||
const auto makeDeps = sourceInfo ? sourceInfo->makeDependencies : std::vector<Dependency>();
|
||||
for (const auto &deps : { dependencies, optionalDependencies, provides, conflicts, replaces, checkDeps, makeDeps }) {
|
||||
for (const auto &dep : deps) {
|
||||
if (dep.name.empty()) {
|
||||
problems.emplace_back("dependency is empty");
|
||||
return problems;
|
||||
}
|
||||
if (containsUnexpectedCharacters(dep.name)) {
|
||||
problems.emplace_back("dependency contains unexpected characters");
|
||||
return problems;
|
||||
}
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
DependencySetBase::iterator DependencySet::find(const Dependency &dependency)
|
||||
{
|
||||
for (auto range = equal_range(dependency.name); range.first != range.second; ++range.first) {
|
||||
|
|
|
@ -417,6 +417,7 @@ struct LIBPKG_EXPORT Package : public PackageBase,
|
|||
std::vector<std::string> processDllsReferencedByImportLibs(std::set<std::string> &&dllsReferencedByImportLibs);
|
||||
bool addDepsAndProvidesFromOtherPackage(const Package &otherPackage, bool force = false);
|
||||
bool isArchAny() const;
|
||||
std::vector<std::string> validate() const;
|
||||
using ReflectiveRapidJSON::JsonSerializable<Package>::fromJson;
|
||||
using ReflectiveRapidJSON::JsonSerializable<Package>::toJson;
|
||||
using ReflectiveRapidJSON::JsonSerializable<Package>::toJsonDocument;
|
||||
|
|
|
@ -466,6 +466,10 @@ void CheckForProblems::run()
|
|||
RepositoryProblem{ .desc = "configured local package directory \"" % db->localPkgDir + "\" is not a directory" });
|
||||
}
|
||||
db->allPackages([&](LibPkg::StorageID, std::shared_ptr<LibPkg::Package> &&package) {
|
||||
const auto packageProblems = package->validate();
|
||||
for (const auto &problem : packageProblems) {
|
||||
problems.emplace_back(RepositoryProblem{ .desc = problem, .pkg = package->name });
|
||||
}
|
||||
if (!package->packageInfo) {
|
||||
problems.emplace_back(RepositoryProblem{ .desc = "no package info present", .pkg = package->name });
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue