diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2020-02-01 17:33:08 +0100 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2020-02-03 12:55:54 +0100 |
commit | 11a40ab11f72f85e905bdba4d3274870fbcaeaee (patch) | |
tree | a195af50ceeae4fbec2f558651aa5dbcf69ebe48 | |
parent | 8886ea163032fb8bf64211a94c5dc252a4572a9c (diff) |
Correctly stop parsing short form arguments on space, also on ?
we have to stop parsing on space so that things like ~ramd64 | ~rall
work correctly.
aptitude does not stop parsing on ?, but we'll do as it gets very
confusing otherwise if you write stuff like ~ramd64?name(foo), and
it resolves to ?and(?architecture(amd64?name), (foo))...
-rw-r--r-- | apt-pkg/cachefilter-patterns.cc | 19 | ||||
-rw-r--r-- | apt-pkg/cachefilter-patterns.h | 4 | ||||
-rw-r--r-- | test/libapt/pattern_test.cc | 2 |
3 files changed, 15 insertions, 10 deletions
diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc index c6875d995..1c92a7b1f 100644 --- a/apt-pkg/cachefilter-patterns.cc +++ b/apt-pkg/cachefilter-patterns.cc @@ -199,12 +199,12 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseGroup() return node; } -std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseArgument() +std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseArgument(bool shrt) { std::unique_ptr<Node> node; if ((node = parseQuotedWord()) != nullptr) return node; - if ((node = parseWord()) != nullptr) + if ((node = parseWord(shrt)) != nullptr) return node; if ((node = parse()) != nullptr) return node; @@ -231,7 +231,7 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseShortPattern() state.offset += sp.shortName.size() + 1; if (sp.takesArgument) { - node->arguments.push_back(parseArgument()); + node->arguments.push_back(parseArgument(true)); node->haveArgumentList = true; } node->end = state.offset; @@ -279,7 +279,7 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parsePattern() return node; } - node->arguments.push_back(parseArgument()); + node->arguments.push_back(parseArgument(false)); skipSpace(); while (sentence[state.offset] == ',') { @@ -288,7 +288,7 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parsePattern() // This was a trailing comma - allow it and break the loop if (sentence[state.offset] == ')') break; - node->arguments.push_back(parseArgument()); + node->arguments.push_back(parseArgument(false)); skipSpace(); } @@ -328,10 +328,13 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseQuotedWord() } // Parse a bare word atom -std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseWord() +std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parseWord(bool shrt) { - static const constexpr auto DISALLOWED_START = "!?~|,()\0"_sv; - static const constexpr auto DISALLOWED = "|,()\0"_sv; + static const constexpr auto DISALLOWED_START = "!?~|,() \0"_sv; + static const constexpr auto DISALLOWED_LONG = "|,()\0"_sv; + static const constexpr auto DISALLOWED_SHRT = "|,() ?\0"_sv; + const auto DISALLOWED = shrt ? DISALLOWED_SHRT : DISALLOWED_LONG; + if (DISALLOWED_START.find(sentence[state.offset]) != APT::StringView::npos) return nullptr; diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index 1b7e70da5..e79702af8 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -102,8 +102,8 @@ struct PatternTreeParser std::unique_ptr<Node> parseGroup(); std::unique_ptr<Node> parsePattern(); std::unique_ptr<Node> parseShortPattern(); - std::unique_ptr<Node> parseArgument(); - std::unique_ptr<Node> parseWord(); + std::unique_ptr<Node> parseArgument(bool shrt); + std::unique_ptr<Node> parseWord(bool shrt); std::unique_ptr<Node> parseQuotedWord(); }; diff --git a/test/libapt/pattern_test.cc b/test/libapt/pattern_test.cc index ca77959e3..84d09351c 100644 --- a/test/libapt/pattern_test.cc +++ b/test/libapt/pattern_test.cc @@ -186,6 +186,8 @@ TEST(TreeParserTest, ParseShortPattern) EXPECT_PATTERN_EQ("!~F~T | ~T", "?or(?and(?not(?false), ?true), ?true)"); EXPECT_PATTERN_EQ("~ramd64|~rall", "?or(?architecture(amd64), ?architecture(all))"); + EXPECT_PATTERN_EQ("~ramd64 | ~rall", "?or(?architecture(amd64), ?architecture(all))"); + EXPECT_PATTERN_EQ("~ramd64?name(foo)", "?and(?architecture(amd64), ?name(foo))"); EXPECT_PATTERN_EQ("(?A|?B)?C", "?and(?or(?A, ?B), ?C)"); EXPECT_PATTERN_EQ("?A|?B?C", "?or(?A, ?and(?B, ?C))"); |