1 //===-- sanitizer_suppressions_test.cc ------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common/sanitizer_suppressions.h"
14 #include "gtest/gtest.h"
15 
16 #include <string.h>
17 
18 namespace __sanitizer {
19 
MyMatch(const char * templ,const char * func)20 static bool MyMatch(const char *templ, const char *func) {
21   char tmp[1024];
22   strcpy(tmp, templ);  // NOLINT
23   return TemplateMatch(tmp, func);
24 }
25 
TEST(Suppressions,Match)26 TEST(Suppressions, Match) {
27   EXPECT_TRUE(MyMatch("foobar$", "foobar"));
28 
29   EXPECT_TRUE(MyMatch("foobar", "foobar"));
30   EXPECT_TRUE(MyMatch("*foobar*", "foobar"));
31   EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix"));
32   EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix"));
33   EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar"));
34   EXPECT_TRUE(MyMatch("foo*bar", "foobar"));
35   EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz"));
36   EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz"));
37   EXPECT_TRUE(MyMatch("^foobar", "foobar"));
38   EXPECT_TRUE(MyMatch("^foobar", "foobar_postfix"));
39   EXPECT_TRUE(MyMatch("^*foobar", "foobar"));
40   EXPECT_TRUE(MyMatch("^*foobar", "prefix_foobar"));
41   EXPECT_TRUE(MyMatch("foobar$", "foobar"));
42   EXPECT_TRUE(MyMatch("foobar$", "prefix_foobar"));
43   EXPECT_TRUE(MyMatch("*foobar*$", "foobar"));
44   EXPECT_TRUE(MyMatch("*foobar*$", "foobar_postfix"));
45   EXPECT_TRUE(MyMatch("^foobar$", "foobar"));
46 
47   EXPECT_FALSE(MyMatch("foo", "baz"));
48   EXPECT_FALSE(MyMatch("foobarbaz", "foobar"));
49   EXPECT_FALSE(MyMatch("foobarbaz", "barbaz"));
50   EXPECT_FALSE(MyMatch("foo*bar", "foobaz"));
51   EXPECT_FALSE(MyMatch("foo*bar", "foo_baz"));
52   EXPECT_FALSE(MyMatch("^foobar", "prefix_foobar"));
53   EXPECT_FALSE(MyMatch("foobar$", "foobar_postfix"));
54   EXPECT_FALSE(MyMatch("^foobar$", "prefix_foobar"));
55   EXPECT_FALSE(MyMatch("^foobar$", "foobar_postfix"));
56   EXPECT_FALSE(MyMatch("foo^bar", "foobar"));
57   EXPECT_FALSE(MyMatch("foo$bar", "foobar"));
58   EXPECT_FALSE(MyMatch("foo$^bar", "foobar"));
59 }
60 
61 static const char *kTestSuppressionTypes[] = {"race", "thread", "mutex",
62                                               "signal"};
63 
64 class SuppressionContextTest : public ::testing::Test {
65  public:
SuppressionContextTest()66   SuppressionContextTest()
67       : ctx_(kTestSuppressionTypes, ARRAY_SIZE(kTestSuppressionTypes)) {}
68 
69  protected:
70   SuppressionContext ctx_;
71 
CheckSuppressions(unsigned count,std::vector<const char * > types,std::vector<const char * > templs) const72   void CheckSuppressions(unsigned count, std::vector<const char *> types,
73                          std::vector<const char *> templs) const {
74     EXPECT_EQ(count, ctx_.SuppressionCount());
75     for (unsigned i = 0; i < count; i++) {
76       const Suppression *s = ctx_.SuppressionAt(i);
77       EXPECT_STREQ(types[i], s->type);
78       EXPECT_STREQ(templs[i], s->templ);
79     }
80   }
81 };
82 
TEST_F(SuppressionContextTest,Parse)83 TEST_F(SuppressionContextTest, Parse) {
84   ctx_.Parse("race:foo\n"
85              " 	race:bar\n"  // NOLINT
86              "race:baz	 \n" // NOLINT
87              "# a comment\n"
88              "race:quz\n"); // NOLINT
89   CheckSuppressions(4, {"race", "race", "race", "race"},
90                     {"foo", "bar", "baz", "quz"});
91 }
92 
TEST_F(SuppressionContextTest,Parse2)93 TEST_F(SuppressionContextTest, Parse2) {
94   ctx_.Parse(
95     "  	# first line comment\n"  // NOLINT
96     " 	race:bar 	\n"  // NOLINT
97     "race:baz* *baz\n"
98     "# a comment\n"
99     "# last line comment\n"
100   );  // NOLINT
101   CheckSuppressions(2, {"race", "race"}, {"bar", "baz* *baz"});
102 }
103 
TEST_F(SuppressionContextTest,Parse3)104 TEST_F(SuppressionContextTest, Parse3) {
105   ctx_.Parse(
106     "# last suppression w/o line-feed\n"
107     "race:foo\n"
108     "race:bar"
109   );  // NOLINT
110   CheckSuppressions(2, {"race", "race"}, {"foo", "bar"});
111 }
112 
TEST_F(SuppressionContextTest,ParseType)113 TEST_F(SuppressionContextTest, ParseType) {
114   ctx_.Parse(
115     "race:foo\n"
116     "thread:bar\n"
117     "mutex:baz\n"
118     "signal:quz\n"
119   );  // NOLINT
120   CheckSuppressions(4, {"race", "thread", "mutex", "signal"},
121                     {"foo", "bar", "baz", "quz"});
122 }
123 
TEST_F(SuppressionContextTest,HasSuppressionType)124 TEST_F(SuppressionContextTest, HasSuppressionType) {
125   ctx_.Parse(
126     "race:foo\n"
127     "thread:bar\n");
128   EXPECT_TRUE(ctx_.HasSuppressionType("race"));
129   EXPECT_TRUE(ctx_.HasSuppressionType("thread"));
130   EXPECT_FALSE(ctx_.HasSuppressionType("mutex"));
131   EXPECT_FALSE(ctx_.HasSuppressionType("signal"));
132 }
133 
134 }  // namespace __sanitizer
135