xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cpp (revision 3cab2bb3f667058bece8e38b12449a63a9d73c4b)
1 //===-- sanitizer_suppressions_test.cpp -----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
10 //
11 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common/sanitizer_suppressions.h"
13 #include "gtest/gtest.h"
14 
15 #include <string.h>
16 
17 namespace __sanitizer {
18 
MyMatch(const char * templ,const char * func)19 static bool MyMatch(const char *templ, const char *func) {
20   char tmp[1024];
21   snprintf(tmp, sizeof(tmp), "%s", templ);
22   return TemplateMatch(tmp, func);
23 }
24 
TEST(Suppressions,Match)25 TEST(Suppressions, Match) {
26   EXPECT_TRUE(MyMatch("foobar$", "foobar"));
27 
28   EXPECT_TRUE(MyMatch("foobar", "foobar"));
29   EXPECT_TRUE(MyMatch("*foobar*", "foobar"));
30   EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix"));
31   EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix"));
32   EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar"));
33   EXPECT_TRUE(MyMatch("foo*bar", "foobar"));
34   EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz"));
35   EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz"));
36   EXPECT_TRUE(MyMatch("^foobar", "foobar"));
37   EXPECT_TRUE(MyMatch("^foobar", "foobar_postfix"));
38   EXPECT_TRUE(MyMatch("^*foobar", "foobar"));
39   EXPECT_TRUE(MyMatch("^*foobar", "prefix_foobar"));
40   EXPECT_TRUE(MyMatch("foobar$", "foobar"));
41   EXPECT_TRUE(MyMatch("foobar$", "prefix_foobar"));
42   EXPECT_TRUE(MyMatch("*foobar*$", "foobar"));
43   EXPECT_TRUE(MyMatch("*foobar*$", "foobar_postfix"));
44   EXPECT_TRUE(MyMatch("^foobar$", "foobar"));
45 
46   EXPECT_FALSE(MyMatch("foo", "baz"));
47   EXPECT_FALSE(MyMatch("foobarbaz", "foobar"));
48   EXPECT_FALSE(MyMatch("foobarbaz", "barbaz"));
49   EXPECT_FALSE(MyMatch("foo*bar", "foobaz"));
50   EXPECT_FALSE(MyMatch("foo*bar", "foo_baz"));
51   EXPECT_FALSE(MyMatch("^foobar", "prefix_foobar"));
52   EXPECT_FALSE(MyMatch("foobar$", "foobar_postfix"));
53   EXPECT_FALSE(MyMatch("^foobar$", "prefix_foobar"));
54   EXPECT_FALSE(MyMatch("^foobar$", "foobar_postfix"));
55   EXPECT_FALSE(MyMatch("foo^bar", "foobar"));
56   EXPECT_FALSE(MyMatch("foo$bar", "foobar"));
57   EXPECT_FALSE(MyMatch("foo$^bar", "foobar"));
58 }
59 
60 static const char *kTestSuppressionTypes[] = {"race", "thread", "mutex",
61                                               "signal"};
62 
63 class SuppressionContextTest : public ::testing::Test {
64  public:
SuppressionContextTest()65   SuppressionContextTest()
66       : ctx_(kTestSuppressionTypes, ARRAY_SIZE(kTestSuppressionTypes)) {}
67 
68  protected:
69   SuppressionContext ctx_;
70 
CheckSuppressions(unsigned count,std::vector<const char * > types,std::vector<const char * > templs) const71   void CheckSuppressions(unsigned count, std::vector<const char *> types,
72                          std::vector<const char *> templs) const {
73     EXPECT_EQ(count, ctx_.SuppressionCount());
74     for (unsigned i = 0; i < count; i++) {
75       const Suppression *s = ctx_.SuppressionAt(i);
76       EXPECT_STREQ(types[i], s->type);
77       EXPECT_STREQ(templs[i], s->templ);
78     }
79   }
80 };
81 
TEST_F(SuppressionContextTest,Parse)82 TEST_F(SuppressionContextTest, Parse) {
83   ctx_.Parse(
84       "race:foo\n"
85       " \trace:bar\n"
86       "race:baz\t \n"
87       "# a comment\n"
88       "race:quz\n");
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       "  \t# first line comment\n"
96       " \trace:bar \t\n"
97       "race:baz* *baz\n"
98       "# a comment\n"
99       "# last line comment\n");
100   CheckSuppressions(2, {"race", "race"}, {"bar", "baz* *baz"});
101 }
102 
TEST_F(SuppressionContextTest,Parse3)103 TEST_F(SuppressionContextTest, Parse3) {
104   ctx_.Parse(
105       "# last suppression w/o line-feed\n"
106       "race:foo\n"
107       "race:bar\r\n"
108       "race:baz");
109   CheckSuppressions(3, {"race", "race", "race"}, {"foo", "bar", "baz"});
110 }
111 
TEST_F(SuppressionContextTest,ParseType)112 TEST_F(SuppressionContextTest, ParseType) {
113   ctx_.Parse(
114       "race:foo\n"
115       "thread:bar\n"
116       "mutex:baz\n"
117       "signal:quz\n");
118   CheckSuppressions(4, {"race", "thread", "mutex", "signal"},
119                     {"foo", "bar", "baz", "quz"});
120 }
121 
TEST_F(SuppressionContextTest,HasSuppressionType)122 TEST_F(SuppressionContextTest, HasSuppressionType) {
123   ctx_.Parse(
124     "race:foo\n"
125     "thread:bar\n");
126   EXPECT_TRUE(ctx_.HasSuppressionType("race"));
127   EXPECT_TRUE(ctx_.HasSuppressionType("thread"));
128   EXPECT_FALSE(ctx_.HasSuppressionType("mutex"));
129   EXPECT_FALSE(ctx_.HasSuppressionType("signal"));
130 }
131 
TEST_F(SuppressionContextTest,RegressionTestForBufferOverflowInSuppressions)132 TEST_F(SuppressionContextTest, RegressionTestForBufferOverflowInSuppressions) {
133   EXPECT_DEATH(ctx_.Parse("race"), "failed to parse suppressions");
134   EXPECT_DEATH(ctx_.Parse("foo"), "failed to parse suppressions");
135 }
136 
137 
138 }  // namespace __sanitizer
139