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
17namespace __sanitizer {
18
19static bool MyMatch(const char *templ, const char *func) {
20 char tmp[1024];
21 snprintf(tmp, sizeof(tmp), "%s", templ);
22 return TemplateMatch(templ: tmp, str: func);
23}
24
25TEST(Suppressions, Match) {
26 EXPECT_TRUE(MyMatch(templ: "foobar$", func: "foobar"));
27
28 EXPECT_TRUE(MyMatch(templ: "foobar", func: "foobar"));
29 EXPECT_TRUE(MyMatch(templ: "*foobar*", func: "foobar"));
30 EXPECT_TRUE(MyMatch(templ: "foobar", func: "prefix_foobar_postfix"));
31 EXPECT_TRUE(MyMatch(templ: "*foobar*", func: "prefix_foobar_postfix"));
32 EXPECT_TRUE(MyMatch(templ: "foo*bar", func: "foo_middle_bar"));
33 EXPECT_TRUE(MyMatch(templ: "foo*bar", func: "foobar"));
34 EXPECT_TRUE(MyMatch(templ: "foo*bar*baz", func: "foo_middle_bar_another_baz"));
35 EXPECT_TRUE(MyMatch(templ: "foo*bar*baz", func: "foo_middle_barbaz"));
36 EXPECT_TRUE(MyMatch(templ: "^foobar", func: "foobar"));
37 EXPECT_TRUE(MyMatch(templ: "^foobar", func: "foobar_postfix"));
38 EXPECT_TRUE(MyMatch(templ: "^*foobar", func: "foobar"));
39 EXPECT_TRUE(MyMatch(templ: "^*foobar", func: "prefix_foobar"));
40 EXPECT_TRUE(MyMatch(templ: "foobar$", func: "foobar"));
41 EXPECT_TRUE(MyMatch(templ: "foobar$", func: "prefix_foobar"));
42 EXPECT_TRUE(MyMatch(templ: "*foobar*$", func: "foobar"));
43 EXPECT_TRUE(MyMatch(templ: "*foobar*$", func: "foobar_postfix"));
44 EXPECT_TRUE(MyMatch(templ: "^foobar$", func: "foobar"));
45
46 EXPECT_FALSE(MyMatch(templ: "foo", func: "baz"));
47 EXPECT_FALSE(MyMatch(templ: "foobarbaz", func: "foobar"));
48 EXPECT_FALSE(MyMatch(templ: "foobarbaz", func: "barbaz"));
49 EXPECT_FALSE(MyMatch(templ: "foo*bar", func: "foobaz"));
50 EXPECT_FALSE(MyMatch(templ: "foo*bar", func: "foo_baz"));
51 EXPECT_FALSE(MyMatch(templ: "^foobar", func: "prefix_foobar"));
52 EXPECT_FALSE(MyMatch(templ: "foobar$", func: "foobar_postfix"));
53 EXPECT_FALSE(MyMatch(templ: "^foobar$", func: "prefix_foobar"));
54 EXPECT_FALSE(MyMatch(templ: "^foobar$", func: "foobar_postfix"));
55 EXPECT_FALSE(MyMatch(templ: "foo^bar", func: "foobar"));
56 EXPECT_FALSE(MyMatch(templ: "foo$bar", func: "foobar"));
57 EXPECT_FALSE(MyMatch(templ: "foo$^bar", func: "foobar"));
58}
59
60static const char *kTestSuppressionTypes[] = {"race", "thread", "mutex",
61 "signal"};
62
63class SuppressionContextTest : public ::testing::Test {
64 public:
65 SuppressionContextTest()
66 : ctx_(kTestSuppressionTypes, ARRAY_SIZE(kTestSuppressionTypes)) {}
67
68 protected:
69 SuppressionContext ctx_;
70
71 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
82TEST_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
93TEST_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
103TEST_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
112TEST_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
122TEST_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
132TEST_F(SuppressionContextTest, RegressionTestForBufferOverflowInSuppressions) {
133 const char *expected_output =
134 "failed to parse suppressions.\n"
135 "Supported suppression types are:\n"
136 "- race\n"
137 "- thread\n"
138 "- mutex\n"
139 "- signal\n";
140 EXPECT_DEATH(ctx_.Parse("race"), expected_output);
141 EXPECT_DEATH(ctx_.Parse("foo"), expected_output);
142}
143
144} // namespace __sanitizer
145

source code of compiler-rt/lib/sanitizer_common/tests/sanitizer_suppressions_test.cpp