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(tmp, func); 23} 24 25TEST(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 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 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