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