From 75f59b16312523ab3deb995c48e8c8ae07586c23 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 4 May 2020 12:23:50 +0200 Subject: Reinstate * wildcards Reinstate * wildcards as they are safe to use, but do not allow any other special characters such as ? or []. Notably, ? would overlap with patterns, and [] might overlap with future pattern extensions (alternative bracketing style), it's also hard to explain. Closes: #953531 LP: #1872200 --- apt-pkg/cacheset.cc | 7 +++++-- test/integration/test-apt-patterns | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 288180f16..3967ba980 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -189,8 +189,11 @@ bool CacheSetHelper::PackageFromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern) { static const char * const isfnmatch = ".?*[]!"; - if (_config->FindB("APT::Cmd::Pattern-Only", false)) - return false; + // Whitelist approach: Anything not in here is not a valid pattern + static const char *const isfnmatch_strict = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.:*"; + + if (_config->FindB("APT::Cmd::Pattern-Only", false) && pattern.find_first_not_of(isfnmatch_strict) != std::string::npos) + return false; if (pattern.find_first_of(isfnmatch) == std::string::npos) return false; diff --git a/test/integration/test-apt-patterns b/test/integration/test-apt-patterns index b55caf35b..b091c8729 100755 --- a/test/integration/test-apt-patterns +++ b/test/integration/test-apt-patterns @@ -233,3 +233,37 @@ testsuccessequal "Listing..." apt list '?x-name-fnmatch(1)' testsuccessequal "Listing... automatic1/now 1.0 i386 [installed,local] manual1/now 1.0 i386 [installed,local]" apt list '?x-name-fnmatch(*1)' + + +# * wildcards should still work +testsuccessequal "Listing... +automatic1/now 1.0 i386 [installed,local] +automatic2/now 1.0 i386 [installed,local]" apt list 'automatic*' + +testfailureequal "Reading package lists... +Building dependency tree... +Reading state information... +Note, selecting 'automatic1' for glob 'automatic*' +Note, selecting 'automatic2' for glob 'automatic*' +automatic1 is already the newest version (1.0). +automatic1 set to manually installed. +automatic2 is already the newest version (1.0). +automatic2 set to manually installed. +You might want to run 'apt --fix-broken install' to correct these. +The following packages have unmet dependencies: + broken : Depends: does-not-exist but it is not installable +E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution)." apt install -s 'automatic*' + +# 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 "Reading package lists... +Building dependency tree... +Reading state information... +E: Unable to locate package automatic?" apt install -s 'automatic?' -- cgit v1.2.3-70-g09d2 From c4f85bcb8bee1b5e647c7e629f616cffc7d12bbc Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 4 May 2020 13:08:33 +0200 Subject: 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. --- apt-private/private-list.cc | 9 +++++---- test/integration/test-apt-patterns | 8 ++++---- 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?' -- cgit v1.2.3-70-g09d2