summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2020-05-04 13:08:33 +0200
committerJulian Andres Klode <julian.klode@canonical.com>2020-05-04 13:08:33 +0200
commitc4f85bcb8bee1b5e647c7e629f616cffc7d12bbc (patch)
tree9cce30181fd90f11bba30579072bf9b689dba664
parent75f59b16312523ab3deb995c48e8c8ae07586c23 (diff)
apt list: Fix behavior of regex vs fnmatch vs wildcards
Previously (and still in cacheset), patterns where only allowed to start with ? or ~, which ignores the fact that a pattern might just as well start with a negation, such a !~nfoo. Also, we ignored the --regex flag if it looked like this, which was somewhat bad. Let's change this all: * If --regex is given, arguments are always interpreted as regex * If it is a valid package wildcard (name or * characters), then it will be interpreted as a wildcard - this set of characters is free from meaningful overlap with patterns. * Otherwise, the argument is interpreted as a pattern. For a future version, we need to adapt parsing for cacheset and list to use a common parser, to avoid differences in their interpretation. Likely, this code will go into the pattern parser, such that it generates a pattern given a valid fnmatch argument for example.
-rw-r--r--apt-private/private-list.cc9
-rwxr-xr-xtest/integration/test-apt-patterns8
2 files changed, 9 insertions, 8 deletions
diff --git a/apt-private/private-list.cc b/apt-private/private-list.cc
index f5c31bbcd..eee657c46 100644
--- a/apt-private/private-list.cc
+++ b/apt-private/private-list.cc
@@ -39,6 +39,7 @@ struct PackageSortAlphabetic /*{{{*/
class PackageNameMatcher : public Matcher
{
+ static constexpr const char *const isfnmatch_strict = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.:*";
pkgCacheFile &cacheFile;
public:
explicit PackageNameMatcher(pkgCacheFile &cacheFile, const char **patterns)
@@ -48,12 +49,12 @@ class PackageNameMatcher : public Matcher
{
std::string pattern = patterns[i];
APT::CacheFilter::Matcher *cachefilter = NULL;
- if (pattern.size() > 0 && (pattern[0] == '?' || pattern[0] == '~'))
- cachefilter = APT::CacheFilter::ParsePattern(pattern, &cacheFile).release();
- else if(_config->FindB("APT::Cmd::Use-Regexp", false) == true)
+ if(_config->FindB("APT::Cmd::Use-Regexp", false) == true)
cachefilter = new APT::CacheFilter::PackageNameMatchesRegEx(pattern);
- else
+ else if (pattern.find_first_not_of(isfnmatch_strict) == std::string::npos)
cachefilter = new APT::CacheFilter::PackageNameMatchesFnmatch(pattern);
+ else
+ cachefilter = APT::CacheFilter::ParsePattern(pattern, &cacheFile).release();
if (cachefilter == nullptr) {
return;
diff --git a/test/integration/test-apt-patterns b/test/integration/test-apt-patterns
index b091c8729..33df21d36 100755
--- a/test/integration/test-apt-patterns
+++ b/test/integration/test-apt-patterns
@@ -256,10 +256,10 @@ E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or speci
# other wildcards should fail
-# FIXME: This should fail
-testsuccessequal "Listing...
-automatic1/now 1.0 i386 [installed,local]
-automatic2/now 1.0 i386 [installed,local]" apt list 'automatic?'
+testfailureequal "Listing...
+E: input:0-10: error: Expected pattern
+ automatic?
+ ^^^^^^^^^^" apt list 'automatic?'