diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2020-02-03 12:15:07 +0100 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2020-02-03 12:55:54 +0100 |
commit | 404771d0ec11f26a0b631018719e2918a049455b (patch) | |
tree | d7f2bed62c67b05e01095865056634db0f9b6be7 | |
parent | 11a40ab11f72f85e905bdba4d3274870fbcaeaee (diff) |
patterns: test for empty terms, reject them
-rw-r--r-- | apt-pkg/cachefilter-patterns.cc | 3 | ||||
-rw-r--r-- | apt-pkg/cachefilter-patterns.h | 2 | ||||
-rw-r--r-- | test/libapt/pattern_test.cc | 26 |
3 files changed, 30 insertions, 1 deletions
diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc index 1c92a7b1f..5a58a9767 100644 --- a/apt-pkg/cachefilter-patterns.cc +++ b/apt-pkg/cachefilter-patterns.cc @@ -263,6 +263,9 @@ std::unique_ptr<PatternTreeParser::Node> PatternTreeParser::parsePattern() node->term = sentence.substr(node->start, state.offset - node->start); + if (node->term.size() <= 1) + throw Error{*node, "Pattern must have a term/name"}; + node->end = skipSpace(); // We don't have any arguments, return node; if (sentence[state.offset] != '(') diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index e79702af8..4eeb68594 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -92,9 +92,9 @@ struct PatternTreeParser /// There may not be anything before or after the pattern, except for /// whitespace. std::unique_ptr<Node> parseTop(); + std::unique_ptr<Node> parse(); // public for test cases only private: - std::unique_ptr<Node> parse(); std::unique_ptr<Node> parseOr(); std::unique_ptr<Node> parseAnd(); std::unique_ptr<Node> parseUnary(); diff --git a/test/libapt/pattern_test.cc b/test/libapt/pattern_test.cc index 84d09351c..bfcaf2093 100644 --- a/test/libapt/pattern_test.cc +++ b/test/libapt/pattern_test.cc @@ -14,6 +14,32 @@ using namespace APT::Internal; +#define EXPECT_EXCEPTION(exp, exc, msg) \ + caught = false; \ + try \ + { \ + exp; \ + } \ + catch (exc & e) \ + { \ + caught = true; \ + EXPECT_TRUE(e.message.find(msg) != std::string::npos) << msg << " not in " << e.message; \ + }; \ + EXPECT_TRUE(caught) << #exp "should have thrown an exception" + +TEST(TreeParserTest, ParseInvalid) +{ + bool caught = false; + + // Not a valid pattern: Reject + EXPECT_EXCEPTION(PatternTreeParser("?").parse(), PatternTreeParser::Error, "Pattern must have a term"); + EXPECT_EXCEPTION(PatternTreeParser("?AB?").parse(), PatternTreeParser::Error, "Pattern must have a term"); + EXPECT_EXCEPTION(PatternTreeParser("~").parse(), PatternTreeParser::Error, "Unknown short pattern"); + + // Not a pattern at all: Report nullptr + EXPECT_EQ(PatternTreeParser("A?").parse(), nullptr); +} + TEST(TreeParserTest, ParseWord) { auto node = PatternTreeParser("?word(word)").parseTop(); |