1 // Copyright 2021, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #![allow(missing_docs)]
16 #![no_main]
17 
18 use hashbrown::HashSet;
19 use libfuzzer_sys::arbitrary::Arbitrary;
20 use libfuzzer_sys::fuzz_target;
21 
22 const MAX_RESERVE: usize = 1024;
23 
24 #[derive(Arbitrary, Debug, Eq, Hash, PartialEq)]
25 enum Data {
26     A,
27     B,
28     Int { val: u8 },
29 }
30 
31 #[derive(Arbitrary, Debug)]
32 enum HashSetMethods {
33     Insert { value: Data },
34     Remove { value: Data },
35     Contains { value: Data },
36     Get { value: Data },
37     GetOrInsert { value: Data },
38     Iter,
39     Drain,
40     Clear,
41     Reserve { additional: usize },
42     ShrinkToFit,
43     ShrinkTo { min_capacity: usize },
44 }
45 
46 fuzz_target!(|commands: Vec<HashSetMethods>| {
47     let mut set = HashSet::new();
48     for command in commands {
49         match command {
50             HashSetMethods::Insert { value } => {
51                 set.insert(value);
52             }
53             HashSetMethods::Remove { value } => {
54                 set.remove(&value);
55             }
56             HashSetMethods::Contains { value } => {
57                 set.contains(&value);
58             }
59             HashSetMethods::Get { value } => {
60                 set.get(&value);
61             }
62             HashSetMethods::GetOrInsert { value } => {
63                 set.get_or_insert(value);
64             }
65             HashSetMethods::Iter => {
66                 std::hint::black_box(set.iter().count());
67             }
68             HashSetMethods::Drain => {
69                 std::hint::black_box(set.drain().count());
70             }
71             HashSetMethods::Clear => {
72                 set.clear();
73             }
74             HashSetMethods::Reserve { additional } => {
75                 // Avoid allocating too much memory and crashing the fuzzer.
76                 set.reserve(additional % MAX_RESERVE);
77             }
78             HashSetMethods::ShrinkToFit => {
79                 set.shrink_to_fit();
80             }
81             HashSetMethods::ShrinkTo { min_capacity } => {
82                 set.shrink_to(min_capacity % MAX_RESERVE);
83             }
84         }
85     }
86 });
87