summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2020-02-03 12:15:07 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2020-02-03 12:55:54 +0100
commit404771d0ec11f26a0b631018719e2918a049455b (patch)
treed7f2bed62c67b05e01095865056634db0f9b6be7
parent11a40ab11f72f85e905bdba4d3274870fbcaeaee (diff)
patterns: test for empty terms, reject them
-rw-r--r--apt-pkg/cachefilter-patterns.cc3
-rw-r--r--apt-pkg/cachefilter-patterns.h2
-rw-r--r--test/libapt/pattern_test.cc26
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();